THREATRADAR-Pipeline/ThreatRadar
GitHub: THREATRADAR-Pipeline/ThreatRadar
一个面向 SOC 和威胁情报团队的开源端到端情报流水线,通过 AI 驱动的投毒检测、Cortex 自动评分和 MISP 集成,帮助团队从多源 feed 中提取、验证并分发可信 IOC。
Stars: 19 | Forks: 0
# ThreatRadar
一个端到端的威胁情报流水线,具备 AI 驱动的 feed 投毒检测、Cortex 驱动的 IOC 评分以及 MISP 集成。
## [](LICENSE)
[](https://www.python.org/)
[](https://www.elastic.co/)
[](https://www.elastic.co/kibana)
[](https://www.elastic.co/beats/filebeat)
[](https://www.docker.com/)
[](https://github.com/TheHive-Project/Cortex)
[](https://www.misp-project.org/)
[](https://medium.com/@salmactf/designing-and-implementing-threatradar-an-open-source-feed-based-threat-intelligence-pipeline-73d568da8f27)
## 目录
- [概述](#overview)
- [流水线架构](#pipeline-architecture)
- [功能特性](#features)
- [技术栈](#technology-stack)
- [前置条件](#prerequisites)
- [完整安装指南](#full-installation-guide)
- [配置说明](#configuration)
- [环境变量](#environment-variables)
- [Cortex 分析器](#cortex-analyzer)
- [威胁情报 Feed](#threat-intelligence-feeds)
- [ML 投毒检测](#ml-poisoning-detection)
- [MISP 集成](#misp-integration)
- [运行 ThreatRadar](#running-threatradar)
- [Docker 部署](#docker-deployment)
- [Kibana 仪表板](#kibana-dashboards)
- [故障排除](#troubleshooting)
- [贡献指南](#contributing)
- [许可证与致谢](#license-and-credits)
## 概述
ThreatRadar 是一个开源的威胁情报流水线,专为安全运营中心 (SOC) 和威胁情报团队设计。它从多个来源聚合 IOC,通过 Cortex 分析器对其进行富化和评分,并在结果到达分析师队列之前,使用 LLM 和 IsolationForest 模型检测 feed 数据中的统计异常和语义矛盾。
其核心设计目标是解决 **feed 投毒** 问题:即向威胁情报 feed 中注入虚假或误导性的 IOC,以操纵防御者的决策。ThreatRadar 通过流水线级别的 AI 检测和来自 MISP 中分析师目击事件的闭环反馈来解决这一问题。
**ThreatRadar 的功能:**
- 从多个开源和商业 feed 中提取 IOC
- 将 IOC 标准化并分类到 7 个类型化的 Elasticsearch 索引中
- 通过 MITRE ATT&CK 映射、CVSS 评分和攻击者归因来富化每个 IOC
- 通过 Cortex 分析器(VirusTotal、AbuseIPDB、Maltiverse、IPinfo、Urlscan、HybridAnalysis)对 IOC 进行评分
- 使用经过训练的 IsolationForest 模型和 LLM 标记统计异常的 IOC,LLM 根据针对 8 类矛盾(APT-行业不匹配、恶意软件不兼容、不合理的组合等)的语义验证,来确定情报是安全的还是被投毒的。
- 将经过验证和富化的 IOC 推送到 MISP,并带有 TLP 标记和分发控制
- 使用分析师的目击事件作为反馈信号来重新训练异常模型
- 每日将 MISP 事件与最新的富化评分和判定结果同步
- 在 180 天的滚动窗口中从 Elasticsearch 过期删除陈旧的 IOC 数据,同时保护像 CVE、勒索软件家族和加密钱包这样的永久参考数据集
## 流水线架构
ThreatRadar 以一组 Docker 微服务的形式运行,分为 9 个顺序阶段:

## 功能特性
- **多源 feed 提取**:NVD、OTX、AbuseIPDB、EmergingThreats、SSL Blacklist 以及许多其他源。可以在不修改核心逻辑的情况下添加自定义源。
- **七种 IOC 类型分类**:IP 地址、URL、文件哈希、域名、CVE、勒索软件家族和加密钱包,每种都路由到适合其类型的分析器。
- **Cortex 分析器集成**:跨六个情报服务进行自动化的 IOC 查询,生成具有严重性级别(CRITICAL / HIGH / MEDIUM / LOW)和推荐操作的标准综合评分。
- **ML 异常检测与 LLM 语义验证**:一个经过校准污染评分的 scikit-learn IsolationForest 模型,可在统计异常的 IOC 进入分析师队列之前对其进行标记。
标记的 IOC 随后会进行 LLM 语义分析(通过 OpenRouter 的 OpenAI GPT-4o),根据针对 8 类矛盾的检查(如 APT-行业不匹配、恶意软件不兼容和威胁组合)来验证情报,并判定情报是 COHERENT(连贯)、SUSPICIOUS(可疑)还是 CONTRADICTED(矛盾)。
- **自动化 MISP 发布**:将富化后的 IOC 批量推送到 MISP,并附带 TLP 分类、分发标签和可配置的 worker 并发性。
- **MISP 每日刷新**:使 MISP 事件与最新的富化评分和判定保持同步,并重新排队任何 MISP 事件已丢失的 IOC。
- **基于反馈的重新训练**:MISP 的目击事件和分析师确认会在满足可配置信号阈值和冷却期后,触发增量模型重新训练。
- **Kibana 仪表板**:预构建的仪表板,用于显示 feed 覆盖范围、IOC 评分分布、SOC 情报和流水线吞吐量。
- **数据保留**:在 180 天的滚动窗口中自动从 Elasticsearch 中移除过期的 IOC 数据,并对 CVE、勒索软件家族和加密钱包等参考数据集提供永久保护。
- **完全容器化**:九个 Docker 服务,配备健康检查、声明的服务间依赖关系和共享的命名网络。
- **无硬编码凭证**:所有密钥均通过环境变量注入。`.gitignore` 默认排除了 `.env`。
## 技术栈
| 层级 | 技术 | 版本 | 角色 |
|---|---|---|---|
| 搜索与存储 | Elasticsearch | 9.3.0 | 跨 7 个类型化索引的主要 IOC 存储 |
| 可视化 | Kibana | 9.3.0 | 仪表板和索引管理 |
| 日志传输 | Filebeat | 9.3.0 | 结构化日志和 feed 提取 |
| IOC 分析 | Cortex (TheHive Project) | latest | 分析器编排引擎 |
| 威胁共享 | MISP | latest | 社区威胁共享平台 |
| 数据库 | MySQL | 8.0 | MISP 后端关系存储 |
| 缓存与队列 | Redis | 7 | MISP 会话和队列管理 |
| 运行时 | Python | 3.11+ | 所有流水线脚本 |
| 机器学习 | scikit-learn | ≥ 1.2.0 | IsolationForest 异常检测 |
| LLM 与语义分析 | OpenRouter(GPT-4o) | latest | 针对被投毒威胁情报的语义矛盾检测 |
| 数据处理 | pandas / numpy | ≥ 2.0 / ≥ 1.24 | 特征工程和数据清洗 |
| MISP 客户端 | PyMISP | ≥ 2.4.170 | 以编程方式与 MISP 交互 |
| Elasticsearch 客户端 | elasticsearch-py | ≥ 9.0 | Elasticsearch 批量操作 |
| 模型持久化 | joblib | ≥ 1.3.0 | IsolationForest 模型序列化 (`.pkl`) |
| 报告 | ReportLab | ≥ 4.0.0 | PDF 报告生成 |
| 容器化 | Docker + Compose | _ | 全栈编排 |
### 外部情报服务 (通过 Cortex)
| 服务 | IOC 类型 |
|---|---|
| VirusTotal | IP, URL, Hash, Domain |
| AbuseIPDB | IP |
| Maltiverse | IP, URL, Hash, Domain |
| IPinfo | IP |
| Urlscan.io | URL, Hash, Domain |
| HybridAnalysis | URL, Domain |
## 前置条件
### 系统要求
| 资源 | 最低配置 | 推荐配置 |
|---|---|---|
| 操作系统 | Ubuntu 22.04 LTS, macOS | Ubuntu 22.04 LTS |
| 内存 | 8 GB | 16 GB |
| 磁盘 | 20 GB 可用空间 | 50 GB 可用空间 |
| CPU | 4 核 | 8 核 |
### 所需软件
```
python3 --version # 3.11.x or 3.12.x required
docker --version # 24.x or later
docker compose version # v2.x required
git --version
```
### API 密钥
| 服务 | 是否必需 | 获取途径 |
|---|---|---|
| Elasticsearch | 是 | 自托管:由 Docker 自动配置 |
| Cortex | 是 | 自托管:安装完成后通过 Cortex UI 生成 |
| NVD (NIST) | 是 | [nvd.nist.gov/developers/request-an-api-key](https://nvd.nist.gov/developers/request-an-api-key) |
| AbuseIPDB | 是 | [abuseipdb.com/account/api](https://www.abuseipdb.com/account/api) |
| AlienVault OTX | 是 | [otx.alienvault.com](https://otx.alienvault.com) → API Keys |
| MISP | 是| 通过包含的 Docker 栈自托管 |
| OpenRouter | 是 | [openrouter.ai/keys](https://openrouter.ai/keys) → New Key |
## 完整安装指南
### 步骤 1:克隆代码库
```
git clone https://github.com/THREATRADAR-Pipeline/ThreatRadar.git
cd ThreatRadar
```
代码库结构:
```
ThreatRadar/
├── elasticsearch/ # Main pipeline
│ ├── data_ingestion/ # Filebeat config and Python feeders
│ ├── data_normalization/ # IOC type classification and deduplication
│ ├── data_enrichment/ # MITRE, CVSS enrichment
│ ├── data_retention/ # Index lifecycle management
│ ├── scoring/ # Cortex scorer
│ ├── poisoning_detection/ # ML anomaly detection
│ │ ├── models/ # IsolationForest and scaler artifacts (.pkl)
│ │ ├── pipeline/ # Production runner
│ │ └── feedback/ # MISP feedback loop and retrainer
│ ├── kibana/ # Dashboard export and import script
│ ├── cortex/ # Cortex application config
│ ├── docker-compose.yml
│ └── Dockerfile
├── misp/ # MISP threat sharing stack
│ ├── docker-compose.yml
│ ├── Dockerfile
│ ├── misp_pusher.py
│ ├── misp_helpers.py
│ └── misp_daily_refresh.py
├── common.py # Shared index and field name constants
└── LICENSE
```
### 步骤 2:设置 Python 虚拟环境
仅在本地开发或在 Docker 外部运行脚本时需要:
```
python3 -m venv venv
source venv/bin/activate
pip install -r elasticsearch/requirements.txt
pip install -r elasticsearch/poisoning_detection/requirements.txt
pip install -r misp/requirements.txt
```
### 步骤 3:配置环境文件
```
cp elasticsearch/.env.example elasticsearch/.env
cp misp/.env.example misp/.env
```
有关完整的参考,请参见 [环境变量](#environment-variables)。
### 步骤 4:配置 Cortex
```
cp elasticsearch/cortex/application.conf.example elasticsearch/cortex/application.conf
```
有关配置详情,请参见 [Cortex 分析器](#cortex-analyzer)。
### 步骤 5:创建共享的 Docker 网络
主流水线和 MISP 栈通过一个命名的外部 Docker 网络进行通信。在启动 Compose 栈之前创建它:
```
docker network create soc-net
```
两个 `docker-compose.yml` 文件都使用 `external: true` 将此网络引用为 `soc-net`。如果没有此网络就启动栈,将导致所有容器启动失败。
### 步骤 6:启动流水线
```
cd elasticsearch
docker compose up -d
```
服务按依赖顺序启动:
| 容器 | 角色 | 端口 |
|---|---|---|
| `elasticsearch` | Elasticsearch 9.3.0 | 9200 |
| `kibana` | Kibana 9.3.0 | 5601 |
| `filebeat` | feed 传输器 | — |
| `cortex` | Cortex 分析器引擎 | 9001 |
| `pipeline` | 提取、标准化、富化 | — |
| `scorer` | Cortex IOC 评分器(7 个并行 worker) | — |
| `poisoning_detection` | IsolationForest 异常检测(每 24 小时运行一次) | — |
| `feedback_loop` | MISP 反馈和模型重新训练(每 30 分钟运行一次) | — |
### 步骤 7:导入 Kibana 仪表板
等待 Kibana 报告健康状态后,运行:
```
bash elasticsearch/kibana/import.sh
```
这将加载 `kibana/dashboards/export.ndjson`。仪表板可以在 `http://localhost:5601` 访问。
### 步骤 8:启动 MISP
```
cd misp
docker compose up -d
```
MISP 将在 `https://localhost:8443` 上可用。初始数据库设置可能需要几分钟。
## 配置说明
### 环境变量
主流水线的所有配置都位于 `elasticsearch/.env` 中。
#### Elasticsearch 与安全
```
ELASTIC_HOST=http://elasticsearch:9200
ELASTIC_USER=elastic
ELASTIC_PASSWORD=
KIBANA_SYSTEM_PASSWORD=
KIBANA_SERVICE_TOKEN=
```
#### 威胁情报 Feed 的 API 密钥
```
NVD_API_KEY=
ABUSE_API_KEY=
OTX_API_KEY=
```
#### Cortex 集成
```
PLAY_SECRET_KEY=
CORTEX_API_KEY=
CORTEX_URL=http://cortex:9001
SCORER_BATCH_SIZE=500 # IOCs processed per scoring batch
SCORER_IOC_WORKERS=4 # Concurrent workers per scorer instance
SCORER_POLL_INTERVAL=30 # Seconds between scorer polling cycles
```
#### 数据流水线范围
```
DATA_MODE=elasticsearch
ES_SOURCE_INDEX=ti_ip,ti_url,ti_domain,ti_hash,ti_cve,ti_wallet,ti_ransomware
MAX_DOCS=200000 # Maximum documents pulled per anomaly detection run
```
#### 异常检测阈值
```
CONTAMINATION_MAX=0.03 # IsolationForest contamination parameter (range: 0.0–0.5)
ML_CONTAMINATION=0.02 # Contamination used during retraining runs
REPORT_MAX_DETAIL_IOCS=250 # Maximum IOCs included in detail section of PDF reports
OUTPUT_DIR=output # Output directory for pipeline reports
```
#### OpenRouter LLM 配置
```
OPENROUTER_API_KEY=
OPENROUTER_MODEL=openai/gpt-4o-mini
OPENROUTER_FALLBACK_MODELS=openai/gpt-4o-mini,meta-llama/llama-3.1-8b-instruct,anthropic/claude-3.5-sonnet
LLM_CALL_TIMEOUT=180
LLM_MAX=500
SKIP_LLM=false
```
#### 反馈循环与重新训练
```
FEEDBACK_LOOP_SECONDS=1800 # Polling interval for MISP sightings (seconds)
FEEDBACK_RETRAIN_MIN_TOTAL_SIGNAL=200 # Minimum sightings required to trigger retraining
FEEDBACK_RETRAIN_COOLDOWN_SECONDS=21600 # Minimum seconds between consecutive retraining runs
FEEDBACK_RETRAIN_FRESH_DAYS=14 # Only use sightings from the last N days
FEEDBACK_BACKFILL_EVENT_ID=true # Backfill MISP event IDs when pushing feedback
TRAIN_MIN_DOCS=50 # Minimum documents required for a training run to proceed
TRAIN_MIN_SIGHTINGS=2 # Minimum MISP sightings required to count as a positive label
TRAIN_MAX_DOCS=20000 # Maximum training set size (older documents are dropped first)
```
#### MISP 连接
```
MISP_URL=https://misp:443/
MISP_KEY=
MISP_VERIFY_SSL=false
MISP_ENABLED=true
```
### Cortex 分析器
编辑 `elasticsearch/cortex/application.conf`:
```
# 生成强密钥: openssl rand -base64 32
play.http.secret.key = "CHANGE_ME_TO_A_STRONG_RANDOM_SECRET"
search {
index = cortex
uri = "http://elasticsearch:9200"
user = "elastic"
password = "SAME_PASSWORD_AS_IN_ENV"
}
job {
runner = [docker]
timeout = 30 minutes
}
docker {
host = "unix:///var/run/docker.sock"
autoRemove = true
}
play.http.context = "/"
```
**在 Cortex 启动后**,在 `http://localhost:9001` 的 Cortex Web UI 中完成分析器设置:
1. 创建一个组织。
2. 添加一个具有 `read, analyze` 角色的用户并生成一个 API 密钥。
3. API 密钥复制到 `elasticsearch/.env` 中的 `CORTEX_API_KEY` 中。
4. 转到 **Analyzers** 并启用以下每一个,为每个输入相应的 API 密钥:
- `VirusTotal_GetReport`
- `AbuseIPDB`
- `Maltiverse`
- `IPinfo`
- `Urlscan_Search`
- `HybridAnalysis_GetReport`
评分器通过 `elasticsearch/scoring/cortex_scorer.py` 中的 `ANALYZER_IDS` 字典将分析器名称映射到内部的 Cortex ID。如果您的 Cortex 安装分配了不同的 ID(可在 Cortex API 的 `GET /api/analyzer` 中查看),请更新该字典:
```
ANALYZER_IDS: dict[str, str] = {
"VirusTotal": "4e0c593591c2d943509e6e3ccb359d23",
"AbuseIPDB": "316d8e2f7e446ecae6cbb3e77280584f",
"Maltiverse": "1f79ad8a0af87006bb6f094a27a87561",
"IPinfo": "050365fe333a9c7c5fb0a1928bb8f25b",
"Urlscan": "3eaf513a6e1abf7bf21fe1fae5bbd503",
"HybridAnalysis": "ffc2eaee2d7c9a507e42752e81593103",
}
```
### 威胁情报 Feed
#### 内置 Feed

#### 添加自定义基于 URL 的 Feed
追加到 `elasticsearch/data_ingestion/new_feeds.py` 中的相关列表:
```
# 纯 IP blocklist
ET_FEEDS: list[dict[str, str]] = [
{
"url": "https://your-feed.example.com/ips.txt",
"name": "My Custom Feed",
"tag": "custom-blocklist",
},
]
# 带 IOC 提取的新闻/博客 RSS 源
NEWS_FEEDS: list[dict[str, str]] = [
{
"url": "https://your-blog.example.com/feed/",
"name": "MySecBlog",
"tag": "news-myblog",
},
]
```
对于结构化 feed(CSV、JSON 或基于 API),请遵循 `new_feeds.py` 中 `SSLBL_URL` 处理器的模式,该模式演示了带有 IOC 提取的 CSV 解析。
对于基于日志或 syslog 的 feed,请以现有的输入配置作为参考,配置 `elasticsearch/data_ingestion/filebeat.yml`。
### ML 投毒检测
IsolationForest 模型经过预训练并作为 `.pkl` 工件存储在 `elasticsearch/poisoning_detection/models/` 中。不要删除这些文件;如果丢失,请触发一次手动重新训练(参见 [运行 ThreatRadar](#running-threatradar))。
关键参数通过上面 [异常检测阈值](#anomaly-detection-thresholds) 中记录的环境变量进行控制。污染参数会直接影响误报率:
- `CONTAMINATION_MAX`:设置在推理时数据中预期的异常值比例。较低的值会将更少的 IOC 标记为异常。
- `ML_CONTAMINATION`:用于在 MISP 反馈基础上进行重新训练。应调整以反映您环境中观察到的实际被投毒 IOC 的比例。
### MISP 集成
编辑 `misp/.env`:
```
# Elasticsearch (与主 pipeline 共享)
ELASTIC_HOST=http://elasticsearch:9200
ELASTIC_USER=elastic
ELASTIC_PASSWORD=
# MISP API
MISP_URL=https://misp:443
MISP_KEY=
MISP_VERIFY_SSL=False
# TLP 和分发
MISP_TLP_TAG=tlp:green
MISP_CLEAN_DISTRIBUTION=1 # Distribution level for clean IOCs (0–4, per MISP schema)
MISP_CORROBORATED_DIST=1 # Distribution for corroborated IOCs
MISP_CVE_EXPLOITED_DIST=1 # Distribution for exploited CVEs
# 性能
MISP_PUSH_WORKERS=12 # Parallel push workers
MISP_PUSH_DELAY=0.05 # Delay between push requests (seconds)
MISP_SEARCH_DELAY=0.02 # Delay between search requests (seconds)
MISP_BULK_FLUSH=500 # Documents per bulk flush operation
# 初始凭据 (仅在首次启动时使用)
MISP_ADMIN_EMAIL=admin@admin.test
MISP_ADMIN_PASSPHRASE=admin #misp default configuration
BASE_URL=https://misp:443
MISP_EXTERNAL_BASEURL=https://misp:443
ADMIN_KEY=
# MySQL backend
MYSQL_ROOT_PASSWORD=
MYSQL_DATABASE=misp
MYSQL_USER=misp
MYSQL_PASSWORD=
# Redis
REDIS_PASSWORD=
```
#### 为反馈循环配置 MISP
反馈守护程序 (`feedback_daemon.py`) 使用带有 `threatradar:analyst_confirmed=true` 标签的 MISP 目击事件作为模型重新训练的正向信号。如果没有此标签,反馈循环将运行但不会积累任何训练信号。
**步骤 1 — 创建分析师确认标签**
登录到 MISP (`https://localhost:8443`),然后转到 **Event Actions → Tags → Add Tag** 并创建以下标签:
```
threatradar:analyst_confirmed=true
```
将颜色设置为醒目的颜色(例如 `#e83030`),以便在事件视图中容易发现该标签。将 taxonomy 字段留空。
**步骤 2 — 在确认 IOC 时应用标签**
当分析师审查 ThreatRadar 推送的事件并确认 IOC 是真正的真阳性时,他们必须将 `threatradar:analyst_confirmed=true` 标签应用于相关的 MISP 属性。反馈守护程序每隔 `FEEDBACK_LOOP_SECONDS` 秒(默认:1800)轮询带有此标签的属性,并将它们计入 `FEEDBACK_RETRAIN_MIN_TOTAL_SIGNAL` 阈值。
**步骤 3 — 验证 API 密钥可以看到该标签**
在 `elasticsearch/.env` 中配置的 `MISP_KEY` 必须属于一个 MISP 用户,该用户对被标记的事件至少拥有 **读取** 权限。如果未提取到目击事件,请在 MISP 管理面板中确认 API 用户的角色和组织共享组。
**步骤 4 — 检查反馈循环日志**
```
docker compose logs -f feedback_loop
```
健康的反馈循环会产生类似于以下内容的日志行:
```
[feedback] Polled MISP: 47 confirmed sightings found (threshold: 200)
[feedback] Cooldown active — next retrain eligible in 4h 12m
```
一旦越过信号阈值并且冷却期结束,将自动触发重新训练:
```
[feedback] Signal threshold reached (213 sightings). Launching retrain...
[retrain] Training complete. Model saved to poisoning_detection/models/isolation_forest.pkl
```
## 运行 ThreatRadar
### 启动完整栈
```
cd elasticsearch
docker compose up -d
```
### 监控服务
```
# 所有 services
docker compose logs -f
# 特定 service
docker compose logs -f scorer
docker compose logs -f poisoning_detection
docker compose logs -f feedback_loop
# Service 状态
docker compose ps
```
### 手动运行评分器
```
# 单批次 — 评分挂起的 IP IOC
docker exec scorer python3 /app/cortex_scorer.py --ioc-type ip --limit 100
# 连续循环模式 (生产环境)
docker exec scorer python3 /app/cortex_scorer.py --loop --ioc-type ip --workers 4 --limit 500
# 有效的 --ioc-type 值: ip, url, hash, domain, cve, ransomware, wallet
```
### 手动运行异常检测流水线
```
# 立即触发,绕过 24 小时休眠间隔
docker exec poisoning_detection python3 /app/poisoning_detection/pipeline/run_pipeline_production.py
```
### 手动运行 Feed 更新
```
docker exec pipeline python3 /app/data_ingestion/new_feeds.py
docker exec pipeline python3 /app/data_ingestion/news_ioc_feeder.py
```
### 手动运行 MISP 操作
```
# 将增强的 IOC 推送到 MISP
docker exec pipeline python3 /misp/misp_pusher.py
# 运行每日 MISP 刷新
docker exec pipeline python3 /misp/misp_daily_refresh.py
```
### 运行数据保留
```
docker exec pipeline python3 /app/data_retention/retention.py
```
## Docker 部署
### 服务图
主 `elasticsearch/docker-compose.yml` 定义了跨两个网络的 8 个服务(内部的 `elastic`,以及与 MISP 栈共享的 `soc-net`):
```
soc-net (external)
│
├── elasticsearch ←→ kibana
│ │
│ ├── filebeat
│ ├── cortex
│ ├── pipeline (ingestion, normalization, enrichment)
│ ├── scorer (7 parallel workers, one per IOC type)
│ ├── ti-pipeline (anomaly detection — every 24 h)
│ └── ti-feedback (MISP feedback loop — every 30 min)
```
### 评分器 Worker 配置
评分器启动 7 个并行进程,每种 IOC 类型一个。`docker-compose.yml` 中的默认并发值:
```
python3 /app/cortex_scorer.py --loop --workers 8 --limit 500 --ioc-type cve &
python3 /app/cortex_scorer.py --loop --workers 8 --limit 500 --ioc-type ransomware &
python3 /app/cortex_scorer.py --loop --workers 8 --limit 500 --ioc-type wallet &
python3 /app/cortex_scorer.py --loop --workers 2 --limit 30 --ioc-type ip &
python3 /app/cortex_scorer.py --loop --workers 2 --limit 30 --ioc-type url &
python3 /app/cortex_scorer.py --loop --workers 2 --limit 30 --ioc-type domain &
python3 /app/cortex_scorer.py --loop --workers 2 --limit 30 --ioc-type hash &
```
IP、URL、域名和哈希 worker 使用较低的并发性,因为相应的 Cortex 分析器(VirusTotal、AbuseIPDB)具有更严格的速率限制。请调整 `--workers` 和 `--limit` 以匹配您的分析器 API 配额。
### 在代码更改后重新构建
```
# 重建单个 service
docker compose up -d --build scorer
# 重建所有 services
docker compose up -d --build
```
### 停止栈
```
# 停止 services,保留 volumes
docker compose down
# 停止 services 并删除所有 volumes (破坏性操作 — 删除所有已索引的数据)
docker compose down -v
```
### MISP 栈
MISP 栈是独立的,只要可以通过 `soc-net` 访问,它就可以运行在单独的主机上:
```
cd misp
docker compose up -d
# UI: https://localhost:8443
```
## Kibana 仪表板
预构建的仪表板位于 `elasticsearch/kibana/dashboards/export.ndjson` 中。导入方法如下:
```
bash elasticsearch/kibana/import.sh
```
包含的仪表板:
- **流水线概览**:所有七种 IOC 类型的相对数量、数据源、流水线健康状况
- **威胁情报**:MITRE 战术热力图、平均 CVSS 评分、OWASP 分布
- **威胁攻击者情报**:最活跃的组织、关键行业受害者
- **数据评分与投毒检测**:跨 IOC 的 Cortex、ML 和 LLM 评分
- **SOC 分析师视图**:分析师确认的 IOC 总数、已推送的 IOC 总数
## 故障排除
| 症状 | 可能原因 | 解决方案 |
|---|---|---|
| Elasticsearch 立即退出 | JVM 堆内存不足 | 将 Docker 内存限制增加到至少 4 GB。在 `docker-compose.yml` 中调整 `ES_JAVA_OPTS=-Xms1g -Xmx1g`。 |
| Kibana 显示“server is not ready” | 正在等待来自 Elasticsearch 的服务令牌 | 等待 2-3 分钟。如果持续存在,运行:`docker exec elasticsearch elasticsearch-service-tokens create elastic/kibana kibana_token` |
| Cortex 返回 `401 Unauthorized` | `CORTEX_API_KEY` 不正确 | 在 Cortex UI 中的 Organizations → API Keys 下重新生成密钥。 |
| Scorer 日志显示“No pending IOCs found” | 提取流水线未运行或未产生结果 | 运行 `docker logs pipeline` 并验证索引是否存在:`curl -u elastic:$PASS http://localhost:9200/_cat/indices/ti_*?v` |
| MISP 推送失败并出现 SSL 错误 | 自签名证书 | 在 `elasticsearch/.env` 和 `misp/.env` 中设置 `MISP_VERIFY_SSL=False`。 |
| Feed 提取未返回结果 | API 密钥无效或受到速率限制 | 单独测试每个 API 密钥。NVD 需要注册密钥才能维持轮询速率。 |
| 找不到 `soc-net` 网络 | 在启动 Compose 之前未创建网络 | 运行 `docker network create soc-net`。 |
| 重新训练从未触发 | 目击信号不足 | 降低 `FEEDBACK_RETRAIN_MIN_TOTAL_SIGNAL` 或允许更多分析师目击事件在 MISP 中积累。 |
| 反馈循环发现零目击事件 | 未应用 `threatradar:analyst_confirmed=true` 标签或 API 密钥不可见 | 在 MISP 中创建标签 (Event Actions → Tags) 并确认 `MISP_KEY` 用户可以读取被标记的事件。 |
| Cortex 中出现 `docker.sock` 权限被拒绝 | Docker 套接字未挂载 | 确认 `docker-compose.yml` 中 `cortex` 服务的 volumes 下存在 `- /var/run/docker.sock:/var/run/docker.sock`。 |
| 找不到 IsolationForest 模型 | `.pkl` 文件已从 `models/` 中删除 | 触发一次手动重新训练:`docker exec poisoning_detection python3 /app/poisoning_detection/pipeline/run_pipeline_production.py` |
| 保留作业删除过于激进 | 阈值设置过低 | 增加 `elasticsearch/.env` 中的 `RETENTION_*_DAYS` 值并重启 pipeline 容器。 |
### 检查索引健康状况
```
# 列出所有 TI indices 及其文档计数和大小
curl -u elastic:${ELASTIC_PASSWORD} http://localhost:9200/_cat/indices/ti_*?v
# 统计特定 index 中的文档数
curl -u elastic:${ELASTIC_PASSWORD} "http://localhost:9200/ti_ip/_count"
# Cluster 健康状况
curl -u elastic:${ELASTIC_PASSWORD} http://localhost:9200/_cluster/health?pretty
```
## 贡献指南
欢迎贡献。有用的领域包括新的 feed 连接器、评分改进、扩展的异常特征以及文档修复。
1. Fork 此代码库并创建一个特性分支:
git checkout -b feature/my-change
2. 进行您的更改。
3. 测试您的代码。
4. 提交并推送您的分支。
5. 向 `main` 发起一个 pull request。包含对更改作用的清晰描述
## 许可证与致谢
ThreatRadar 在 [MIT 许可证](LICENSE) 下发布。
### 鸣谢
- [TheHive Project / Cortex](https://github.com/TheHive-Project/Cortex) :分析器编排引擎
- [MISP Project](https://www.misp-project.org/) :开源威胁情报共享平台
- [Elastic Stack](https://www.elastic.co/) :Elasticsearch、Kibana 和 Filebeat
- [abuse.ch](https://abuse.ch/) :SSL Blacklist 和恶意软件追踪 feed
- [AlienVault OTX](https://otx.alienvault.com/) :开放威胁交换
- [EmergingThreats](https://rules.emergingthreats.net/) :网络层威胁情报
- [OpenPhish](https://openphish.com/) :社区钓鱼 URL feed
- [CERT Polska](https://cert.pl/) :钓鱼域名阻止列表
- [Ransomware.live](https://ransomware.live/) :勒索软件受害者追踪 feed
- [Ransomwhere](https://ransomwhe.re/) :勒索软件加密货币支付追踪
- [CISA KEV](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) :已知被利用漏洞目录
- [NIST NVD](https://nvd.nist.gov/) :国家漏洞数据库
- [MITRE ATT&CK](https://attack.mitre.org/) :企业威胁技术和攻击者知识库
- [OWASP Top 10](https://owasp.org/Top10/) :Web 应用程序安全风险分类
- [scikit-learn](https://scikit-learn.org/) :IsolationForest 实现
- [OpenRouter](https://openrouter.ai/) :基于云的 LLM API 网关
标签:AI异常检测, Apex, CIDR查询, Cortex, Docker, Docker Compose, Elasticsearch, Feed Poisoning Detection, Filebeat, IOC评分, Python, TheHive, 入侵指标, 参数枚举, 可视化看板, 威胁情报, 威胁情报源, 安全运营中心, 安全防御评估, 实时处理, 开发者工具, 情报管道, 搜索引擎查询, 数据 enrichment, 无后门, 机器学习, 版权保护, 网络映射, 自动化响应, 越狱测试, 逆向工具