bcheevers123/threat-landscape
GitHub: bcheevers123/threat-landscape
一个每日自动聚合 54 个来源并加权排名的威胁情报管道,生成 HTML 与 STIX 并通过 SFTP 发布。
Stars: 0 | Forks: 0
# 网络威胁态势 — 每日简报生成器
一个 Python 管道,从公共来源收集网络威胁情报,对前 10 名威胁进行排名和增强,生成精美的 HTML 页面和 STIX 2.1 JSON 包,并通过 SFTP 部署到 WordPress 网站。
一个配套的 **ML/AI 态势** 管道单独运行,跟踪顶级的机器学习研究和 AI 行业进展。
这两个管道设计用于在 Raspberry Pi 上运行,但在 Windows 上也同样适用。WordPress 网站通过一个轻量级短代码插件渲染内容 — 不需要 WordPress REST API 依赖。
## 目录
1. [架构概述](#architecture-overview)
2. [在 Windows PC 上的设置](#setup--windows-pc)
3. [在 Raspberry Pi 上的设置](#setup--raspberry-pi)
4. [配置](#configuration)
5. [CLI 命令](#cli-commands)
6. [AI/ML 管道](#aiml-pipeline)
7. [调度](#scheduling)
8. [部署](#deployment)
9. [WordPress 插件安装](#wordpress-plugin-installation)
10. [短代码用法](#shortcode-usage)
11. [故障排除](#troubleshooting)
12. [限制与注意事项](#limitations-and-caveats)
13. [法律与伦理考量](#legal-and-ethical-considerations)
## 架构概述
```
config/
config.yaml Cyber pipeline settings (scoring weights, output dirs, SFTP)
sources.yaml Cyber source list with credibility scores
aiml/
config/
config.yaml ML/AI pipeline settings
sources.yaml ML/AI source list
output/ Generated ML/AI artefacts (gitignored)
static/
theme.css Violet/indigo theme overrides for the ML/AI page
app.js ML/AI-specific JS (badge tooltips, score panel)
templates/
index.html.j2 ML/AI Jinja2 template
src/
collectors/ RSS/Atom feed adapters + parallel collection manager
normalisers/ URL canonicalisation, title cleaning
dedupe/ URL-exact + title-similarity deduplication
scoring/ Transparent weighted scoring (6 dimensions)
enrichment/ Rule-based NER, ATT&CK mapping, extractive summarisation
stix/ STIX 2.1 bundle builder
render/ Jinja2 HTML + JSON renderer
deploy/ SFTP uploader
main.py Cyber pipeline CLI entry point
aiml_main.py ML/AI pipeline CLI entry point
templates/
index.html.j2 Cyber Jinja2 template
static/
style.css Clean, responsive CSS (shared base)
app.js Vanilla JS (expand/collapse, copy STIX, search/filter, tooltips)
output/ Generated cyber artefacts (gitignored)
index.html
latest.json
stix/.json
static/
wordpress_plugin/
barry-threat-landscape/
barry-threat-landscape.php WordPress shortcode plugin
btl-style.css Plugin-scoped stylesheet
```
### 管道阶段
1. **收集** — 并行线程获取所有启用来源的 RSS/Atom 订阅源
2. **规范化** — 规范 URL、去除 HTML 实体、确保发布时间
3. **去重** — 按 URL 分组,然后按标题相似度(rapidfuzz)分组;合并佐证报告
4. **评分** — 权重和:时效性、来源可信度、佐证、严重性、覆盖面、可行动性;领域多样性上限防止单一来源主导前 10 名
5. **增强** — 提取 CVE、国家、行业、恶意软件家族、威胁行为者、ATT&CK 技术;生成抽取式摘要
6. **STIX** — 为每个威胁构建 STIX 2.1 包(报告 + 威胁行为者 + 恶意软件 + 漏洞 + 攻击模式对象)
7. **渲染** — Jinja2 → `index.html`、`latest.json`、`stix/*.json`
8. **部署** — 通过 SFTP 上传到网络主机
## 在 Windows PC 上的设置
这是在 Raspberry Pi 闲置时的推荐设置。准备切换回 Pi 时,请改用 [在 Raspberry Pi 上的设置](#setup--raspberry-pi)。
### 先决条件
- Python 3.11 或更高版本 — 从 [python.org](https://www.python.org/downloads/) 下载
- Git(可选,用于克隆)
- Windows Terminal 或 PowerShell
### 步骤
在项目目录中打开终端(右键文件夹 → “在终端中打开”,或 `cd` 到该目录):
```
cd C:\Users\barry\PycharmProjects\ThreatLandscape
:: Create and activate a virtual environment
python -m venv venv
venv\Scripts\activate
:: Install dependencies
pip install -r requirements.txt
:: Copy and fill in environment variables
copy .env.example .env
:: Edit .env in Notepad or your editor — fill in SFTP credentials if deploying
:: Run the cyber pipeline
python -m src.main build
:: Preview the output in your browser
python -m src.main preview
:: Open http://localhost:8080
```
### Windows 上的 SFTP 密钥设置
```
:: Generate a key pair (run in Windows Terminal or PowerShell)
ssh-keygen -t ed25519 -C "pc-threat-landscape" -f "%USERPROFILE%\.ssh\threat_landscape"
:: Copy public key to your web host (replace with your actual host and user)
type "%USERPROFILE%\.ssh\threat_landscape.pub"
:: Paste the output into your web host's "Authorised Keys" via the control panel,
:: or use ssh-copy-id if your host supports it via WSL.
```
然后更新你的 `.env`:
```
SFTP_KEY_PATH=C:\Users\barry\.ssh\threat_landscape
```
### Windows 上的调度
参见下面的 [调度 — Windows 任务计划程序](#windows-task-scheduler)。
## 在 Raspberry Pi 上的设置
已在运行 Raspberry Pi OS 精简版(64 位)的 Raspberry Pi 4(2 GB RAM)上测试。
```
# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装 Python 3.11+(如果尚未安装)
sudo apt install -y python3 python3-pip python3-venv git
# 克隆仓库
git clone /home/pi/ThreatLandscape
cd /home/pi/ThreatLandscape
# 创建虚拟环境
python3 -m venv venv
source venv/bin/activate
# 安装依赖项
pip install -r requirements.txt
# 配置
cp .env.example .env
nano .env # fill in SFTP_HOST, SFTP_USER, SFTP_KEY_PATH
# 测试构建
python -m src.main build
# 测试部署(可选)
python -m src.main deploy
```
### Pi 上的 SSH 密钥设置
```
# 在 Pi 上生成密钥对
ssh-keygen -t ed25519 -C "pi-threat-landscape" -f ~/.ssh/threat_landscape
# 将公钥复制到您的网络主机
ssh-copy-id -i ~/.ssh/threat_landscape.pub user@your-webhost.example.com
# 更新 .env
SFTP_KEY_PATH=~/.ssh/threat_landscape
```
## 配置
### `config/config.yaml`(网络管道)
```
output_dir: output # where generated files are written
top_n: 10 # number of threats to output
max_items_per_source: 50 # items fetched per source feed
lookback_hours: 48 # items older than this are penalised in scoring
scoring:
recency: 0.25 # weights must sum to 1.0 (excluding diversity_cap)
source_credibility: 0.20
corroboration: 0.15
severity: 0.20
breadth: 0.10
actionability: 0.10
diversity_cap: 2 # max items from the same source domain in the top 10
enrichment:
provider: deterministic # no paid API required
max_summary_words: 80
deploy:
sftp_host: "" # or set SFTP_HOST env var
sftp_port: 22
sftp_user: "" # or set SFTP_USER env var
sftp_key_path: "" # or set SFTP_KEY_PATH env var
remote_base_path: /public_html/wp-content/uploads/barry-threat-landscape
branding:
site_name: Barry Cheevers
page_title: Cyber Threat Landscape Today
subtitle: A daily briefing on the top active cyber threats
site_url: https://barrycheevers.co.uk
```
### `aiml/config/config.yaml`(ML/AI 管道)
与网络配置的关键区别:
```
output_dir: aiml/output
static_dir: static # base CSS; aiml/static/theme.css layered on top
scoring: # ML pool — significance and credibility dominate
recency: 0.20
source_credibility: 0.28
severity: 0.25 # maps to AI/ML significance (breakthroughs, open weights…)
diversity_cap: 2
scoring_ai: # AI news pool — corroboration is the strongest signal
corroboration: 0.28
recency: 0.25
diversity_cap: 2
deploy:
remote_base_path: /public_html/wp-content/uploads/barry-aiml-landscape
```
### `config/sources.yaml`
添加、禁用或调整来源而无需更改代码:
```
sources:
- name: NCSC UK
url: https://www.ncsc.gov.uk/api/1/services/v1/report-rss-feed.xml
type: rss
credibility: 0.95
enabled: true
tags: [advisory, uk, government]
stream: technical # technical | mainstream | both
```
`credibility`(0.0–1.0)直接影响 `source_credibility` 评分维度。政府通告应得分最高;博客和新闻较低。
`stream` 控制条目进入哪个评分池:`technical`(专家视角)、`mainstream`(消费者视角,带安全关键词过滤)或 `both`(通过标题分析路由)。
### 环境变量(`.env`)
从 `.env.example` 复制并填写你的值:
| 变量 | 描述 |
|---|---|
| `SFTP_HOST` | 远程部署主机 |
| `SFTP_PORT` | SSH 端口(默认:22) |
| `SFTP_USER` | SSH 用户名 |
| `SFTP_KEY_PATH` | SSH 私钥路径 |
| `SFTP_PASSWORD` | SFTP 密码(推荐使用密钥认证) |
| `OPENAI_API_KEY` | 可选 — 用于 LLM 增强 |
| `ANTHROPIC_API_KEY` | 可选 — 用于 LLM 增强 |
环境变量优先于 `config.yaml` 中的值。
## CLI 命令
首先激活虚拟环境:
```
# Linux / macOS / Pi
source venv/bin/activate
# Windows
venv\Scripts\activate
```
### 网络威胁管道
```
# 仅收集(保存 output/raw_items.json 以供检查)
python -m src.main collect
# 完整构建:收集 → 标准化 → 去重 → 评分 → 丰富 → 渲染
python -m src.main build
# 通过 SFTP 将生成的 output/ 部署到远程主机
python -m src.main deploy
# 构建并一次性部署
python -m src.main run-all
# 本地预览服务器(打开 http://localhost:8080)
python -m src.main preview
# 启用调试日志记录
python -m src.main --verbose build
# 覆盖配置路径
python -m src.main --config path/to/config.yaml --sources path/to/sources.yaml build
```
### ML/AI 管道
```
python -m src.aiml_main build
python -m src.aiml_main deploy
python -m src.aiml_main run-all
python -m src.aiml_main preview # open http://localhost:8081
python -m src.aiml_main --verbose build
```
## AI/ML 管道
ML/AI 管道是一个并行系统,生成一个独立的页面,涵盖机器学习研究和 AI 行业新闻。它与网络管道并列运行并独立配置。
### 功能
- 从 ML/AI 特定来源收集:arXiv(cs.LG、cs.CL、cs.CV、cs.AI、cs.RO、cs.NE、stat.ML)、Google DeepMind 博客、OpenAI 博客、Anthropic、MIT Technology Review、VentureBeat、The Verge、BAIR Blog、Lilian Weng 的博客、Nature Machine Intelligence 等
- 将条目分为两个池:**ML**(研究论文、技术发布)和 **AI**(行业新闻、政策、伦理)
- 使用 AI/ML 特定评分(重要性、影响范围、适用性)而非网络威胁评分
- 为每个条目打标签:
- **主题类型** 徽章(研究、模型发布、安全、监管等)
- **ML 技术** 徽章(LLM、扩散模型、强化学习、计算机视觉等)
- 应用领域多样性上限,防止 arXiv 填满整个 ML 前 10 名
- 部署到独立远程路径(`barry-aiml-landscape`)
### 输出
```
aiml/output/
index.html Standalone ML/AI landscape page
latest.json ML/AI data for a WordPress shortcode (if desired)
stix/ STIX bundles (minimal — ML items rarely map to full STIX objects)
static/ Copied assets including violet/indigo theme
```
### 同时运行两个管道
```
# 按顺序构建并部署两者
python -m src.main run-all && python -m src.aiml_main run-all
```
## 调度
### Windows 任务计划程序
1. 打开 **任务计划程序**(在开始菜单中搜索)
2. 点击 **创建基本任务**
3. 命名为 `Threat Landscape Pipeline`
4. 设置触发器:**每日**,开始时间 `07:00`
5. 操作:**启动程序**
- 程序:`C:\Users\barry\PycharmProjects\ThreatLandscape\venv\Scripts\python.exe`
- 参数:`-m src.main run-all`
- 起始位置:`C:\Users\barry\PycharmProjects\ThreatLandscape`
6. 完成,右键任务 → **属性** → **常规** 选项卡 → 勾选 **无论用户是否登录都运行**
要为 ML/AI 管道创建第二个任务,使用 `-m src.aiml_main run-all`,或创建一个包装批处理文件:
```
:: run_all.bat — save in the project root
@echo off
cd /d C:\Users\barry\PycharmProjects\ThreatLandscape
call venv\Scripts\activate
python -m src.main run-all
python -m src.aiml_main run-all
```
将任务计划程序的操作指向 `run_all.bat` 以通过一个计划任务同时运行两者。
### cron(Raspberry Pi)
在伦敦时间 07:00 运行。`TZ` 变量会自动处理 GMT/BST 切换:
```
# 编辑方式:crontab -e
0 7 * * * TZ=Europe/London /home/pi/ThreatLandscape/venv/bin/python -m src.main run-all >> /home/pi/ThreatLandscape/logs/pipeline.log 2>&1
5 7 * * * TZ=Europe/London /home/pi/ThreatLandscape/venv/bin/python -m src.aiml_main run-all >> /home/pi/ThreatLandscape/logs/aiml_pipeline.log 2>&1
```
首先创建日志目录:
```
mkdir -p /home/pi/ThreatLandscape/logs
```
### systemd 定时器(Raspberry Pi 替代方案)
创建 `/etc/systemd/system/threat-landscape.service`:
```
[Unit]
Description=Cyber Threat Landscape Pipeline
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=pi
WorkingDirectory=/home/pi/ThreatLandscape
Environment=TZ=Europe/London
ExecStart=/home/pi/ThreatLandscape/venv/bin/python -m src.main run-all
StandardOutput=append:/home/pi/ThreatLandscape/logs/pipeline.log
StandardError=append:/home/pi/ThreatLandscape/logs/pipeline.log
```
创建 `/etc/systemd/system/threat-landscape.timer`:
```
[Unit]
Description=Run Threat Landscape Pipeline daily at 07:00 London time
[Timer]
OnCalendar=07:00
TimeZone=Europe/London
Persistent=true
[Install]
WantedBy=timers.target
```
启用:
```
sudo systemctl daemon-reload
sudo systemctl enable --now threat-landscape.timer
sudo systemctl status threat-landscape.timer
```
## 部署
部署步骤通过 SFTP 将以下文件上传到你的网络主机:
### 网络管道
```
/public_html/wp-content/uploads/barry-threat-landscape/
latest.json (read by the WordPress plugin)
index.html (standalone page)
stix/.json (one per threat)
static/style.css
static/app.js
```
可访问地址:
.json
static/style.css
static/app.js
static/theme.css
```
### 试运行 / 测试
运行 `build` 而不执行 `deploy`,以在本地生成文件并通过 `preview` 检查,然后再上传任何内容。
### 首次远程目录设置
某些共享主机不允许通过 SFTP 自动创建目录。如果部署因“找不到文件”错误而失败,请先通过主机文件管理器或 cPanel 手动创建远程目录:
```
wp-content/uploads/barry-threat-landscape/
wp-content/uploads/barry-aiml-landscape/
```
## WordPress 插件安装
该插件用于渲染 **网络威胁** 数据。也可以将第二个短代码连接到 ML/AI 的 `latest.json`(可选)。
### 手动安装
1. 通过 SFTP 或服务器文件管理器将插件文件夹复制到你的 WordPress 安装目录:
```
wordpress_plugin/barry-threat-landscape/ → wp-content/plugins/barry-threat-landscape/
```
2. 登录 WordPress 管理后台。
3. 导航到 **插件 → 已安装插件**。
4. 找到 **Barry Threat Landscape** 并点击 **激活**。
5. 导航到 **设置 → 威胁景观**。
6. 配置 JSON 源:
- **留空** 使用默认路径 `wp-content/uploads/barry-threat-landscape/latest.json`(通过 SFTP 部署到此位置时推荐)
- 或输入完整 HTTPS URL:`https://yoursite.com/wp-content/uploads/barry-threat-landscape/latest.json`
### 压缩包安装
```
cd wordpress_plugin
zip -r barry-threat-landscape.zip barry-threat-landscape/
```
在 Windows 上:
```
cd wordpress_plugin
powershell Compress-Archive barry-threat-landscape barry-threat-landscape.zip
```
然后通过 **插件 → 新增 → 上传插件** 上传。
## 短代码用法
在 WordPress 页面或文章中添加以下短代码:
```
[barry_threat_landscape]
```
可选属性以覆盖标题:
```
[barry_threat_landscape title="Today's Top 10 Cyber Threats"]
```
该插件会:
- 从配置的源获取 `latest.json`(本地文件或 HTTPS URL)
- 使用 WordPress 瞬态缓存结果(默认 TTL:1 小时)
- 内联渲染威胁卡片
- 如果文件不可用,则友好地显示错误信息
- 在“设置 → 威胁景观”中提供 **立即刷新缓存** 按钮
## 运行测试
```
# 首先激活虚拟环境
pip install -r requirements.txt
pytest
# 启用覆盖率
pytest --cov=src --cov-report=term-missing
```
## 故障排除
### 未收集到任何条目
- 检查网络连接:`curl -I https://feeds.feedburner.com/TheHackersNews`
- 在 Windows 上:`Invoke-WebRequest -Uri https://feeds.feedburner.com/TheHackersNews -Method Head`
- 某些订阅源可能暂时不可用 — 管道会优雅降级
- 使用 `--verbose` 运行以获取每个来源的调试输出:`python -m src.main --verbose collect`
### SFTP 部署失败
- 手动测试 SSH 连接:`ssh -i path/to/key user@host`
- 检查 `remote_base_path` 在服务器上是否存在且可写
- 部署程序会尝试创建远程目录树;如果主机限制此操作,请先通过 cPanel 或主机文件管理器手动创建目录
- 在 Windows 上,确保 `SFTP_KEY_PATH` 中的路径使用正确的分隔符(`C:\Users\barry\.ssh\key` 或等效正斜杠)
### WordPress 插件显示“文件未找到”
- 确认 `latest.json` 已成功部署到远程路径
- 检查 `wp-content/uploads/` 是否可被 Web 服务器读取(通常权限为 `755`)
- 使用 **设置 → 威胁景观 → 立即刷新缓存** 强制重新获取
- 如果使用 URL 源,请验证 URL 是否为 HTTPS — 插件会拒绝纯 HTTP 以保障安全
### 威胁页面为空或稀疏
- 管道发布其收集到的内容;如果来源不可用,显示的威胁可能少于 10 个
- 运行 `collect` 后检查 `output/raw_items.json` 查看收集到了什么
- 如果条目较少,增加 `config.yaml` 中的 `lookback_hours`
### 启动时评分权重错误
- `config.yaml` 中的 `diversity_cap` 键不是评分权重,应单独处理 — 不要将其包含在自定义评分块中
- `scoring:` 下的权重值总和必须为 1.0(不包括 `diversity_cap`)
### ML/AI 管道产生结果很少
- arXiv 订阅源内容丰富但可能会偶尔限制爬虫 — 如果收集结果很少,稍等几分钟后重试
- `_is_ml_article()` 过滤器会移除离题技术文章;如果合法文章被丢弃,请查看 `src.aiml_main collect` 的 `--verbose` 输出
### 虚拟环境未找到(Windows)
```
:: If venv\Scripts\activate gives a permissions error in PowerShell:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
```
## 从 Windows PC 迁移到 Raspberry Pi
准备将管道移回 Pi 时:
1. 确保 Pi 运行 Raspberry Pi OS 且 Python 3.11+
2. 将项目复制或克隆到 `/home/pi/ThreatLandscape`
3. 遵循 [在 Raspberry Pi 上的设置](#setup--raspberry-pi)
4. 将 `.env` 文件复制到 Pi(不要提交到 git)
5. 将 SSH 私钥复制到 Pi 的 `~/.ssh/` 并更新 `.env` 中的 `SFTP_KEY_PATH`
6. 运行 `python -m src.main build` 验证构建是否正常
7. 设置 cron 或 systemd 调度
8. 禁用 Windows 任务计划程序任务
项目目录结构和所有配置文件在平台间保持一致 — 仅激活命令和调度器不同。
## 限制与注意事项
- **增强准确性**:ATT&CK 映射、归因、国家和行业提取均基于规则关键词匹配。会产生误报并遗漏细微差别。将所有分析字段视为最佳努力信号,而非事实依据。
- **无实时数据**:页面反映上次管道运行时的公共订阅源状态,不是实时订阅。
- **来源可用性**:订阅源 URL 可能变更;如果来源静默,请检查其 URL 并更新 `sources.yaml`
- **无全文提取**:管道使用 RSS 订阅摘要作为主要文本来源。默认不获取全文文章(这会更慢、更重,且更可能违反发布者条款)。如果需要,`trafilatura` 依赖项可用于扩展 `RSSCollector` 以获取全文。
- **STIX 包不完整**:当证据稀疏时,STIX 包仅包含报告对象。这在 STIX 2.1 中是明确允许的。
- **ML/AI 评分是近似值**:ML/AI 项目的“严重性”、“覆盖面”和“可行动性”维度使用关键词启发式方法,而非语义理解。恰好提到“医疗保健”的论文即使并非主要应用,也会因覆盖面而获得更高评分。
- **性能**:在 Raspberry Pi 4 上,从 40 多个来源收集大约需要 60–90 秒。在现代 PC 上速度显著更快。构建步骤在两者上都很快。
## 法律与伦理考量
- **来源服务条款**:请查阅 `sources.yaml` 中每个订阅源的条款。大多数允许非商业个人使用的自动化访问,但你有责任核实这一点。
- **归因**:始终链接回原始文章。生成的页面为每个条目提供原始 URL。
- **默认不抓取**:管道仅使用官方 RSS/Atom 订阅源,不抓取网页内容。
- **不捏造事实**:系统明确设计为不捏造事实。不确定字段使用“未知”/“未确认”标签。绝不将输出作为权威情报的替代品。
- **个人数据**:此管道不收集或处理任何个人数据。
- **GDPR / 数据保护**:生成的页面完全来源于公共来源,不存储或传输任何个人数据。
标签:AI趋势, Apex, GitHub Pages, HTML生成, Python, Raspberry Pi, RSS采集, SEO, SFTP部署, STIX 2.1, URL规范化, Windows兼容, WordPress, 信誉评分, 公开源, 内存执行, 去重, 威胁情报, 定时任务, 并行采集, 开发者工具, 恶意代码分析, 文件完整性监控, 无REST API, 无后门, 机器学习, 权重配置, 每日简报, 短代码插件, 网络威胁, 自动化管道, 逆向工具, 配置文件