HazemRefaat21/automated_incident_response

GitHub: HazemRefaat21/automated_incident_response

一个基于 Wazuh 和 Django 构建的自动化安全事件响应流水线,实现从 Web 攻击检测、告警分类到自动封禁 IP 的端到端 SIEM 能力。

Stars: 0 | Forks: 0

# 自动化事件响应 (SIEM) 一个端到端的**安全信息与事件管理**流水线,它使用 **Wazuh** 检测 Web/主机攻击,在 **Django** 后端进行分类,并**自动响应**(封禁 IP、终止进程、通知)—— 配备 Django 管理控制台和 **Kibana** 仪表板以实现可视化。 ## 工作原理(流水线) ``` ┌─────────────┐ access log ┌──────────────────┐ HTTP traffic │ Django │ ───────────────────────▶ │ Wazuh Agent │ ───────────▶ │ (your app) │ django_access.log │ (tails the log) │ └─────────────┘ └────────┬─────────┘ │ events ▼ ┌──────────────────┐ │ Wazuh Manager │ │ (web ruleset → │ │ raises alerts) │ └────────┬─────────┘ │ custom-django │ integration ▼ (HTTP POST) ┌───────────────────────────── Django backend ──────────────────────────────┐ │ POST /api/alerts/ingest/ │ │ │ │ │ ▼ │ │ alerts/hooks.py ── classifies → attack_type + severity (from DB) │ │ │ │ │ ▼ │ │ response_worker ── runs every response mapped to that attack_type: │ │ handlers/ block_ip · kill_process · notify │ │ │ │ │ ▼ │ │ search/es_client ── mirrors alerts + responses to Elasticsearch ─────────┼──▶ Kibana └────────────────────────────────────────────────────────────────────────────┘ ``` 1. **Django** 编写 Apache 格式的访问日志(`AccessLogMiddleware`)。 2. **Wazuh agent** 监控该日志;**Wazuh manager** 内置的 Web 规则集会标记 SQLi / XSS / 目录遍历 / 扫描器 / 暴力破解。 3. Wazuh 的**自定义集成**(`wazuh-config/integrations/custom-django.py`)将每个警报 POST 到 `POST /api/alerts/ingest/`(通过 `X-Wazuh-Secret` 进行身份验证)。 4. `alerts/hooks.py` 根据数据库中的 `AttackType` 行对警报进行**分类**(对 Wazuh 规则描述进行关键字匹配 → `attack_type`,评分 → `severity`)。非攻击的干扰信息会被丢弃。 5. **响应 worker** 运行映射到该攻击类型的每个**响应**(通过 `iptables` 封禁 IP、终止进程、通知),并将每次运行记录在 `ResponseAction` 中。 6. 警报和响应会被同步到 **Elasticsearch**,并在 **Kibana** 中进行可视化。 ## 技术栈 | 层级 | 技术 | |------------------|--------------------------------------------------------| | 检测 | Wazuh(Docker 中的 manager,主机上的 agent) | | 后端 / API | Django 6 + Django REST Framework + SimpleJWT | | 数据库 | PostgreSQL | | 任务队列 | `django-tasks-db`(基于数据库;自我监控的 worker) | | 可视化 | Elasticsearch 8.15 + Kibana 8.15(独立,Docker) | | 响应操作 | Python 处理程序 + `iptables` | ## 我们依赖的服务与组件 系统在运行时交互的所有组件、它们的用途,以及您是否必须运行它: | 服务 / 组件 | 它的作用 | 默认端口 | 是否必需? | |---------------------|-------------------|--------------|-----------| | **Wazuh Manager** (Docker) | 运行 Web 规则集、引发警报、运行向 Django 发送 POST 请求的自定义集成 | `1514` (agent), `55000` (API) | **是** — 它是检测大脑 | | **Wazuh Agent** (主机) | 监控 Django 的 `django_access.log` 并将事件发送给 manager | — | **是** | | **PostgreSQL** | 主数据库(警报、IP 配置、攻击类型、响应、任务队列) | `5432` | **是** | | **后台任务 worker** (`django-tasks-db`) | 消费并执行响应任务(`block_ip`、`kill_process`、`notify`)。**在 Django 进程内的守护线程中自动启动**(`RUN_TASK_WORKER=True`) — 无需单独的进程 | — | **是**(内置) | | **Redis** | 被 `/api/health/` 检查使用,并在导入时由 Celery 应用加载。任务执行已迁移至 `django-tasks-db`,因此 Django **在没有 Redis 的情况下仍可启动** — 但健康检查会报告 `degraded`,且 Celery 功能将无法使用 | `6379` | 推荐使用 | | **Celery / Flower** | 旧版任务层,已被 `django-tasks-db` **取代**。Celery 应用在启动时仍会初始化;您**无需**运行 Celery worker 即可触发响应 | `5555` (Flower) | 否(旧版) | | **Elasticsearch** (Docker) | 存储用于可视化的警报和响应镜像。与 Wazuh indexer 相互独立 | `9201` (主机) | 用于仪表板 | | **Kibana** (Docker) | 基于 Elasticsearch 的 SOC 仪表板 UI | `5601` | 用于仪表板 | | **iptables** (主机) | `block_ip` 响应实际封禁攻击者的 IP | — | 用于 IP 封禁 | | **Docker + Compose** | 运行 Wazuh、Elasticsearch 和 Kibana | — | **是** | ## 仓库结构 ``` automated_incident_response/ ├── django-backend/ # the Django project (run from here) │ ├── manage.py │ ├── siem_backend/ # settings, urls, middleware │ ├── alerts/ # Alert model, ingest API, classifier hooks │ ├── responses/ # ResponseDefinition / AttackResponseMap / admin │ ├── classification/ # AttackType model (DB-managed attack types) │ └── search/ # Elasticsearch sync (es_client, es_sync command) ├── response_worker/ # response handlers + actions (block_ip, kill_process, notify) ├── classification-engine/ # ⚠️ orphaned reference module — not used at runtime ├── wazuh-config/ # Wazuh agent localfile + custom integration script ├── kibana/ # Elasticsearch + Kibana docker-compose + dashboard ├── scripts/attack-simulation/test_attacks.sh # fire test attacks ├── docs/ # architecture & how-to notes ├── requirements.txt └── .env.example ``` ## 前置条件 - **Python 3.12+** 和 `pip` - 在本地运行 **PostgreSQL** - 在本地运行 **Redis**(由健康检查 / Celery 应用使用 — 见下文注释) - **Docker** + Docker Compose(用于 Wazuh 和 Kibana/Elasticsearch) - 正常运行的 **Wazuh** 技术栈(Docker 中的 manager,主机上的 agent) — 参见 [Wazuh 快速入门](https://documentation.wazuh.com/current/quickstart.html) - 带有 **iptables** 的 Linux(`block_ip` 响应会使用它;已在 WSL2 上测试) ## 运行指南 — 基础步骤 按顺序执行以下步骤。假设您从项目根目录 `/home/hazem/automated_incident_response` 开始执行命令。 ### 第 1 步 — 克隆并进入项目 ``` cd /home/hazem/automated_incident_response ``` ### 第 2 步 — 创建虚拟环境并安装依赖 ``` python3 -m venv venv source venv/bin/activate pip install --upgrade pip pip install -r requirements.txt ``` ### 第 3 步 — 配置环境变量 复制示例文件并修改变量值: ``` cp .env.example django-backend/.env ``` 打开 `django-backend/.env` 并至少设置: ``` DEBUG=True SECRET_KEY= ALLOWED_HOSTS=localhost,127.0.0.1 DB_NAME=siem_db DB_USER=siem_user DB_PASSWORD= DB_HOST=localhost DB_PORT=5432 # 必须与 wazuh-config/integrations/custom-django.py 中硬编码的 secret 匹配 WAZUH_INTEGRATION_SECRET=wazuh-django-secret-key-123 # Elasticsearch(在步骤 8 中启动) — 如果您使用 kibana/docker-compose.yml,请保持默认 ES_ENABLED=True ES_URL=http://localhost:9201 ``` ### 第 4 步 — 创建 PostgreSQL 数据库 ``` sudo -u postgres psql <<'SQL' CREATE DATABASE siem_db; CREATE USER siem_user WITH PASSWORD 'your-db-password'; GRANT ALL PRIVILEGES ON DATABASE siem_db TO siem_user; ALTER DATABASE siem_db OWNER TO siem_user; SQL ``` (使用您在 `.env` 中设置的相同名称/用户名/密码。) ### 第 5 步 — 启动 Redis Redis 被 `/api/health/` 检查使用,并在启动时由 Celery 应用加载。在运行 Django 之前启动它: ``` # Docker: docker run -d --name siem-redis -p 6379:6379 redis:7 # …或使用本地安装的 Redis: sudo systemctl start redis-server ``` ### 第 6 步 — 应用迁移并创建管理员用户 ``` cd django-backend python manage.py migrate python manage.py createsuperuser ``` 迁移会播种默认的**攻击类型**和**响应**,因此系统开箱即用。 ### 第 7 步 — 运行 Django 服务器 ``` # 仍在 django-backend/ 目录内 python manage.py runserver 0.0.0.0:8001 ``` - API & 管理: - 健康检查: ### 第 8 步 — 启动 Kibana + Elasticsearch(可视化) 从项目根目录(新终端)开始: ``` docker compose -f kibana/docker-compose.yml up -d ``` - Elasticsearch: (仅限环回接口) - Kibana UI: 将任何现有的警报/响应回填到 Elasticsearch: ``` cd django-backend python manage.py es_sync ``` 然后在 Kibana 中导入预构建的仪表板: **Stack Management → Saved Objects → Import** → `kibana/soc-dashboard.ndjson`。 ### 第 9 步 — 将 Wazuh 接入流水线 Wazuh **manager** 在 Docker 中运行;**agent** 在主机上运行。 **9a. 向 agent 注册 Django 的访问日志**(以便 Wazuh 读取它): ``` sudo bash wazuh-config/install-django-localfile.sh # idempotent # 使 wazuh 用户对 log 具有可读权限: chmod o+r django-backend/logs/django_access.log sudo systemctl restart wazuh-agent # or: sudo /var/ossec/bin/wazuh-control restart ``` **9b. 在 Wazuh manager 上安装自定义集成**,以便警报发送至 Django。 将 `wazuh-config/integrations/custom-django.py` 复制到 manager 容器的 `/var/ossec/integrations/` 中,赋予其可执行权限,并在 manager 的 `ossec.conf` 中添加引用它的 `` 块。在脚本内部确认: - `DJANGO_URL` 指向运行 Django 的主机,端口为 **8001** (例如从容器内部访问 `http://172.18.0.1:8001/api/alerts/ingest/`)。 - `WAZUH_SECRET` 与您 `.env` 中的 `WAZUH_INTEGRATION_SECRET` 匹配。 修改完配置后重启 manager。 ### 第 10 步 — 测试整个流水线 向受监控的应用程序发起模拟攻击: ``` bash scripts/attack-simulation/test_attacks.sh ``` 等待约 30 秒,然后验证整个流程: 1. **Wazuh Dashboard** → Threat Hunting 显示原始警报。 2. **Django admin** → `/admin/alerts/alert/` 显示带有 `attack_type` + `severity` 的已分类警报。 3. **Django admin** → `/admin/responses/responseaction/` 显示已运行的自动 响应(例如已封禁的 IP)。 4. **Kibana** () 显示已填充数据的 SOC 仪表板。 ✅ 如果您看到已分类的警报和已执行的响应,说明流水线正在正常工作。 ## 日常 API 参考 首先进行身份验证 (JWT): ``` curl -X POST http://localhost:8001/api/auth/token/ \ -H 'Content-Type: application/json' \ -d '{"username":"admin","password":""}' ``` | Endpoint | 用途 | |--------------------------------------------|--------------------------------------| | `POST /api/alerts/ingest/` | Wazuh 将警报推送到这里(密钥认证)| | `GET /api/alerts/` | 列出 / 过滤已分类的警报 | | `GET /api/ips/` · `POST /api/ips/{id}/block/` | IP 配置,手动封禁/解封 | | `GET /api/responses/` | 已执行的响应操作日志 | | `GET /api/response-definitions/` | 已配置的响应 | | `POST /api/response-definitions/{id}/run/` | 手动运行响应 | | `GET /api/response-handlers/` | 可用的处理程序键 | | `GET /api/health/` | 健康状态 (DB / Redis / Wazuh) | 手动运行响应(例如封禁 IP 1 小时): ``` curl -X POST http://localhost:8001/api/response-definitions//run/ \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -d '{"target":"1.2.3.4","params":{"duration_hours":1}}' ``` ## 自定义检测和响应 大多数自定义操作**仅限仪表板,无需代码**: - **添加攻击类型** → admin → `classification/attacktype/`(键、关键字、 基础分数、优先级)。下一个匹配的警报将自动分类。 - **映射攻击 → 响应** → admin → `responses/attackresponsemap/`。 - **添加新的响应操作** → 在 `response_worker/handlers/` 中编写处理程序,使用 `@register_response('key')` 注册它, 将模块添加到 `handlers/__init__.py` 的导入循环中,然后在 admin 中创建一条 `ResponseDefinition` 记录。 完整指南:[`docs/adding-attacks-and-responses.md`](docs/adding-attacks-and-responses.md)。 ## 故障排除 | 症状 | 可能的原因 / 修复方法 | |---------|--------------------| | Wazuh POST 返回 **401** | `WAZUH_INTEGRATION_SECRET` ≠ `custom-django.py` 中的 `WAZUH_SECRET` | | 没有警报送达 Django | 集成中的 `DJANGO_URL`/端口错误,或者 Django 未在 `0.0.0.0:8001` 上运行;运行 `diagnose-django-detection.sh` | | Wazuh agent 无法读取日志 | `chmod o+r django-backend/logs/django_access.log` | | 响应从未执行 | 任务 worker 被禁用 — 确保 `RUN_TASK_WORKER=True`(默认) | | Kibana 为空 | 运行 `python manage.py es_sync` 并检查 `ES_URL=http://localhost:9201` | | 集成脚本提示 "requests not found" | 该脚本使用标准库 `urllib` — 将当前版本重新复制到容器中 | ## 延伸阅读 - [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) - [`docs/INSTALLATION.md`](docs/INSTALLATION.md) - [`docs/adding-attacks-and-responses.md`](docs/adding-attacks-and-responses.md)
标签:Django, Wazuh, 安全运营, 库, 应急响应, 扫描框架, 搜索引擎查询, 测试用例, 自动化防御, 请求拦截, 越狱测试, 逆向工具