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, 安全运营, 库, 应急响应, 扫描框架, 搜索引擎查询, 测试用例, 自动化防御, 请求拦截, 越狱测试, 逆向工具