yigitdayoglu/detection-as-code
GitHub: yigitdayoglu/detection-as-code
该项目将安全检测规则纳入 Git 版本控制与 GitHub Actions CI/CD 流水线,实现规则的自动测试、审查和部署,取代传统的 SIEM 控制台手动管理方式。
Stars: 0 | Forks: 0
# Detection-as-Code CI/CD Pipeline


安全检测规则的管理方式与软件相同:在 Git 中进行版本控制,通过 pull request 进行更改、自动测试,并在无需任何人手动编辑控制台的情况下部署到生产环境。该设计遵循 [RunReveal Detection-as-Code 指南](https://blog.runreveal.com/runreveal-detection-cicd-guide/),并借鉴了 Sigma 和 Elastic 检测项目的约定。
## 为什么需要它
管理 SIEM 规则的传统方式是登录 Web 控制台并进行手动编辑。这种方法没有更改历史记录、没有审查步骤,并且在规则生效前也没有测试。一个拼写错误可能会静默禁用关键规则,而范围过广的规则可能会让分析师淹没在误报之中。没人能回答“这是谁更改的,什么时候,以及为什么?”。
Detection-as-Code 将检测规则视为源代码。每一次更改都是带有作者和原因的 commit。每一次更改在进入生产环境前都会经过审查和测试。如果某条规则在凌晨 3 点引发了故障,待命分析师可以查看 git 历史记录,了解 pull request 中的逻辑推理,并一步将其 revert。
## 架构
该仓库是唯一的真实来源。在其之上运行着两个 pipeline,它们由信任边界隔开:验证在不受信任的 pull-request 代码上运行,且无法访问生产环境;而部署则在已合并到 `main` 分支的经过审查的代码上运行。
```
flowchart TD
A[feature branch] -->|open PR| B{Validation CI
validate.yml} B -->|lint schema + run tests| C{pass?} C -->|no| D[merge blocked
branch protection] C -->|yes| E[review + squash merge] E --> F[main
source of truth] F -->|push to main| G[Deployment CD
deploy.yml] G -->|inject production secret| H[sync rules to RunReveal] F -->|VERSION changed| I[Release
release.yml] I --> J[git tag + GitHub release] ``` 这两个触发器拥有不同的权限级别。`pull_request` 的代码尚未受信任,因此验证 pipeline 没有任何 secret,也无法触及生产环境。向 `main` 分支的 `push` 意味着代码已经通过了审查和 CI,因此部署 pipeline 被允许从限定了作用域的 environment secret 中读取生产环境的 token。相同的信任边界,不同的两面。 ## 仓库布局 ``` detection-as-code/ ├── .github/workflows/ │ ├── validate.yml # CI: lint + test on every pull request │ ├── deploy.yml # CD: sync rules to production on merge to main │ └── release.yml # tag + GitHub release when VERSION changes ├── detections/ │ ├── sql/ # RunReveal-style SQL detections, grouped by log source │ │ └── aws/ │ └── sigma/ # portable, platform-agnostic Sigma rules ├── tests/datasets/ # synthetic log events with expected match/no-match ├── scripts/ │ ├── validate_rules.py # schema + policy validation │ ├── test_rules.py # behavioural unit tests │ └── deploy_rules.py # deployment tool (dry-run by default) ├── docs/runbook.md # operational procedures ├── VERSION # current rule-set version (SemVer) ├── CHANGELOG.md # human-readable change history └── requirements.txt # pinned Python dependencies ``` 规则按日志源(`aws`、`okta` 等)进行分组,因为检测是针对特定源的 schema 编写的。MITRE ATT&CK 的覆盖范围记录在每个规则的 metadata 中,而不是通过文件夹来区分,因此可以通过两种方式找到同一个规则。 ## 检测是如何构成的 每个规则都是一个单一的 YAML 文件,同时包含 query 及其 metadata,因此这两者永远不会产生偏差。一个 SQL 检测如下所示: ``` id: aws-console-login-no-mfa name: AWS Console Login Without MFA description: > Detects successful AWS console logins by IAM users without MFA. Federated/SSO logins are excluded because their MFA is enforced at the identity provider. severity: high status: experimental mitre_attack: tactic: TA0001 technique: T1078.004 false_positives: - Break-glass emergency accounts intentionally exempt from MFA query: | SELECT eventTime, userIdentity.userName AS user_name, sourceIPAddress AS source_ip FROM aws_cloudtrail WHERE eventName = 'ConsoleLogin' AND responseElements.ConsoleLogin = 'Success' AND additionalEventData.MFAUsed != 'Yes' AND userIdentity.type = 'IAMUser' ``` `false_positives` 和排除理由与 query 同样重要:它们会告知待命分析师该规则为什么会触发,以及何时可以安全地将其忽略。每个规则都在 `detections/sigma/` 下附带了 Sigma 等效文件,以便在不同的 SIEM 平台间移植,并在 `tests/datasets/` 下提供了一个测试数据集。 ## 本地开发 ``` git clone https://github.com/yigitdayoglu/detection-as-code.git cd detection-as-code python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt python scripts/validate_rules.py # schema + policy checks python scripts/test_rules.py # behavioural tests against datasets python scripts/deploy_rules.py # dry-run: shows what would deploy ``` 你在本地运行的同样也是 CI 运行的那两个命令,因此你可以在打开 pull request 之前看到通过(绿色)的结果。 ## 贡献工作流 `main` 分支受保护:禁止直接 push(即使是管理员也不行),并且 `validate` 检查必须在 pull request 合并前通过。 ``` git switch -c feature/my-new-rule # 添加规则、其对应的 Sigma 以及测试数据集 python scripts/validate_rules.py && python scripts/test_rules.py git commit -am "feat: add my new detection" git push -u origin feature/my-new-rule gh pr create ``` 一旦 CI 变绿(通过)并且 pull request 经过审查后,请对其进行 squash-merge。合并操作会自动触发部署。 ## 部署与 secrets 合并到 `main` 分支时,`deploy.yml` 将针对 GitHub 的 `production` 环境运行。RunReveal API token 作为 secret 存在于该环境中,会在 runtime 注入到 job 中,并在日志中进行遮盖处理。它永远不会出现在源代码中。为了实际推送更改,部署工具需要使用 `--apply` 标志;其默认行为是 dry run。 ## 版本控制与发布 规则集在 `VERSION` 文件中使用[语义化版本控制](https://semver.org/):新增检测为 MINOR 版本更新,修复为 PATCH 版本更新,而对 pipeline 或 schema 的破坏性更改则为 MAJOR 版本更新。在已合并的 pull request 中更新 `VERSION` 会触发 `release.yml`,从而创建相应的 git tag 和 GitHub release。更改会记录在 [CHANGELOG.md](CHANGELOG.md) 中。 ## 回滚 由于生产环境是 `main` 的镜像,回滚错误规则只需进行 git 操作即可:通过 pull request revert 有问题的合并,部署 pipeline 会将生产环境重新同步到 revert 后的状态。完整流程请参阅 [docs/runbook.md](docs/runbook.md)。 ## 范围与限制 这是一个个人作品集项目,特意划定了两个边界: - **RunReveal 同步已打桩(stubbed)。** `deploy_rules.py` 会读取 token、遍历规则,并像真实的部署一样报告每个规则的结果,但由于该项目不提供真实的凭证,网络调用实际上只是一个占位符。替换为真实的 API 调用仅需修改一行代码。 - **测试运行器在 Python 中模拟检测逻辑。** 它会评估规则所使用的 SQL 子集(由 `AND` 连接的相等和不等比较组成的 `WHERE` 子句),而不是运行真实的 ClickHouse 引擎。它测试的是规则逻辑,而不是查询引擎。
validate.yml} B -->|lint schema + run tests| C{pass?} C -->|no| D[merge blocked
branch protection] C -->|yes| E[review + squash merge] E --> F[main
source of truth] F -->|push to main| G[Deployment CD
deploy.yml] G -->|inject production secret| H[sync rules to RunReveal] F -->|VERSION changed| I[Release
release.yml] I --> J[git tag + GitHub release] ``` 这两个触发器拥有不同的权限级别。`pull_request` 的代码尚未受信任,因此验证 pipeline 没有任何 secret,也无法触及生产环境。向 `main` 分支的 `push` 意味着代码已经通过了审查和 CI,因此部署 pipeline 被允许从限定了作用域的 environment secret 中读取生产环境的 token。相同的信任边界,不同的两面。 ## 仓库布局 ``` detection-as-code/ ├── .github/workflows/ │ ├── validate.yml # CI: lint + test on every pull request │ ├── deploy.yml # CD: sync rules to production on merge to main │ └── release.yml # tag + GitHub release when VERSION changes ├── detections/ │ ├── sql/ # RunReveal-style SQL detections, grouped by log source │ │ └── aws/ │ └── sigma/ # portable, platform-agnostic Sigma rules ├── tests/datasets/ # synthetic log events with expected match/no-match ├── scripts/ │ ├── validate_rules.py # schema + policy validation │ ├── test_rules.py # behavioural unit tests │ └── deploy_rules.py # deployment tool (dry-run by default) ├── docs/runbook.md # operational procedures ├── VERSION # current rule-set version (SemVer) ├── CHANGELOG.md # human-readable change history └── requirements.txt # pinned Python dependencies ``` 规则按日志源(`aws`、`okta` 等)进行分组,因为检测是针对特定源的 schema 编写的。MITRE ATT&CK 的覆盖范围记录在每个规则的 metadata 中,而不是通过文件夹来区分,因此可以通过两种方式找到同一个规则。 ## 检测是如何构成的 每个规则都是一个单一的 YAML 文件,同时包含 query 及其 metadata,因此这两者永远不会产生偏差。一个 SQL 检测如下所示: ``` id: aws-console-login-no-mfa name: AWS Console Login Without MFA description: > Detects successful AWS console logins by IAM users without MFA. Federated/SSO logins are excluded because their MFA is enforced at the identity provider. severity: high status: experimental mitre_attack: tactic: TA0001 technique: T1078.004 false_positives: - Break-glass emergency accounts intentionally exempt from MFA query: | SELECT eventTime, userIdentity.userName AS user_name, sourceIPAddress AS source_ip FROM aws_cloudtrail WHERE eventName = 'ConsoleLogin' AND responseElements.ConsoleLogin = 'Success' AND additionalEventData.MFAUsed != 'Yes' AND userIdentity.type = 'IAMUser' ``` `false_positives` 和排除理由与 query 同样重要:它们会告知待命分析师该规则为什么会触发,以及何时可以安全地将其忽略。每个规则都在 `detections/sigma/` 下附带了 Sigma 等效文件,以便在不同的 SIEM 平台间移植,并在 `tests/datasets/` 下提供了一个测试数据集。 ## 本地开发 ``` git clone https://github.com/yigitdayoglu/detection-as-code.git cd detection-as-code python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt python scripts/validate_rules.py # schema + policy checks python scripts/test_rules.py # behavioural tests against datasets python scripts/deploy_rules.py # dry-run: shows what would deploy ``` 你在本地运行的同样也是 CI 运行的那两个命令,因此你可以在打开 pull request 之前看到通过(绿色)的结果。 ## 贡献工作流 `main` 分支受保护:禁止直接 push(即使是管理员也不行),并且 `validate` 检查必须在 pull request 合并前通过。 ``` git switch -c feature/my-new-rule # 添加规则、其对应的 Sigma 以及测试数据集 python scripts/validate_rules.py && python scripts/test_rules.py git commit -am "feat: add my new detection" git push -u origin feature/my-new-rule gh pr create ``` 一旦 CI 变绿(通过)并且 pull request 经过审查后,请对其进行 squash-merge。合并操作会自动触发部署。 ## 部署与 secrets 合并到 `main` 分支时,`deploy.yml` 将针对 GitHub 的 `production` 环境运行。RunReveal API token 作为 secret 存在于该环境中,会在 runtime 注入到 job 中,并在日志中进行遮盖处理。它永远不会出现在源代码中。为了实际推送更改,部署工具需要使用 `--apply` 标志;其默认行为是 dry run。 ## 版本控制与发布 规则集在 `VERSION` 文件中使用[语义化版本控制](https://semver.org/):新增检测为 MINOR 版本更新,修复为 PATCH 版本更新,而对 pipeline 或 schema 的破坏性更改则为 MAJOR 版本更新。在已合并的 pull request 中更新 `VERSION` 会触发 `release.yml`,从而创建相应的 git tag 和 GitHub release。更改会记录在 [CHANGELOG.md](CHANGELOG.md) 中。 ## 回滚 由于生产环境是 `main` 的镜像,回滚错误规则只需进行 git 操作即可:通过 pull request revert 有问题的合并,部署 pipeline 会将生产环境重新同步到 revert 后的状态。完整流程请参阅 [docs/runbook.md](docs/runbook.md)。 ## 范围与限制 这是一个个人作品集项目,特意划定了两个边界: - **RunReveal 同步已打桩(stubbed)。** `deploy_rules.py` 会读取 token、遍历规则,并像真实的部署一样报告每个规则的结果,但由于该项目不提供真实的凭证,网络调用实际上只是一个占位符。替换为真实的 API 调用仅需修改一行代码。 - **测试运行器在 Python 中模拟检测逻辑。** 它会评估规则所使用的 SQL 子集(由 `AND` 连接的相等和不等比较组成的 `WHERE` 子句),而不是运行真实的 ClickHouse 引擎。它测试的是规则逻辑,而不是查询引擎。
标签:多线程, 逆向工具