FabulaNox/agentic-soc-triage

GitHub: FabulaNox/agentic-soc-triage

基于本地小模型的 SOC 告警分诊代理,通过 L1-L2-人类三层架构自动过滤 SIEM 噪音,只将真正需要关注的告警交给人工处理。

Stars: 0 | Forks: 0

# 智能 SOC 分诊 **一个本地 LLM SOC 分析师,负责对家庭实验室 SIEM 的夜间告警进行分诊,因此人类只需关注真正需要人类处理的内容。** [为什么使用 Agent](#why-an-agent-not-just-a-filter) · [分诊层级](#the-l1---l2---human-tiers) · [运行说明](#run-it) · [NoxLab 的一部分 ↗](https://github.com/FabulaNox/NoxLab) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
一个**本地 LLM SOC 分析师**,负责对家庭实验室 SIEM 的夜间告警进行分诊,因此人类只需关注真正需要人类处理的内容。一个 **L1 agent**(一个本地小模型)对每个高危/严重告警进行分类,关闭显而易见的误报,随时间学习良性模式,并**仅将其无法解决的问题升级**给 **L2** 审核者(Claude),然后再交给我。它完全在本地机器上的入门级 GPU 上运行,完全免费。 它的存在是因为家庭实验室的 SIEM 会产生*大量*噪音——即使在空闲时,它也会接收约 160,000 个事件——而且手动进行早间分诊(或者通过按 token 付费给云端模型,将安全遥测数据发送到外部)无法规模化扩展。 ![SOC triage pipeline: a scheduled overnight job builds a daily report (top rules, high/critical alerts, Suricata signatures) that feeds the L1 agent (gemma4:e4b via Ollama) - stage 1 classifies each finding with short-circuits, vault RAG, correlation memory, and month-context; stage 2 assembles posture, summary, and action items; stage 3 escalates if unresolved findings exceed a threshold. The agent injects an L1 Analysis block back into the report for a morning human spot-check, and flags what it cannot resolve for on-demand L2 (Claude) review, then a human verdict.](https://static.pigsec.cn/wp-content/uploads/repos/cas/30/30c9f51bbee25b7281d100a9b0a7a431bd556a5ec5ee8a94490ad0c8fe172f04.svg) ## 目录 - [为什么使用 Agent,而不仅仅是过滤器](#why-an-agent-not-just-a-filter) - [L1 -> L2 -> 人类 分诊层级](#the-l1---l2---human-tiers) - [包含内容](#whats-here) - [运行说明](#run-it) - [Agent 生成的产物](#what-the-agent-produces) - [截图](#screenshots) - [设计说明](#design-notes) ## 为什么使用 Agent,而不仅仅是过滤器 SOC 分诊的难点不在于数量,而在于**关联判断**:“这条规则触发了 200 次”毫无意义,除非你知道这是游戏会话、扫描器还是补丁爆发。因此,L1 阶段是一个真正的 agent,而不是正则表达式: - **它按顺序根据上下文进行推理。** prompt 告诉模型首先检查*关联规则*,然后是*已知模式*,接着是*当天的首要规则 + 最近的报告*以查找关联活动——这模仿了分析师实际进行分诊的方式。 - **在不需要判断时保持低成本。** 在任何模型调用之前,两个短路机制会确定性地关闭告警:一个无条件良性规则 ID 列表,以及一个 CVE 预检,当受影响的包刚刚安装且*已经是最新可用版本*时,该预检会关闭漏洞告警(存在 CVE,无上游补丁 = 无需操作)。 - **随着时间推移变得更敏锐。** 模型识别出的良性模式会被标准化(IP 转换为 `/24`)并追加到下一次运行加载的**关联记忆**中——并提交到笔记库中,从而将学习过程版本化。 - **基于我自己的笔记进行基础设定。** **RAG 查找**会针对每个规则在知识库中运行,因此模型在决定之前会看到类似“*规则 5710 预计来自 VPN 网段 - 良性*”的信息。 - **它知道自己的局限性。** 任何被它分类为 `SUSPICIOUS`/`UNKNOWN` 且超过阈值的告警都会触发 **L2 升级**——它从不自行裁定安全事件。 ## L1 -> L2 -> 人类 分诊层级 | 层级 | 负责者 | 运行方式 | 任务 | |---|---|---|---| | **L1** | `gemma4:e4b` (本地,每夜,免费) | 每天晚上 | 过滤 + 总结,关闭显而易见的告警,**绝不进行裁定** | | **L2** | Claude (按需) | 仅针对 L1 无法解决的少数告警 | 审核升级的告警,记录结论 | | **人类** | 我 | 随时 | 最终决定 | 每次 L1 运行都会向**基准 CSV** 中记录一行数据(包含其决定、耗时,以及用于后续 L2 结论的一列),以便随着时间的推移将 L1 的决策与 L2 进行对比衡量——该模型是被问责的,而不是被盲目信任的。 在实践中,大多数早晨都是 **L1-only**:agent 关闭所有告警,我只需阅读摘要。L2 是例外——仅在其标记出无法解决的问题时才启用——因此最近的报告通常完全显示如下所示的 L1 输出。 ## 包含内容 ``` scripts/soc-agent.sh the L1 agent (3 stages: classify, assemble, escalate) soc-agent.conf.example config: model, paths, known-rule short-circuits, thresholds examples/ sample-daily-report.md a report before/after the agent runs (the injected L1 block) gemma-soc-memory.example.md the self-updating correlation memory format assets/ where the dashboard / alert screenshots go (see assets/README.md) ``` ## 运行说明 ``` $ soc-agent.sh --report ~/notes/.../security-report-2026-04-09.md [2026-04-09 06:00:01] Starting SOC agent on: security-report-2026-04-09.md [2026-04-09 06:00:01] Stage 1: classifying findings... [2026-04-09 06:02:01] Stage 1 done (120034ms): 6 findings [2026-04-09 06:02:01] Stage 2: assembling draft... [2026-04-09 06:03:48] Stage 2 done (107442ms) [2026-04-09 06:03:48] Stage 3: L2 flag triggered (1 unresolved findings) [2026-04-09 06:03:48] Injected L1 Analysis block into report [2026-04-09 06:03:49] Memory updated and committed [2026-04-09 06:03:49] Done ``` `--dry-run` 会将分析块打印到标准输出,而不是将其注入报告。该 agent 是幂等的:它会跳过已经包含 `## L1 Analysis` 部分的报告。 ## Agent 生成的产物 该 agent 会在每日报告中追加一个 **L1 Analysis** 块——包括安全态势、总结、操作项表格、每个告警的结论,以及(如果触发)L2 审核标志。请参阅 [`examples/sample-daily-report.md`](examples/sample-daily-report.md) 获取完整的前后对比;该块如下所示: ``` ## L1 分析 (gemma4:e4b - 2026-04-09 06:03) **Overall Posture:** ELEVATED Volume normal (~140k events). Dominant pattern is perimeter scan noise on the edge router (rule 100120), all blocked. One UNKNOWN: an outbound connection from the Windows lab VM worth a human glance. ### Action Items | # | Priority | Status | Item | Target | |---|----------|--------|------|--------| | 1 | Med | Open | Unexpected outbound from lab VM - confirm benign | win11-lab | | 2 | Info | L1 Closed | Edge scan noise, blocked at perimeter | router | ### Finding Verdicts | Finding | Verdict | Inference | |---------|---------|-----------| | Rule 100120 on router | KNOWN | Perimeter scan, dropped at firewall - recurring | | Rule 5710 on win11-lab | UNKNOWN | Outbound to unrecognised host, no vault note | ### 需要 L2 Review Gemma flagged 1 finding it could not resolve (threshold: 1). ``` ## 截图 请参阅 [`assets/README.md`](assets/README.md)。Telegram 实时告警、Wazuh dashboard 和渲染后的每日报告都在那里——已**脱敏**(这些显示了实时的主机/IP,并且图像的像素不受文本脱敏机制的保护,因此在发布前必须手动裁剪/模糊处理)。 ## 设计说明 - **本地化、小型、夜间运行是刻意为之。** 本地化将遥测数据保留在设备上(第三方无法看到安全事件,也没有按 token 收费)。`e4b` 足以在入门级 GPU 上进行初步分诊——它负责过滤和总结,不进行裁定。夜间运行利用了 GPU,此时没有其他任务需要它;摘要会在新的一天开始前准备好。 - **它是噪音过滤器和初步总结者,而不是决策者。** 根据设计,升级和裁定由人类完成——本地小模型擅长“显然是良性的/显然值得关注”,并且被限制在这条线的这一侧。 *自托管安全家庭实验室的一部分。规则 ID 是标准的 Wazuh ID;主机、地址和路径已进行抽象处理。* ## 许可证 [MIT](LICENSE) - 配置、脚本和文档可免费改编。
标签:AI风险缓解, Cutter, LLM, LLM评估, Metaprompt, Ollama, Unmanaged PE, 告警分诊, 安全运营, 扫描框架, 本地大模型