tor-fetch — Darknet Collection Pipeline
I blazed the trail. Here's the tool. Your results are your own.
Snapshot-based batch collector for .onion and clearnet data via Tor + Kali WSL. Self-growing seed pool, auto-discovery, OSINT toolchain. Domain-agnostic.
目录
快速开始
# 链路自检(每次重启后跑一次)
wsl -d <distro> -- tor-fetch
# 采集
cd <project_root>
python -m crawler snapshot run
如果 tor-fetch 提示 Tor 没启动:
Start-Process -FilePath "<tor-path>\tor.exe" -ArgumentList "-f <torrc-path>" -WindowStyle Hidden
安装
1. Tor 配置
Tor 必须监听 0.0.0.0:9050 才能被 WSL2 访问。torrc:
SOCKSPort 127.0.0.1:9050
SOCKSPort 0.0.0.0:9050
SOCKSPolicy accept 127.0.0.1
SOCKSPolicy accept <wsl-subnet>/16
SOCKSPolicy reject *
这样 WSL 网关 IP 变化时不需要改 Tor 配置。
2. tor-fetch 链路自检脚本
将 tor-fetch.sh 装进 Kali WSL(仅首次):
wsl -d <distro> -- sudo cp <path>/tor-fetch.sh /usr/local/bin/tor-fetch
wsl -d <distro> -- sudo chmod +x /usr/local/bin/tor-fetch
自动完成:检测 WSL 网关 IP → 更新 proxychains4.conf → 测试 Tor 链路 → 探测 .onion DNS。
3. Python 配置
pip install aiohttp aiohttp_socks
cp config_template.py config.py # 填入你的路径和种子 URL
配置模板见 config_template.py。
架构
Windows 宿主机 WSL2 Kali
┌────────────────────┐ ┌──────────────────────┐
│ Tor (tor.exe) │◄──────────│ proxychains4 │
│ 监听 0.0.0.0:9050 │ socks5 │ ← tor-fetch 自动修 IP │
│ upstream proxy │ └──────────────────────┘
│ obfs4 bridges │
└────────────────────┘
▲
│ socks5://127.0.0.1:9050
┌──────────┴──────────────┐
│ Python collector │
│ (aiohttp + aiohttp_socks)│
└─────────────────────────┘
- Tor 监听
0.0.0.0:9050:WSL 网关 IP 变化不影响 - Python collector 直连
socks5://127.0.0.1:9050(不依赖 WSL) - Kali WSL 仅跑 prescreen(快速 TCP 存活探测);guard clause 在 WSL 不可用时自动回退到 Windows 直连 Tor
- Tor 可选链路上游 SOCKS5 代理 + obfs4 网桥
Snapshot Phase 流程
每次 python -m crawler snapshot run 按序执行:
| # | Phase | 说明 | |---|-------|------| | 1 | 侦察 | 加载 SEED_ONIONS + SEED_CLEARNET + discovered_seeds.json,去重,截断至 BATCH_SIZE | | 2 | 启动 Tor | 检查 9050 端口,未运行则启动 TorPool(3 实例) | | 2.3 | DDG 发现 | 搜索 DDG onion HTML,解码 uddg 链接,新种子写入种子池 | | 2.5 | Prescreen | WSL curl 快速 HEAD 检查 onion 存活,全挂则跳过走直连 | | 3 | 采集 | aiohttp 并发抓取,3 并发,60s 超时,重试+指数回退 | | 3.5 | Onion 发现 | 从采集 HTML 中提取新 .onion 链接,写入种子池 | | 4 | 停止 Tor | 关闭 Tor 实例 | | 5 | 归档 | 写入 snapshot manifest + 金融信号 JSON |
所有 Phase 使用 graceful degradation——单 Phase 失败不中断管线,自动降级继续。
种子管理
三种种子源,每次 snapshot 自动合并:
| 种子源 | 文件 | 类型 |
|--------|------|------|
| SEED_ONIONS | config.py | 手工维护的核心 onion 站点 |
| SEED_CLEARNET | config.py | 手工维护的 clearnet 站点 |
| discovered_seeds.json | data/ | 自动发现积累的种子池 |
种子池自动增长:
- Phase 2.3:DDG onion 搜索关键词 → 解码 uddg 链接 → 发现 clearnet 站点
- Phase 3.5:从已采集 HTML 中提取
.onion链接
验证过的起始种子
SEED_ONIONS = [
# DDG — Phase 2.3 的主力搜索引擎
"https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion",
# Ahmia — .onion 搜索引擎
"http://juhanurmihxlp77nkq76byazcldy2hlmovfu2epvl5ankdibsot4csyd.onion",
]
搜索引擎是通用的——换成你的关键词就能切到任何领域。
DDG_SEARCH_KEYWORDS和SEED_CLEARNET配置你的目标领域即可。
DDG 种子发现
通过 DuckDuckGo onion 的 HTML 版(无 JS)搜索关键词,解码 uddg 重定向链接。
config.py:
DDG_ONION_SEARCH = "https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/html/?q={}"
DDG_SEARCH_KEYWORDS = [
"oil price trading",
"crude oil news today",
"commodity market analysis",
"WTI brent spread",
"energy market report",
"oil supply demand",
]
SeedExplorer(crawler/seed_discovery.py)链路:搜索 → 正则 uddg → URL decode → 过滤无关域名 → 去重 → 写入种子池。
配置
从 config_template.py 复制为 config.py。关键参数:
| 参数 | 默认 | 说明 |
|------|------|------|
| TOR_EXE | <path> | Tor 可执行文件路径 |
| SNAPSHOT_BATCH_SIZE | 30 | 单次采集上限 |
| SNAPSHOT_CONCURRENT | 3 | 并发抓取数 |
| SNAPSHOT_TIMEOUT | 60 | 单站超时(秒) |
| USE_BRIDGES | False | 启用 obfs4 网桥 |
输出示例
Snapshot Manifest(data/snapshots/{id}.json)
{
"snapshot_id": "62e4ddc4dce3",
"started_at": 1751702837.0,
"ended_at": 1751702871.0,
"transport": "tor",
"targets_total": 30,
"targets_onion": 10,
"targets_clearnet": 20,
"fetched": 21,
"failed": 9,
"skipped": 0,
"bytes_total": 4895230,
"seeds_discovered": 3
}
金融信号(data/snapshots/{id}_signals.json)
{
"snapshot_id": "62e4ddc4dce3",
"signal_count": 16,
"signals": [
{
"severity": 5,
"category": "commodity_market",
"tickers": ["BRENT", "BZ", "USD", "WTI"],
"summary": "Brent crude rose to $72.10/bbl, up 0.42% from previous session"
},
{
"severity": 5,
"category": "geopolitical_flash",
"tickers": ["NG", "WTI"],
"summary": "Energy infrastructure disruption flagged across producer region"
},
{
"severity": 3,
"category": "commodity_market",
"tickers": ["CNY", "DXY", "USD"],
"summary": "Currency correlation signal detected — USD strength pressuring commodities"
}
]
}
信号字段:severity(1-5,越高越强)、category(commodity_market / geopolitical_flash / general)、tickers(影响的品种代码)、summary(信号摘要)。
OSINT 工具(Kali WSL)
全部通过 proxychains4 走 Tor:
wsl -d <distro> -- proxychains4 <tool> <args>
| 工具 | 用途 | 安装 |
|------|------|------|
| theHarvester | 邮箱/域名/子域枚举 | apt install theHarvester |
| Recon-ng | Web 侦察框架 | apt install recon-ng |
| amass | 子域名发现与映射 | apt install amass |
| exiftool | 文件元数据提取 | apt install exiftool |
| sherlock | 用户名跨站搜索 | apt install sherlock |
| metagoofil | 公开文档元数据 | apt install metagoofil |
排障
| 症状 | 原因 | 解决 |
|------|------|------|
| tor-fetch Tor 不可达 | Tor 进程未启动(SOCKS 端口无响应) | 运行 PowerShell 启动命令,等 15s 电路建立后重试 |
| tor-fetch onion 返回 000 | Tor 电路正在协商(通常 <30s) | Tor 启动后有个启动窗口,等待 30s 再试 |
| proxychains4 超时 | Tor 上游代理不通,或网桥被阻断 | 检查上游代理(Clash/V2Ray)是否运行;换网桥 |
| Snapshot 中 Tor 超时 | obfs4 网桥 IP 被墙或端口被封 | 等待 2 分钟让电路重建,或换 obfs4 网桥地址 |
| Prescreen 全挂 | WSL 未启动或被安全策略禁用 | guard clause 自动跳过,回退 Windows 直连 Tor |
| DDG 搜索无结果 | Tor 电路出口被 DDG 限流 | 等几分钟下一轮 snapshot 自动重试 |
| 采集结果为空 | 目标站点是 SPA/JS 渲染页面 | 当前版本不支持 headless 渲染,换非 JS 站点 |
| 种子池不增长 | 关键词覆盖不足或 DDG 出口 IP 被限 | 扩展 DDG_SEARCH_KEYWORDS,换一批关键词 |
Scan to join WeChat group