thunderstornX/dark-web-monitor-lite
GitHub: thunderstornX/dark-web-monitor-lite
dark-web-monitor-lite 是一款防御性 CTI 工具,用于监控公开可索引的 onion 服务并基于关键字监控列表进行模糊匹配,通过 webhook 发送告警。
Stars: 0 | Forks: 0
```
██████╗ ██╗ ██╗███╗ ███╗
██╔══██╗██║ ██║████╗ ████║ dark-web-monitor-lite
██║ ██║██║ █╗ ██║██╔████╔██║
██║ ██║██║███╗██║██║╚██╔╝██║ ─── defensive CTI · Tor-aware ───
██████╔╝╚███╔███╔╝██║ ╚═╝ ██║
╚═════╝ ╚══╝╚══╝ ╚═╝ ╚═╝
```
[](https://github.com/thunderstornX/dark-web-monitor-lite/actions/workflows/tests.yml)
[](results/security_scan.md)
[](results/security_scan.md)
[](results/security_scan.md)
[](results/README.md)
[](https://doi.org/10.5281/zenodo.20480454)
[](LICENSE)
`dark-web-monitor-lite` 是一款防御性的网络威胁情报
工具,用于监控公开可索引的 onion 服务 URL,匹配组织设定的关键字监控列表,
并通过 Slack、Discord 或通用 HTTP webhook 发送
警报。
该工具专门针对 Tor 进行了适配:它通过 `httpx-socks` 将 `.onion` 的请求路由至
SOCKS5 代理,并使用标准库的 socket 检查来探测 SOCKS 的连通性。当无法连接到 SOCKS 代理时,它会进行优雅降级:每一个
获取器都会返回一个类型化的 `FetchResult`,以便操作员可以直接在报告中
看到覆盖缺失。
**匹配引擎**是唯一被评估的组件。实时 onion
获取、webhook 发送和 Tor 链路健康状态仅通过
mock 进行测试——这种刻意的设计确保了评估能够在离线状态下
重现。
## 快速开始
```
git clone https://github.com/thunderstornX/dark-web-monitor-lite.git
cd dark-web-monitor-lite
python -m venv .venv
.venv/bin/pip install -r requirements.txt
# 验证 config 而不进行任何网络调用:
.venv/bin/python -m cli.main dry-run \
--watchlist config/watchlist.yaml \
--sources config/sources.yaml
# 运行扫描(对于 clearnet 源不需要 Tor;onion 源
# 如果没有运行 Tor 代理,将报告 TOR_UNAVAILABLE):
.venv/bin/python -m cli.main scan \
--watchlist config/watchlist.yaml \
--sources config/sources.yaml \
--output out/scan.json
# 生成一个您可以粘贴到自己的 scheduler 中的 crontab 行:
.venv/bin/python -m cli.main render-cron \
--watchlist config/watchlist.yaml \
--sources config/sources.yaml \
--output /var/log/dwm/scan.json \
--log /var/log/dwm/scan.log
```
## 架构
```
┌─────────────────────┐
│ YAML watchlist │ brands / codenames / iocs
│ (FICTIONAL default) │ + mandatory _disallowed_categories
└─────────────────────┘
│
┌─────────────────────┐
│ YAML sources │ public-directory placeholders;
│ (pre-flight checks) │ requires_auth = false enforced
└─────────────────────┘
│
┌─────────────────────┐
│ Tor SOCKS probe │ 2-second TCP-connect probe;
│ (graceful fallback) │ failure → TOR_UNAVAILABLE
└─────────────────────┘
│
┌─────────────────────┐ ──► JSON report
│ matcher + fetcher │
│ (the measured part) │ ──► Slack / Discord / generic
└─────────────────────┘ webhooks (all optional)
```
每次获取都会返回一个类型化的 `FetchResult`,状态为以下之一:
| 状态 | 含义 |
|---------------------|--------------------------------------------------|
| `ok` | 已获取并运行了匹配器 |
| `http_error` | 上游响应 4xx/5xx |
| `network_error` | DNS/连接/传输失败 |
| `tor_unavailable` | onion URL + Tor SOCKS 代理无法访问 |
| `timeout` | 超过 `fetch_timeout_s` |
| `skipped_policy` | 源未通过预检查策略 |
## 匹配引擎
针对每个关键字的两阶段匹配:
1. **精确匹配** —— 不区分大小写的子字符串扫描。得分始终为
`100.0`。
2. **模糊匹配**(可选,使用 `--no-fuzzy` 禁用)—— 仅在
精确匹配阶段未捕获到关键字时运行。
模糊评分器使用两种策略:
* **多词关键字**:滑动窗口扫描,其中每个关键字
token 必须在正文原子中具有近似等价项;该窗口的得分
是每个 token 最佳 `fuzz.ratio` 得分的**最小值**。使用
`min`(而不是 `max`)进行聚合,可以避免
更简单的 rapidfuzz 配置容易陷入的部分子字符串陷阱(例如,`Project
Aurora` 错误匹配到 `Aurora Borealis`)。
* **单词关键字**:对每个正文原子执行 `fuzz.ratio`,并且
对无分隔符连接的相邻原子对执行 `fuzz.ratio` —— 这可以
捕获类似 `AcmeCorp` 这样的 CamelCase 条目(其正文形式是
以空格分隔的 `Acme Corp`)。少于 5 个字符的 token 绝不会
进行模糊匹配。
## 重现评估
```
.venv/bin/python eval/run_eval.py
```
55 个标记样本 × 10 个监控列表关键字 = 550 个 (样本, 关键字)
单元。测量了两种配置。
**最新测量数据** (2026-05-12):
| 模式 | TP | FP | FN | TN | 精确率 (Precision) | 召回率 (Recall) | F1 | 准确率 (Accuracy) |
|--------------|---:|---:|---:|----:|----------:|-------:|-------:|---------:|
| 仅精确匹配 | 29 | 1 | 13 | 507 | 0.9667 | 0.6905 | 0.8056 | 0.9745 |
| **开启模糊匹配** | 41 | 6 | 1 | 502 | **0.8723** | **0.9762** | **0.9213** | **0.9873** |
开启模糊匹配以 9.4 个百分点的精确率换取了 28.6 个百分点的召回率;F1
0.806 → **0.921**。请参阅 [results/README.md](results/README.md) 了解
逐单元的残差分析(7 个单元;均合理 —— 正文
否定、复数变体、边缘 URL tokenization)。
## 测试
```
.venv/bin/pytest -q
```
涵盖匹配器、Tor 探测器、获取器、
警报器、调度器、跨模块 dataclass 以及
评估工具辅助函数的 59 项测试。HTTP 请求使用
[`respx`](https://lundberg.github.io/respx/) 进行 mock;CI 环境中不包含实时 Tor 和
实时 webhook。
| 模块 | 测试 |
|-------------------------|------:|
| `matcher.py` | 22 |
| `alerter.py` | 10 |
| `fetcher.py` | 7 |
| `tor_client.py` | 6 |
| `eval/run_eval.py` | 6 |
| `findings.py` | 5 |
| `scheduler.py` | 3 |
| **总计** | **59**|
## 安全状况
| 门禁 | 发现数 | 抑制数 |
|-----------:|:--------:|:------------:|
| Bandit | 0 | 0 |
| pip-audit | 0 | 0 |
| Semgrep | 0 | 0 |
详见 [results/security_scan.md](results/security_scan.md)。
## 合规基准
该仓库提供了三份文档,旨在直接引入
部署者的策略库中:
* **[ETHICAL_USE.md](ETHICAL_USE.md)** —— 仓库中最重要的文件
。
* **[compliance/POLICY_TEMPLATE.md](compliance/POLICY_TEMPLATE.md)** ——
组织部署策略模板,涵盖授权、
监控列表治理、源列表治理、操作护栏、
事件处理、数据保留、审计和退出机制。
* **[compliance/LEGAL_REVIEW.md](compliance/LEGAL_REVIEW.md)** ——
一份涵盖四个司法管辖区(美国、英国、
欧盟、巴基斯坦)关于限制被动监控的法规摘要。**这不构成法律建议。** 其目的是
引出正式法律审查必须回答的问题。
## 本工具*不*做的事情
* 它**不会**在非法服务上创建账户。
* 它**不会**购买、试图购买或招揽非法
商品、服务或数据。
* 它**不会**抓取付费、数据泄露掮客或非公开可索引的
服务。ETHICAL_USE.md 严格定义了“公开可访问”:
由公开的 Tor 搜索引擎索引,无需账户、无需
付费、无需邀请、无需特定用户授权。
* 它**不会**保留捕获的内容。正文内容默认会被计算哈希以进行去重并被丢弃。
* 它**不会**针对个人。
## 引用
如果您在学术工作中使用了本软件,请引用
[CITATION.cff](CITATION.cff) 记录。配套的
[IEEE 论文](paper/paper.tex) 描述了其设计并报告了
实际测量结果。
## 许可证
MIT。请参阅 [LICENSE](LICENSE)。该许可证约束代码的使用;
[ETHICAL_USE.md](ETHICAL_USE.md) 约束代码的用途。
标签:Python, Tor网络, 威胁情报, 安全规则引擎, 实时处理, 开发者工具, 无后门, 暗网监控, 模糊匹配, 网络安全, 逆向工具, 隐私保护