diagonalciso/soc-ops

GitHub: diagonalciso/soc-ops

基于 Wazuh 的轻量级自托管 SOC 工作台,集成 AI 告警分析、案例管理和威胁情报富化功能。

Stars: 0 | Forks: 0

# SOCops Wazuh 的 AI 辅助 SOC 工作台。轻量级、自托管、单进程 Python 应用 —— 除了 Anthropic SDK 和 pyTelegramBotAPI 外无其他外部依赖。 运行在单个 Linux 主机上。连接到 Wazuh/OpenSearch,将告警存储在 SQLite 中,并在 8081 端口上提供深色主题的 Web UI。 ## 功能 ### 告警队列 (`/`) - 每 60 秒从 Wazuh 拉取实时告警队列 - 状态生命周期:`new` → `ack` | `escalated` | `fp` | `suppressed`(重新打开为 `new`) - **类别筛选器**:全部 / Systemd / 完整性 (FIM) / CIS / Web / Windows - **状态筛选器**:全部 / 新 / 已升级 / Ack / FP - **分组视图**:在独立告警和分组视图之间切换(折叠相同规则 + 相同 agent,显示 ×N 计数) - 通过 Claude Haiku 对每个告警进行 AI 分析(如果没有 API key/credits 则回退到基于规则的 stub) - 源 IP 上的威胁情报风险徽章(AbuseIPDB + OTX) - 将告警分配给分析师 - 添加带有完整时间戳记录的备注;状态更改会自动记录 - 从操作栏将告警添加到案例 - 可点击的 agent 名称 / 源 IP 可打开 24 小时实体时间线 ### 仪表板 (`/dashboard`) 每 5 分钟更新一次的 Chart.js 面板: - 随时间变化的告警严重程度(柱状图) - 按告警数量排名的 Top agent(柱状图) - MITRE ATT&CK 战术分布(环形图) - CIS 合规性仪表盘(通过 / 失败 / 错误率) ### 案例 (`/cases`) - 创建命名的安全事件容器(标题、严重程度、描述) - 将多个告警链接到一个案例 - 案例状态生命周期:`open` → `in_progress` → `resolved` → `closed` - 案例详情显示所有链接的告警 ### 抑制规则 (`/suppressions`) - 定义在接入时自动抑制嘈杂告警的规则 - 匹配项:`rule_id`、`agent_name`、`srcip`、`rule_description` - 运算符:`equals`、`contains`、`starts_with` - 可选的过期日期;命中计数器显示每条规则已抑制了多少告警 - 告警详情中的“⊘ 抑制”按钮会从当前告警自动预填表单 ### 指标 (`/metrics`) - **KPI 卡片**:MTTR、FP 率、24 小时数量、积压时长、升级率 - **每小时数量迷你图**:过去 24 小时按小时统计的告警数 - **Top agent 表**:按告警数量排名的前 5 个 agent(过去 7 天) - **嘈杂规则表**:按 FP 率排名的检测规则(红色 > 50%,橙色 > 30%) - **MITRE ATT&CK 覆盖率**:14 战术网格,显示过去 7 天内触发了哪些战术 - **检测规则库**:包含总计/ack/fp/escalated 计数的完整规则表,可排序 ## 要求 - Python 3.10+ - 可通过 HTTPS 访问的 Wazuh 和 OpenSearch Dashboards - `anthropic` Python 包(可选 —— 用于 Claude API 分析) - `pyTelegramBotAPI`(可选 —— 用于 Telegram bot) ``` pip3 install anthropic pyTelegramBotAPI --break-system-packages ``` ### 通过 Ollama 使用本地 AI(出于隐私推荐) SOCops 支持通过 Ollama 进行本地 LLM 分析 —— 无需 API key 或互联网,并且**告警数据永远不会离开您的网络**。对于担心将安全事件数据发送到第三方云 API 的环境,这是首选方案。 最简单的入门方法是 [AnythingLLM Desktop](https://anythingllm.com),它自带了 Ollama 实例 —— 安装后即可直接使用 Ollama,无需额外设置。 **设置:** 1. 安装 AnythingLLM Desktop 并启动它(Ollama 运行在 `http://127.0.0.1:11434`) 2. 拉取模型 —— 针对此用例推荐: curl -s http://127.0.0.1:11434/api/pull -d '{"name":"qwen2.5:3b"}' # 快速,~20s/告警 curl -s http://127.0.0.1:11434/api/pull -d '{"name":"qwen3:8b"}' # 质量更高,~75s/告警 3. 在 `.env` 中设置: OLLAMA_BASE_URL=http://127.0.0.1:11434 OLLAMA_MODEL=qwen2.5:3b **分析调度顺序:** Ollama → OpenRouter → 基于规则的 stub **GPU 注意事项:** 如果您的 GPU VRAM 小于 6 GB,Ollama 将报 CUDA OOM 错误。SOCops 会自动强制使用 CPU 推理(`num_gpu: 0`)来避免这种情况。 **思考模型:** `qwen3:8b` 支持 `think: true` 以进行更深入的推理,但需要快速的 CPU —— 预计每个告警至少需要 75 秒。 ## 配置 将 `.env.example` 复制到 `.env` 并填入相应值: ``` # 必填项 WAZUH_HOST=your.wazuh.host # Wazuh/OpenSearch host WAZUH_USER=changeme # OpenSearch user WAZUH_PASS=yourpassword # OpenSearch password # App 设置 SOCOPS_PORT=8081 POLL_INTERVAL=60 # Wazuh poll interval (seconds) INITIAL_WINDOW=now-24h # How far back to fetch on first run # AI 分析 — 设置一个或多个(如果已配置,则优先尝试 Ollama) ANTHROPIC_API_KEY=sk-ant-... # Claude Haiku (cloud) OLLAMA_BASE_URL=http://127.0.0.1:11434 # Local Ollama (AnythingLLM or standalone) OLLAMA_MODEL=qwen2.5:3b # Model to use (must be pulled first) # Threat intel 富化(可选) OTX_KEY= # AlienVault OTX API key ABUSEIPDB_KEY= # AbuseIPDB API key (1000 lookups/day free) # 出站通知(可选) NOTIFY_WEBHOOK= # Slack / ntfy / generic webhook URL NOTIFY_EMAIL= # Recipient email for high-severity alerts SMTP_HOST= # SMTP server hostname SMTP_PORT=587 SMTP_USER= SMTP_PASS= NOTIFY_LEVEL=12 # Minimum rule level to trigger notification ``` ## 运行 ### 直接运行 ``` cd /path/to/soc-ops env WAZUH_HOST=your.wazuh.host WAZUH_USER=changeme WAZUH_PASS='yourpassword' \ SOCOPS_PORT=8081 ANTHROPIC_API_KEY='sk-ant-...' \ python3 app.py ``` 或者使用 `.env` 文件: ``` env $(cat .env | grep -v '^#' | xargs) python3 app.py ``` ### 作为 systemd 服务运行 ``` # 首先使用真实凭据编辑 .env sudo cp soc-ops.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable --now soc-ops sudo journalctl -u soc-ops -f ``` 该服务单元通过 `EnvironmentFile=` 从 `.env` 读取凭据。 ## 架构 ``` Browser → http://:8081 ↓ Python ThreadingHTTPServer (app.py) ├─ GET / → Alert queue (HTML) ├─ GET /dashboard → Wazuh dashboard (HTML) ├─ GET /cases → Case management (HTML) ├─ GET /suppressions → Suppression rules (HTML) ├─ GET /metrics → KPIs + MITRE heatmap (HTML) ├─ GET /api/alerts → Alert list JSON (?status=&category=&group_key=&rule_id=&since=) ├─ GET /api/alerts/ → Single alert + analysis + enrichment ├─ POST /api/alerts//action → {action, notes, assigned_to} ├─ GET /api/alerts//notes → Notes thread ├─ POST /api/alerts//notes → Add note ├─ GET /api/stats → Queue statistics ├─ GET /api/groups → Grouped alert view (?status=&category=) ├─ GET /api/kpis → SOC KPI metrics ├─ GET /api/mitre → MITRE tactic coverage ├─ GET /api/rules → Detection rule stats ├─ GET /api/timeline → Entity timeline (?agent=|?ip=&hours=) ├─ GET /api/enrich/ → On-demand IP enrichment ├─ GET /api/suppressions → List suppression rules ├─ POST /api/suppressions → Create suppression rule ├─ DELETE /api/suppressions/ → Delete rule ├─ GET /api/cases → List cases ├─ POST /api/cases → Create case ├─ GET /api/cases/ → Case detail + alerts ├─ POST /api/cases//alerts → Link alert to case ├─ POST /api/cases//action → Update case status ├─ GET /api/export/alerts.csv → CSV export (?status=&category=&since=7d) ├─ GET /api/export/alerts.json → JSON export └─ GET /api/data → Dashboard chart data (5-min cache) ↓ background threads _poller() — every 60s: fetch new Wazuh alerts → SQLite, check suppression, notify _analyst_worker() — continuous: AI analysis for unanalyzed alerts (highest level first) _enrichment_worker()— every 30s: enrich srcIPs via AbuseIPDB + OTX (1 IP/sec rate limit) ↓ wazuh.py WazuhClient → OpenSearch at WAZUH_HOST:443 db.py SQLite → soc-ops.db analyst.py → Ollama (local) → OpenRouter → rule-based stub enrichment.py → AbuseIPDB + OTX APIs notifier.py → Webhook + SMTP email ``` ## 文件布局 | 文件 | 作用 | |---|---| | `app.py` | 主服务器 —— 所有路由、后台线程、所有页面的内联 HTML/CSS/JS | | `db.py` | SQLite schema、CRUD 助手、抑制引擎 | | `wazuh.py` | WazuhClient —— OpenSearch 查询、噪声过滤 | | `analyst.py` | 分析引擎:Ollama → OpenRouter → 基于规则的 stub | | `enrichment.py` | IP 威胁情报:AbuseIPDB + OTX | | `notifier.py` | 出站告警:webhook + SMTP 邮件 | | `soc-ops.service` | systemd unit 文件 | | `.env.example` | 配置模板 | | `soc-ops.db` | SQLite 数据库(自动创建,不在 git 中) | ## 数据库 Schema ``` alerts — main alert store (Wazuh hits + SOC workflow state) alert_notes — timestamped notes thread per alert (analyst + auto-generated) cases — incident containers case_alerts — many-to-many: alerts ↔ cases suppression_rules — ingest-time suppression conditions settings — key/value store (last_poll_time, etc.) ``` 关键告警字段:`wazuh_id`、`timestamp`、`agent_name`、`agent_ip`、`rule_id`、`rule_level`、`rule_description`、`rule_groups`、`mitre_technique`、`mitre_tactic`、`srcip`、`status`、`group_key`、`analysis`、`enrichment`、`assigned_to`、`operator_notes`、`full_json`。 ## 噪声过滤 匹配以下内容的告警将在接入时被丢弃(绝不存储): - VirusTotal 频率限制 / 无记录错误 - PAM 登录会话开启/关闭 - SSH 身份验证成功 - Wazuh agent/manager/server 启动消息 在 `wazuh.py` → `NOISE_MUST_NOT` 中配置其他过滤器。 ## 告警类别 | 类别 | 规则组匹配 | |---|---| | Systemd | `rule_groups LIKE '%systemd%'` | | 完整性 | `rule_groups LIKE '%syscheck%'` (FIM + 注册表) | | CIS | `rule_groups LIKE '%sca%'` | | Web | `rule_groups LIKE '%web%'` | | Windows | `rule_groups LIKE '%windows%'` | ## Telegram Bot 位于 `telebot/` 的独立 bot,可让您通过手机与 Claude 聊天。 ``` cd /path/to/telebot # 编辑 .env:添加 TELEGRAM_BOT_TOKEN 和 ANTHROPIC_API_KEY python3 bot.py ``` 命令:`/clear` 重置历史记录 · `/model` 显示当前使用的模型 · `/myid` 显示您的 Telegram 用户 ID。 仅限您的账户使用:在 `.env` 中设置 `ALLOWED_USER_ID=`。 ## Wazuh 连接 - 主机:`WAZUH_HOST` 端口 443 (OpenSearch Dashboards) - 认证:通过 `POST /auth/login` 获取 session cookie - 查询:过去 N 小时的告警,根据最低规则级别和噪声排除进行过滤 - FIM 路径排除:`*/.cache/*`、`*/tmp/*`
标签:AI风险缓解, Python, Wazuh, 告警管理, 安全运营, 扫描框架, 无后门, 逆向工具