rathin-nair/threat-intel-pipeline
GitHub: rathin-nair/threat-intel-pipeline
该项目构建了一条从开源威胁情报源到 Elastic SIEM 检测引擎的检测即代码流水线,实现 IOC 摄取、Sigma 规则自动生成与 CI 驱动部署的全链路自动化。
Stars: 0 | Forks: 0
# 威胁情报检测流水线
一个“检测即代码”的流水线:摄取开源 IOC 订阅源和 MISP 威胁情报,自动从中生成 [Sigma](https://github.com/SigmaHQ/sigma) 检测规则,验证并将这些规则转换为可由 Elastic 部署的查询,最后将它们推送到 SIEM —— 所有这些都通过版本控制并由 CI 驱动。
这是一个在本地实验室环境中运行的**作品集/演示项目**,并非经过生产环境强化的部署(参见 [安全说明](#security-notes))。
## 架构
```
flowchart TD
A["abuse.ch feeds\n(URLhaus, ThreatFox, Feodo Tracker)"] --> B[normalize]
B --> C["push into MISP\n(Events / Attributes)"]
C --> D["MISP = source of truth for IOCs"]
D --> E["Sigma rule generation\n(Jinja2 templates, UUID5 rule IDs,\nMISP-timestamp watermark)"]
E --> F["rules/sigma/*.yml\n(git, PR-reviewed)"]
F --> G["validate (schema)\nhosted GH runner"]
F --> H["convert (pySigma → Elastic)\nhosted GH runner"]
G --> I["deploy: push to Kibana Detection Engine\nself-hosted GH runner"]
H --> I
I --> J["synthetic ECS logs indexed →\nverify detection fires"]
```
**为什么将 MISP 置于中间环节**,而不是直接从 abuse.ch 订阅源生成规则:MISP 是 IOC 状态持久且唯一的真实数据源 —— 去重、打标(TLP/置信度)以及 MISP 内置的 warninglist(过滤掉主要 DNS 解析器等已知的良性值)都在这里一次性完成,因此每个下游消费者(今天的 Sigma 生成,明天的任何其他需求)都从同一个经过审查的存储库中读取数据,而不是针对原始订阅源数据重新实现这套逻辑。
## 资源占用
MISP (PHP/MySQL) + 单节点 Elasticsearch + Kibana 大约需要 **8–16GB RAM 和约 20GB 磁盘空间**,冷启动时间约为 2 分钟(MISP 会在此期间执行首次启动迁移)。在此提前说明,以免您在运行 `make lab-up` 时感到意外。
## 前置条件
| 需求 | 说明 |
|---|---|
| Docker + Compose v2 | 必须能够运行 `docker compose version`(不支持旧版的 `docker-compose`) |
| `make` | 基础的 Debian/Ubuntu 安装中不包含此命令 —— 需执行 `apt install make`(或 `build-essential`) |
| Python 3.11+ 及 `venv` | 在 Debian/Ubuntu 上需执行 `apt install python3-venv`,否则 `make install` 会报错 "ensurepip is not available" |
| 约 8–16GB RAM,约 20GB 磁盘 | 参见 [资源占用](#resource-footprint) |
## 快速开始
```
# 1. Install
make install # creates .venv, installs the package + dev deps
# 2. Configure (required - the stack reads every password from here)
cp .env.example .env
# Fill in ABUSECH_AUTH_KEY (register at https://auth.abuse.ch/ - required
# for URLhaus + ThreatFox since 2025-06-30; Feodo Tracker needs no key).
# The changeme-* infrastructure passwords work as-is for a local lab.
# 3. Bring up the local lab
make lab-up # MISP + Elasticsearch + Kibana via Docker
# MISP: https://localhost (log in with MISP_ADMIN_EMAIL / MISP_ADMIN_PASSPHRASE)
# Kibana: http://localhost:5601 (log in as elastic / see ELASTIC_PASSWORD)
# Generate a MISP API key from the UI (Administration > List Auth Keys) and
# put it in .env as MISP_API_KEY. Or, headless:
# docker exec tip-misp-misp-core-1 su -s /bin/bash www-data \
# -c "/var/www/MISP/app/Console/cake User change_authkey admin@admin.test"
# 4. Point detections at your logs
# DETECTION_INDEX_PATTERN in .env must match where logs actually land. The
# default (demo-logs-*) matches scripts/generate_synthetic_logs.py; change
# it to filebeat-*/logs-* etc. for real data, or rules will deploy but
# never match anything.
# 5. Run the pipeline end to end
make demo # ingest -> generate -> validate -> convert -> deploy
# 6. See detections actually fire (optional)
.venv/bin/python3 scripts/generate_synthetic_logs.py --index
# then watch Kibana > Security > Alerts; rules run on a 5-minute interval
```
手头没有 Docker?`make test` 可以针对手动编写的 MISP-attribute 测试夹具运行完整的流水线逻辑(规则生成、验证、转换),且**完全不需要任何外部服务** —— 详见 [`tests/smoke/test_offline_generation.py`](tests/smoke/test_offline_generation.py)。
### Makefile 目标
| 目标 | 作用 |
|---|---|
| `make install` | 创建 `.venv`,安装包及开发依赖 |
| `make lab-up` / `make lab-down` | 启动/停止本地的 MISP + Elastic/Kibana 技术栈 |
| `make lab-status` | 显示两个技术栈的容器状态 |
| `make ingest` | 获取 abuse.ch 订阅源,进行标准化,并推送到 MISP |
| `make generate` | 根据新的 MISP 属性生成 Sigma 规则 |
| `make validate` | 对 `rules/sigma/*.yml` 执行 `sigma-cli check` |
| `make convert` | 将 Sigma 规则转换为 Elastic 查询(存放在 `queries/`,已被 gitignore 忽略) |
| `make deploy` | 将规则推送到 Kibana 的 Detection Engine,并停用过期规则 |
| `make demo` | 链式执行 `ingest generate validate convert deploy` |
| `make test` / `make smoke` | 运行单元测试+冒烟测试 / 仅运行冒烟测试 |
## 仓库结构
```
src/threat_intel_pipeline/
feeds/ abuse.ch clients (URLhaus, ThreatFox, Feodo Tracker) + shared retry/backoff
normalize/ NormalizedIOC pydantic schema (the fixed ioc_type enum Phase-3 keys off of)
misp_client/ PyMISP wrapper: push IOCs, warninglist filtering, MISP <-> NormalizedIOC mapping
sigma_gen/ Jinja2 Sigma rule templates + idempotent (UUID5) generator + watermark cursor
validate/ sigma-cli check wrapper
convert/ Sigma -> Elastic Lucene/Detection-Engine query conversion
deploy/ Kibana Detection Engine API push + TTL-based rule retirement
docker/ docker-compose for MISP and Elastic/Kibana (local lab only)
rules/sigma/ generated Sigma rules - the actual detection-as-code artifact (git-tracked)
queries/ converted Elastic queries - gitignored, regenerated by `make convert`
scripts/ run_ingest.py, generate_synthetic_logs.py
tests/
unit/ fast, no external services
smoke/ offline rule-generation pipeline against a JSON fixture, no live MISP/Elastic
integration/ full e2e against a live Elastic (skips automatically if unreachable)
```
有关水印/幂等性设计以及 CI 的可达性拆分(自托管 vs. 托管运行器),请参见 [`docs/architecture.md`](docs/architecture.md)。
## 安全说明
- **自托管的 GitHub Actions 运行器**:仅连接到 `schedule` / `workflow_dispatch` / 推送到 `main` 分支的触发器 —— 绝不绑定 `pull_request`。来自复刻仓库的 PR 绝不能在您的机器上执行。
- **Secrets**:abuse.ch 的 Auth-Key 和 MISP 的 API key 在本地存放在 `.env` 中,并作为自托管运行器的 GitHub Actions secrets 保存。应用程序代码绝不会记录原始的 key 值 —— 仅记录其存在性/成功状态(例如 "MISP push OK, 12 attributes")。
- **本仓库不包含任何凭证。** 每个基础设施的密码(Elasticsearch、`kibana_system`、Kibana 的加密 key、MISP 的 MySQL / Redis / 管理员密码)都是通过 Compose 的变量替换从您被 gitignore 忽略的 `.env` 文件中读取的。compose 文件仅引用 `${VAR}` 而不包含其他内容;如果缺少某个值,`make lab-up` 将会报错并给出明确的提示信息。`.env.example` 附带了用于回环测试环境的临时 `changeme-*` 默认值,如果在其他环境中使用则必须进行修改。
- **所有端口仅绑定到 `127.0.0.1`** —— 绝不绑定到 `0.0.0.0`。全接口绑定再加上可预测的凭证,是暴露的 Elasticsearch 实例被自动化扫描器发现并勒索的标准方式。如果您需要远程访问,请通过隧道(`ssh -L`)连接,而不是扩大绑定范围。
- **本地实验室的便捷设置,绝非生产环境的做法**:不使用 TLS 的身份验证(`xpack.security.http.ssl.enabled=false`)、MISP 的自签名证书、没有备份的单节点 Elasticsearch,以及 Kibana 使用共享账户连接,而不是每个组件使用独立的服务账户。在您的机器以外的任何环境使用本项目之前,所有这些都需要替换。
- **Elasticsearch 安全功能已启用且不可关闭。** Kibana 的 Detection Engine Rules UI 会调用权限检查 endpoint,当 `xpack.security` 关闭时会返回 400 错误,导致页面完全崩溃 —— 因此技术栈在运行时开启了身份验证。被禁用的是 TLS,以便在脚本化实验室环境中跳过 Elastic 的证书注册流程。
## 版权归属
IOC 订阅源由 [abuse.ch](https://abuse.ch/) 免费提供(URLhaus、ThreatFox、Feodo Tracker)。abuse.ch 的条款限制了对订阅源数据的转售/重新打包,并期望获得署名 —— 本仓库不提交原始的批量订阅源转储数据,仅包含一个精心挑选的小型测试夹具(`tests/fixtures/sample_iocs.json`)。
通过 [MISP](https://www.misp-project.org/) 进行威胁情报的存储/关联。
检测规则采用 [Sigma](https://github.com/SigmaHQ/sigma) 格式编写,并通过 [pySigma](https://github.com/SigmaHQ/pySigma) / [pySigma-backend-elasticsearch](https://github.com/SigmaHQ/pySigma-backend-elasticsearch) 进行转换。
## 许可证
[MIT](LICENSE)。
各项依赖保留了其各自的许可证,且未在此处重新分发 —— 它们通过 pip 单独安装。值得注意的是,`sigma-cli` 和 `pySigma` 采用 LGPL-2.1-or-later 许可证,而 PyMISP 采用 BSD 许可证;本项目将它们作为库使用,并调用 `sigma check` 作为子进程,因此 MIT 许可证仅适用于本项目的代码。
abuse.ch 的 **订阅源数据** 完全不受本许可证的约束 —— 其相关条款请参见 [版权归属](#attribution)。
标签:Elasticsearch, PB级数据处理, Reconnaissance, Sigma规则, 威胁情报, 安全运维, 开发者工具, 目标导入, 自动化流水线, 请求拦截, 越狱测试, 逆向工具