一个被忽视的等式:转换成功 ≠ 检测有效
Detection-as-Code 的实践者常把 Sigma 规则仓库的 CI/CD 流水线设计成三段式:
这个模型在语法层面是闭环的——YAML 格式正确、能成功转成 Splunk SPL 或 Sentinel KQL、能推送到生产 SIEM。但它漏掉了一个关键问题:这条规则在你的日志环境里真的能命中预期事件吗?
Sigma 的通用格式设计本意是打破厂商锁定,让检测逻辑脱离特定 SIEM 的查询方言。但这个抽象层也带来了语义损耗:字段名在不同日志源中的映射、时间戳格式差异、大小写敏感度、多值字段的解析方式、甚至同一 Event ID 在不同 Windows 版本中的字段缺失——这些细节在 sigma convert 的输出里不会自动暴露。
本文从工程落地的角度,讨论 Sigma 规则进入 CI/CD 后必须补上的验证环节,以及为什么“验证”比“转换”更能决定检测工程的质量。
Sigma 生态的当前状态
Sigma 规则库目前维护超过 3000 条社区规则,覆盖 Windows、Linux、云服务和多种应用日志。核心工具链包括:
| 组件 | 作用 | 版本基线 |
|---|---|---|
| sigma-cli | 规则转换 CLI,基于 pySigma | v1.x |
| pySigma | Python 解析与转换库 | v0.11+ |
| Backend Plugins | Splunk、Elastic、Sentinel、Loki 等后端 | 各独立版本 |
| Pipeline Plugins | 字段映射与日志源适配(如 sysmon、crowdstrike) | 各独立版本 |
| sigma-rules-validator | JSON Schema 校验 GitHub Action | v1 |
安装与基础转换示例:
pip install sigma-cli
sigma plugin install splunk
sigma convert --target splunk --pipeline splunk_windows ./rules/一条典型 Sigma 规则的结构:
title: Windows Defender Threat Detection Disabled
logsource:
product: windows
service: windefend
detection:
selection:
EventID:
- 5001
- 5010
- 5012
- 5101
condition: selection
level: high转换后的 Splunk SPL:
source="WinEventLog:Microsoft-Windows-Windows Defender/Operational" EventCode IN (5001, 5010, 5012, 5101)看起来干净直接,但这里的 source= 和 EventCode 是 splunk_windows pipeline 的默认映射。如果你的 Splunk 环境中该日志的 source 名称不同,或者字段名是 event_id 而非 EventCode,这条规则转换成功但永远不会触发。
CI/CD 流水线的三层验证
把检测工程当成软件工程来管理,意味着验证不能停在“YAML 没写错”。建议把流水线拆成三层:
Layer 1:Schema 验证(已有成熟方案)
Grafana Labs SecOps 团队向 SigmaHQ 贡献了 JSON Schema 和 sigma-rules-validator GitHub Action。它能验证规则文件的 YAML 结构、必填字段、UUID 格式、相关引用等。
# .github/workflows/validate-sigma.yml
name: Validate Sigma Rules
on: [pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: SigmaHQ/sigma-rules-validator@v1
with:
paths: "./rules"
schemaURL: "https://raw.githubusercontent.com/SigmaHQ/sigma-specification/main/sigma-schema.json"这一步能拦住 80% 的格式错误,但它对检测逻辑的正确性一无所知。
Layer 2:转换测试(多数团队到此为止)
在 CI 中遍历所有目标后端,确保每条规则都能成功转换:
for backend in splunk elastic sentinel loki; do
sigma convert --target "$backend" --pipeline "${backend}_windows" ./rules/ || exit 1
done这一步能发现后端不支持的修饰符、字段类型冲突、pipeline 缺失等问题。但它的盲区在于:转换成功只代表语法兼容,不代表语义正确。
Layer 3:回归测试与字段映射验证(最需要补上的环节)
这是检测工程区别于普通代码工程的核心差异。代码的单元测试可以 mock 依赖,但检测规则的“单元测试”必须验证它能否在真实日志结构上正确匹配。
回归测试的最小可行方案:
- 样本日志库:为每条规则维护一组“应该命中”和“不应该命中”的样本日志(JSON/行格式)。
- 端到端匹配:用转换后的 SIEM 查询在样本日志上执行,验证是否返回预期结果。
- 字段映射漂移检测:当 pipeline 或后端插件升级时,自动比对字段映射变更,标记可能受影响的规则。
# 示例:规则同目录下的测试配置
# rules/windows/process_creation/proc_creation_win_malware_test.yml
test_cases:
should_match:
- name: "Base64 encoded PowerShell"
log: |
{ "CommandLine": "powershell -EncodedCommand ZQBjAGgAbwAgAGgAZQBsAGwAbwA=", "EventID": 4688 }
should_not_match:
- name: "Normal PowerShell execution"
log: |
{ "CommandLine": "powershell.exe -File C:\\scripts\\backup.ps1", "EventID": 4688 }这个测试数据当前不是 Sigma 官方规范的一部分,需要团队自行维护。但它的价值在于:把“规则是否正确”从主观判断变成可自动执行的断言。
字段映射:最隐蔽的失效模式
Sigma 的 pipeline 机制负责把通用字段映射到 SIEM 专有字段。这是整个链路中最容易出错的环节,因为映射是配置而非代码,变更往往不会被评审视为“逻辑修改”。
常见映射失效场景
| 场景 | 表现 | 发现难度 |
|---|---|---|
| 字段重命名 | Splunk 索引侧把 src_ip 改为 src_ip_address | 高,转换仍成功 |
| 字段缺失 | 新日志源版本不再输出 ParentProcessName | 高,查询返回空结果 |
| 大小写差异 | 规则写 EventID,实际字段是 eventid | 中,部分 SIEM 不敏感 |
| 多值字段 | 规则匹配单值,实际日志中该字段是数组 | 高,行为不可预测 |
| 时间戳解析 | @timestamp 格式从 ISO8601 变为 Unix ms | 中,影响时间窗口过滤 |
治理建议:把字段映射表当成接口契约来管理。每次 pipeline 变更都必须附带受影响规则清单,并在 CI 中执行回归测试。
生产落地的硬性约束
| 约束项 | 说明 | 缓解措施 |
|---|---|---|
| 后端版本碎片化 | Splunk 8.x 与 9.x 的 SPL 语法差异 | CI 矩阵测试多版本 |
| Pipeline 插件滞后 | 新日志源(如 CrowdStrike Falcon NG)无官方 pipeline | 自建内部 pipeline,定期同步上游 |
| 规则量膨胀 | 3000+ 社区规则,全部启用导致 SIEM 查询队列拥堵 | 按环境、资产类型、威胁模型分层启用 |
| 误报基线缺失 | 新规则上线即全量告警,未经过观察期 | 新规则默认“仅记录”运行 7 天 |
| 样本日志脱敏 | 真实日志含敏感数据,不能直接用于 CI 测试 | 字段级脱敏 + 合成日志 |
结论
Sigma 规则进 CI/CD 的核心差距不在于转换,而在于验证。Schema 校验能拦住格式错误,转换测试能发现后端兼容性问题,但只有回归测试能证明规则在真实日志结构上能命中预期事件。字段映射漂移是最隐蔽的失效模式,需要把映射表当成接口契约来管理,每次 pipeline 变更都附带受影响规则清单。
后续研究方向
- Sigma 规则与 K8s 审计日志、云 Trail 日志的 pipeline 建设现状如何?自建映射的成本是否值得?
- 当 SIEM 厂商原生支持 Sigma 格式(如 Chronicle 的 YARA-L 与 Sigma 的互转)时,pySigma 后端的维护责任如何分配?
- 大语言模型辅助规则生成(自然语言描述 → Sigma YAML)的误报率与可维护性是否满足生产要求?


