Yash-Patil-1/IncidentResponder

GitHub: Yash-Patil-1/IncidentResponder

一款基于 YAML 剧本的自动化安全事件响应 CLI 工具,在告警触发时自动执行 IP 充实、防火墙封锁、通知和案例追踪。

Stars: 1 | Forks: 0

🚨 Incident Responder

Automated IR Playbook Engine

Python version License Status Coverage SOAR

A SOAR-style CLI tool that executes YAML-defined response playbooks when security alerts fire — enrich IPs, block with iptables, log cases, and generate IR reports.

🔗 Pairs with LogSentinel — Detect → Respond → Report

## 📋 概述 Incident Responder 弥合了**检测**与**响应**之间的差距。当安全告警触发时(来自 LogSentinel 或任何 SIEM),Incident Responder 会将其与 YAML 定义的剧本进行匹配,并执行自动化响应动作 —— 通过 AbuseIPDB/VirusTotal 充实 IP 信息,使用 iptables 封锁它,发送基于文件的通知,并将所有内容记录到带有完整审计追踪的 SQLite 数据库中。 **为什么选择这个项目?** 自动化事件响应 (SOAR) 是 SOC 岗位中最抢手的技能之一。该项目展示了构建剧本驱动自动化、集成威胁情报 API、与系统防火墙交互以及维护事件案例管理的实用能力。 ### 作品集矩阵 | 工具 | 角色 | 功能描述 | |------|------|-------------| | **LogSentinel** | 🔍 检测 | 解析日志,检测威胁,关联告警 | | **Incident Responder** | 🚨 响应 | 充实 IP,封锁攻击者,通知,记录案例 | ## ✨ 功能特性 | 特性 | 描述 | |---------|-------------| | **YAML 剧本** | 使用简单的 YAML 定义响应工作流 —— 触发器、动作、参数 | | **5 种动作类型** | `firewall_block`、`enrich_ip`、`notify`、`webhook`、`log_case` —— 可扩展架构 | | **Webhook 通知** | Slack 和 Discord webhook,支持环境变量或按剧本进行 URL 覆盖,以及模板变量 | | **IP 充实** | 查询 AbuseIPDB + VirusTotal API,自动进行 1 小时缓存 | | **防火墙封锁** | iptables IP 封锁,带有 dry-run 模式(默认安全)+ `--execute` 标志 | | **通配符触发器** | 在 `trigger_rule_ids` 中使用 `"*"` 匹配任何告警规则 —— 全局捕获剧本 | | **模板变量** | `{{alert.source_ip}}`、`{{alert.rule_id}}` —— 动态消息/案例模板 | | **LogSentinel 集成** | 原生读取 `{"alerts": [...]}` 报告格式 —— 将检测管道连接至响应 | | **SQLite 数据库** | 持久化事件追踪,带有完整的动作审计追踪 | | **HTML 报告** | 深色主题的事件报告,包含严重性徽章和动作时间线 | | **JSON 导出** | 结构化的事件数据,用于 SIEM 集成和程序化使用 | | **5 个 CLI 命令** | `run`、`list-playbooks`、`list-incidents`、`incident`、`stats` | | **3 个内置剧本** | SSH 暴力破解封锁、端口扫描封锁、全高危通知 | ## 🚀 快速开始 ### 安装 ``` # 克隆 repository git clone https://github.com/Yash-Patil-1/IncidentResponder.git cd IncidentResponder # 创建 virtual environment(推荐) python3 -m venv .venv source .venv/bin/activate # 安装 Incident Responder pip install -e . ``` ### 基本用法 ``` # 使用示例 alert 运行 incident-responder run Sample_alerts/ssh_brute_alert.json # 列出可用的 playbooks incident-responder list-playbooks # 列出追踪的 incidents incident-responder list-incidents # 查看 incident 详情 incident-responder incident 1 ``` ### 与 LogSentinel 集成 ``` # 生成 LogSentinel 报告 logsentinel --sample --format json # 将 alerts 直接 pipe 到 Incident Responder incident-responder run --from-logsentinel reports/logsentinel_report_*.json --verbose ``` ### 执行模式(iptables 需要 sudo 权限) ``` # Dry-run(默认)— 显示将会发生的操作 incident-responder run Sample_alerts/ssh_brute_alert.json # Execute 模式 — 实际封禁该 IP incident-responder run Sample_alerts/ssh_brute_alert.json --execute ``` ### 示例输出 ``` $ incident-responder run Sample_alerts/ssh_brute_alert.json --verbose [+] Alert: [High] SSH Brute Force Detected (DET-001) [+] Source IP: 192.168.1.100 [+] Mode: DRY-RUN [+] Matching playbooks: block_ssh_brute_force, notify_high_severity_alert ============================================================ Incident #1: SSH Brute Force Detected ============================================================ Playbook: block_ssh_brute_force Status: open Alert: [High] DET-001 - 192.168.1.100 ============================================================ Step 1: [✓] enrich_ip No enrichment providers configured (set ABUSEIPDB_API_KEY, VIRUSTOTAL_API_KEY) Step 2: [✓] firewall_block [DRY-RUN] Would block 192.168.1.100 via iptables chain INPUT (Blocked by IncidentResponder - SSH brute force) Step 3: [✓] notify Notification written to /home/user/.incident_responder/notifications.log Step 4: [✓] log_case Case logged: SSH brute force from 192.168.1.100 - blocked via iptables Step 5: [✓] enrich_ip No enrichment providers configured (set ABUSEIPDB_API_KEY, VIRUSTOTAL_API_KEY) Step 6: [✓] notify Notification written to /home/user/.incident_responder/notifications.log Step 7: [✓] log_case Case logged: High severity alert DET-001 from 192.168.1.100 - investigation needed [+] HTML report: reports/ir_incident_1_20260523_113948.html ``` ## 📖 剧本格式 剧本是存储在 `config/playbooks/` 中的 YAML 文件。每个剧本定义了触发条件和一系列自动化动作。 ``` name: block_ssh_brute_force description: Block IP address detected performing SSH brute force attacks trigger_rule_ids: - DET-001 - SSH_BRUTE_FORCE min_severity: medium actions: - type: enrich_ip params: providers: [abuseipdb, virustotal] - type: firewall_block params: chain: INPUT comment: "Blocked by IncidentResponder - SSH brute force" - type: notify params: message: "Blocked {{alert.source_ip}} for SSH brute force ({{alert.count}} attempts)" - type: log_case params: summary: "SSH brute force from {{alert.source_ip}} - blocked via iptables" ``` ### 触发规则 | 字段 | 描述 | 示例 | |-------|-------------|---------| | `trigger_rule_ids` | 激活此剧本的告警规则 ID | `["DET-001", "SSH_BRUTE_FORCE"]` | | `min_severity` | 所需的最低告警严重性 | `low`, `medium`, `high`, `critical` | | 通配符 `"*"` | 匹配任何规则 ID | `["*"]` —— 与 `min_severity: high` 配合使用以实现全局捕获 | ### 动作类型 | 动作 | 描述 | 关键参数 | |--------|-------------|------------| | `firewall_block` | 通过 iptables 封锁 IP(默认为 dry-run) | `ip`, `chain`, `comment` | | `webhook` | 通过 webhook 发送 Slack / Discord 通知 | `type` (slack/discord), `message`, `url` (可选覆盖) | | `enrich_ip` | 查询 AbuseIPDB + VirusTotal 获取 IP 信誉 | `ip`, `providers` | | `notify` | 将结构化通知写入 JSONL 日志文件 | `message`, `channel` | | `log_case` | 在 SQLite 数据库中记录案例摘要 | `summary` | ### 模板变量 所有动作参数均支持 `{{alert.field}}` 替换: | 变量 | 来源 | 示例 | |----------|--------|---------| | `{{alert.rule_id}}` | 告警规则 ID | `DET-001` | | `{{alert.title}}` | 告警标题 | `SSH Brute Force Detected` | | `{{alert.severity}}` | 严重性级别 | `High` | | `{{alert.source_ip}}` | 攻击者 IP | `192.168.1.100` | | `{{alert.count}}` | 事件计数 | `15` | | `{{alert.mitre_technique}}` | MITRE ATT&CK ID | `T1110 - Brute Force` | ## 🛠️ CLI 参考 ``` usage: incident-responder [-h] [--version] {run,list-playbooks,list-incidents,incident,stats} ... ``` ### 命令 #### `run` —— 针对告警执行剧本 ``` incident-responder run [alert_file] [options] Positional Arguments: alert_file Path to alert JSON file (optional — interactive mode if omitted) Options: --from-logsentinel PATH Load alert from LogSentinel report JSON --execute Actually execute actions (default: dry-run) --verbose, -v Show detailed progress --output-dir, -o DIR Report output directory (default: ./reports) --format, -f {html,json} Report format (default: html) --playbooks-dir PATH Path to custom playbooks directory ``` #### `list-playbooks` —— 显示所有已加载的剧本 ``` incident-responder list-playbooks [--playbooks-dir PATH] ``` #### `list-incidents` —— 显示追踪的事件 ``` incident-responder list-incidents [--status {open,closed}] ``` #### `incident` —— 查看或管理事件 ``` incident-responder incident [close] ``` #### `stats` —— 显示数据库统计信息 ``` incident-responder stats ``` ### 用法示例 ``` # 使用独立 alert JSON 运行 incident-responder run Sample_alerts/ssh_brute_alert.json # 从 LogSentinel 报告运行 incident-responder run --from-logsentinel logsentinel_report.json -v # Execute 模式(实际封禁该 IP) sudo incident-responder run alert.json --execute # 查看 incident 详情 incident-responder incident 1 # 调查结束后关闭 incident incident-responder incident 1 close # 生成 JSON 报告而不是 HTML incident-responder run alert.json --format json # 使用自定义 playbooks incident-responder run alert.json --playbooks-dir ./my-playbooks # 显示 database 统计信息 incident-responder stats # 检查版本 incident-responder --version ``` ## 📁 项目结构 ``` IncidentResponder/ ├── pyproject.toml # Package configuration (console_scripts entry) ├── requirements.txt # Python dependencies ├── README.md # This file ├── PRD.md # Product requirements document │ ├── src/ │ ├── __init__.py # Package init (version: 1.0.0) │ ├── models.py # Alert, Playbook, ActionResult, Incident dataclasses │ ├── engine.py # PlaybookEngine — loader, matcher, executor │ ├── database.py # SQLite database (WAL mode, incidents + actions tables) │ ├── main.py # CLI entry point (5 commands) │ ├── reporter.py # IncidentReporter — HTML and JSON reports │ ├── actions/ │ │ ├── __init__.py # ActionRegistry — maps types to handlers │ │ ├── firewall.py # iptables block (dry-run / execute) │ │ ├── enrich.py # AbuseIPDB + VirusTotal with 1-hour cache │ │ ├── webhook.py # Slack & Discord webhook notifications │ │ ├── notify.py # File-based JSONL notifications │ │ └── log_case.py # Case logging to SQLite │ ├── utils.py # Shared template rendering utility │ └── templates/ │ └── report.html # Jinja2 HTML report template │ ├── config/ │ └── playbooks/ │ ├── block_ssh_brute.yaml # SSH brute force → enrich + block + notify │ ├── block_port_scan.yaml # Port scan → enrich + block + notify │ └── notify_high_alert.yaml # Catch-all high+ severity → enrich + notify │ ├── Sample_alerts/ │ ├── ssh_brute_alert.json # DET-001: SSH brute force (LogSentinel-compatible) │ └── port_scan_alert.json # DET-005: Port scan (standalone format) │ ├── tests/ │ ├── test_engine.py # 13 tests — playbook matching, execution, persistence │ ├── test_actions.py # 12 tests — firewall, notify, log_case, registry │ └── test_database.py # 12 tests — CRUD, filtering, stats, edge cases │ ├── reports/ # Generated incident reports └── venv/ # Virtual environment (local) ``` ## 🔧 API & Webhook 配置 ### 威胁情报 API(充实) 要启用 IP 充实,请设置以下环境变量: ``` # AbuseIPDB(免费版:1,000 次检查/天) export ABUSEIPDB_API_KEY="your_key_here" # VirusTotal(免费版:500 次请求/天) export VIRUSTOTAL_API_KEY="your_key_here" ``` 如果没有 API 密钥,充实步骤将被优雅跳过并显示明确的提示信息。 ### Webhook URL(通知) 要启用 Slack 和 Discord 通知,请设置以下环境变量: ``` # Slack incoming webhook export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/T00/B00/xxxxx" # Discord webhook export DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/123456/abcdef" ``` 每个剧本也可以在其动作参数中指定自定义的 webhook URL(覆盖环境变量)。 如果没有这些变量,webhook 步骤将被优雅跳过并显示明确的提示信息。 ## 🧪 运行测试 ``` # 安装 dev dependencies pip install -e ".[dev]" # 运行所有测试 python -m pytest tests/ -v # 运行 coverage python -m pytest tests/ --cov=src --cov-report=term ``` **当前测试结果:56/56 通过**(模块覆盖率为 46% —— 依赖网络的代码和 CLI 代码不包含在单元测试中) ## 🔌 LogSentinel 集成 Incident Responder 旨在与 [LogSentinel](https://github.com/Yash-Patil-1/LogSentinel) 无缝配合使用: ``` # Step 1:使用 LogSentinel 进行检测 logsentinel sample_logs/auth.log --format json --verbose # Step 2:使用 Incident Responder 进行响应 incident-responder run --from-logsentinel reports/logsentinel_report_*.json --verbose ``` `--from-logsentinel` 标志会自动解析 LogSentinel 的 `{"alerts": [...]}` 报告格式。 ## 🗺️ 架构 ``` ┌──────────────┐ │ Alert JSON │ │ (standalone │ │ or LS fmt) │ └──────┬───────┘ │ ┌──────▼───────┐ │ Playbook │ │ Engine │ │ │ │ 1. Load │ │ playbooks │ │ 2. Match │ │ alert │ │ 3. Create │ │ incident │ └──────┬───────┘ │ ┌────────────┼────────────┬───────────┐ │ │ │ │ ┌──────▼───┐ ┌─────▼────┐ ┌─────▼────┐ ┌────▼──────┐ │ Firewall │ │ Enrich │ │ Webhook │ │ Notify │ │ Block │ │ IP (VT + │ │ (Slack / │ │ (File │ │ (iptables│ │ AbuseDB) │ │ Discord) │ │ JSONL) │ └──────┬───┘ └─────┬────┘ └─────┬────┘ └─────┬─────┘ │ │ │ │ └────────────┼────────────┼────────────┘ │ ┌──────▼───────┐ │ SQLite DB │ │ (Incidents │ │ + Actions) │ └──────┬───────┘ │ ┌──────▼───────┐ │ Reporter │ │ HTML / JSON │ └──────────────┘ ``` ### 数据流 1. **摄取 (Ingest)** —— 告警通过 JSON 文件、LogSentinel 报告或手动输入到达 2. **匹配 (Match)** —— PlaybookEngine 将告警与已加载的剧本进行比较(`trigger_rule_ids` + `min_severity`) 3. **事件 (Incident)** —— 在 SQLite 数据库中创建新的事件记录 4. **执行 (Execute)** —— 每个匹配剧本的动作按顺序运行 5. **记录 (Log)** —— 每个动作结果都记录在数据库中,并带有完整的审计追踪 6. **报告 (Report)** —— 生成 HTML 或 JSON 报告,以供人工审查或 SIEM 摄取 ## 📝 许可证 本项目采用 MIT 许可证授权。 ## 👨‍💻 作者 **Yash Patil** —— 网络安全分析师 | SOC 运营与事件响应 - 📧 yashpatil7714@gmail.com - 🔗 [LinkedIn](https://www.linkedin.com/in/yash-patil-997357330) - 🐙 [GitHub](https://github.com/Yash-Patil-1)
使用 Python、PyYAML、SQLite 构建,并对自动化防御深表赞赏。
属于 检测 → 响应 → 搜寻 SOC 工具集的一部分。
标签:iptables, PB级数据处理, Python, SOAR, 威胁情报, 安全运维, 开发者工具, 无后门, 网络信息收集, 自动化响应, 逆向工具, 配置错误