Arnav-005/soc-incident-response-platform
GitHub: Arnav-005/soc-incident-response-platform
基于 n8n 构建的端到端 SOC 事件响应自动化平台,利用 LLM 对多源安全告警进行智能分诊、SLA 路由升级与审计追踪。
Stars: 0 | Forks: 0
# AI 网络安全事件响应平台
一个基于
**n8n** 构建的端到端 SOC(安全运营中心)自动化 pipeline。它从异构工具中
摄取安全告警,使用 LLM 对严重程度和类别进行
分诊(在模型调用失败或返回格式错误输出时,提供基于规则的兜底方案),在 SLA 强制升级机制下将事件路由给正确的团队,跟踪解决进度,保留防篡改的审计追踪,并通过电子邮件发送周度趋势报告。
本项目旨在演示 AI 驱动的决策自动化与
实际的工作流编排工程相结合:schema 验证、具备优雅兜底的错误处理、human-in-the-loop 审批、定时与
webhook 触发的执行,以及条件分支——所有这些都在
六个可独立测试的工作流中串联在一起。
## 解决的问题
SOC 团队被来自防火墙、EDR、防病毒软件和
云监控工具的大量原始告警淹没——每个工具都有各自的 payload 格式。分诊过程
手动、缓慢且不一致;没有标准的 schema 来关联
跨工具的事件,缺乏 SLA 强制执行机制,也没有集中化的合规审计追踪。
该平台实现了摄取 → 分诊 → 路由 →
解决 → 报告的自动化,同时在针对高严重程度事件的
最终决策中保留了 human-in-the-loop 机制。
## 架构
```
[External alert sources] --webhook--> [WF1: Ingest & Normalize]
| |
| v
| [WF2: AI Classify Severity]
| |
| v
| [WF3: Assign & Escalate (SLA timer)]
| |
| v
| [WF4: Resolution & Notify] <--webhook-- [Analyst status update]
| |
+------------------ every stage -----> [WF5: Audit Log] <---+
| |
v |
[WF6: Dashboard & Reports]-+
(cron, reads WF5's log)
```
展示就绪版本请参见 `/docs/architecture-diagram.png`。
## 工作流
| # | 名称 | 触发器 | 目的 |
|---|------|---------|---------|
| **WF1** | 告警摄取与标准化 | Webhook `POST /alert-ingest` | 将来自多种模拟告警源格式的 payload 标准化为同一个 schema;验证必填字段;以 `422` 状态码和审计事件拒绝格式错误的告警,而不是直接崩溃 |
| **WF2** | AI 威胁分类与优先级排序 | Execute Workflow (来自 WF1) | 调用 LLM (Groq,兼容 OpenAI 的 API) 以分类严重程度/类别;如果模型响应缺失、格式错误或 API 调用失败,则回退到确定性的基于规则的映射器 |
| **WF3** | 事件分配与升级 | Execute Workflow (来自 WF2) + Webhook `POST /incident-ack` | 按类别将事件路由到团队的 Slack 频道;对于高/严重级别,启动 SLA 计时器并在未确认时自动升级(辅助 Slack 频道 + 发送邮件给团队主管);ack webhook 是 human-in-the-loop 的控制手段 |
| **WF4** | 解决跟踪与通知 | Webhook `POST /incident-resolve` | 按 ID 查找事件,标记为已解决,通知利益相关者,如果事件不存在则返回清晰的 `404`——绝不追加重复记录 |
| **WF5** | 审计日志 | Execute Workflow (来自 WF1–WF4) | 刻意保持极简:将每个生命周期事件标准化为统一结构,并将其追加到 Google Sheets 审计追踪中。对其他工作流绝不造成瓶颈 (fire-and-forget) |
| **WF6** | 安全仪表板与报告 | Cron (每周) | 将事件/审计数据汇总为 MTTR、按严重程度划分的未解决积压、最常复发的资产、升级率和分类方法分布比例;通过邮件发送 HTML 报告 |
### 自定义节点: `AlertNormalizer`
一个自定义的 TypeScript n8n 节点,可摄取多种模拟
源格式的原始告警 payload,并输出一个经过验证的统一 schema。目前
在 WF1 中作为 Code 节点占位符实现 (`AlertNormalizer (Code
placeholder)`);一旦
pipeline 完全接通,打包的自定义节点版本将作为计划内的直接替换项。
**统一 schema:**
```
{
"id": "string",
"source": "firewall | edr | antivirus | cloud_monitor | generic",
"severity_raw": "string",
"asset": "string",
"description": "string",
"timestamp": "ISO 8601 string",
"raw_payload": "object",
"valid": "boolean"
}
```
**支持的模拟源格式:**
- `SplunkLike` (防火墙风格): `{event_id, rule_name, host, severity, time}`
- `EDRLike` (CrowdStrike 风格): `{detection_id, technique, device_name, confidence, timestamp}`
- `CloudMonitorLike` (GuardDuty 风格): `{finding_id, type, resource, severity_score, updated_at}`
- 通用兜底:对其他任何格式进行尽力而为的字段映射
## 高级功能
| 功能 | 位置 |
|---|---|
| AI 驱动的决策制定 | WF2 (通过 Groq LLM 进行严重程度/类别分类) |
| 人工审批步骤 | WF3 — 分析师必须在 SLA 时间窗口内触发 ack webhook,否则事件将自动升级 |
| 错误处理与重试逻辑 | WF1 (schema 验证拒绝路径),WF2 (AI 调用回退至基于规则的评分),WF4 (处理未找到记录的情况,而不是静默无操作或抛出原始的 500 错误) |
| 日志与审计追踪 | WF5 — 来自每个工作流的每个生命周期事件都会记录在此处 |
| 定时工作流 | WF6 (每周 Cron 报告) |
| Webhook 触发的工作流 | WF1 (告警接入),WF3 (分析师 ack),WF4 (分析师解决) |
| 条件分支 | WF1 (有效/无效),WF3 (类别路由,SLA 违规/未违规),WF4 (找到/未找到行) |
## 数据存储
一个包含两个标签页的 Google Sheets 电子表格:
**`incidents`** — 每个告警一行,在分配时创建 (WF3) 并
在解决时更新 (WF4):
```
incident_id | source | asset | description | severity | category |
classification_method | status | acknowledged | acknowledged_by |
acknowledged_at | created_at | resolved_at | resolution_notes | resolved_by
```
**`audit_log`** — 每个生命周期事件一行,由 WF5 追加:
```
incident_id | stage | timestamp | actor | details
```
`stage` 值:`ingest_rejected`, `classified`, `assigned`, `escalated`,
`acknowledged_in_time`, `acknowledged`, `resolved`。
## 设置
### 前置条件
- 自托管的 n8n (Docker Desktop 应用)
- [ngrok](https://ngrok.com) 用于公共 webhook URL
- 一个包含 `incidents` 和 `audit_log` 标签页的 Google Sheets 电子表格(表头如上所述)
- 一个 Groq API key
- 一个 Slack 工作区(传入 webhook 或 bot token),包含每个
团队的频道(`#network-team`, `#endpoint-team`, `#cloud-team`, `#soc-general`,
`#soc-escalations`)
- 用于出站通知的 Gmail(或 SMTP)凭据
### 导入顺序
1. 首先导入 `WF5-Audit-Log.json` — 其他所有工作流都会调用它
2. 然后依次导入 `WF1-Ingest-Normalize.json` 到 `WF6-Dashboard-Reports.json`
3. 在每个工作流中,打开每一个 **Execute Workflow** 节点,并将其
`workflowId` 下拉菜单设置为实际导入的工作流(它们目前都
指向空的占位符)
4. 在每个 Sheets 节点(WF3, WF4, WF5,
WF6)上设置 Google Sheets 的 `documentId` — 同一个电子表格,不同的标签页
5. 将您的 Groq 凭据附加到 WF2 的 HTTP Request 节点上
6. 在 WF3, WF4, WF6 中设置真实的 Slack 频道名称/ID 和 Gmail 地址
7. 通过 ngrok 暴露 WF1 以及 WF3/WF4 的 webhook
### 测试
使用 `curl`/Postman 通过三种模拟格式模拟告警源。
确切测试 payload 和预期响应,请参阅每个工作流画布中的便签。贯穿完整生命周期的一个代表性通过用例:
```
# 1. 发送高严重性告警
curl -X POST /webhook/alert-ingest \
-H "Content-Type: application/json" \
-d '{"event_id":"fw-1001","rule_name":"Port scan detected","host":"10.0.1.15","severity":"high","time":"2026-07-25T08:00:00Z"}'
# 2. (在 SLA 窗口内)确认它
curl -X POST /webhook/incident-ack \
-H "Content-Type: application/json" \
-d '{"incident_id":"fw-1001","acknowledged_by":"analyst_jane"}'
# 3. 解决它
curl -X POST /webhook/incident-resolve \
-H "Content-Type: application/json" \
-d '{"incident_id":"fw-1001","resolution_notes":"Blocked source IP at perimeter firewall","resolved_by":"analyst_jane"}'
```
另外需要测试的内容:一个无效 payload(预期返回 `422`),一个在 SLA 时间窗口过后仍未确认的高严重程度告警(预期自动升级),以及一次针对未知 `incident_id` 的解决调用(预期返回清晰的 `404`)。
## 仓库内容
```
/workflows
WF1-Ingest-Normalize.json
WF2-AI-Classify.json
WF3-Assign-Escalate.json
WF4-Resolve-Notify.json
WF5-Audit-Log.json
WF6-Dashboard-Reports.json
/docs
architecture-diagram.png
README.md
```
## 状态 / 已知后续事项
- `AlertNormalizer` 自定义 TypeScript 节点尚未打包 — Code 节点
占位符在功能上与其等效
- 可选的拓展功能(`GET /dashboard-data` webhook 将
每周汇总数据以 JSON 公开)尚未构建
- 导出的 JSON 中的凭据、电子表格 ID、Slack 频道和工作流 ID 均为
占位符,必须在导入后按实例进行设置
标签:DLL 劫持, Petitpotam, SOC自动化, 大语言模型, 安全运营, 工作流引擎, 扫描框架, 自动化编排, 请求拦截