rithinkrishnakv/jobless-router

GitHub: rithinkrishnakv/jobless-router

实时 BGP 零信任威胁情报引擎,监听全球路由数据流,通过 RPKI 验证、意图评分和基线偏差检测识别路由劫持与泄露。

Stars: 0 | Forks: 0

Jobless-Router — BGP zero-trust threat-intel engine
[![tests](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/a266f92980190445.svg)](https://github.com/rithinkrishnakv/jobless-router/actions/workflows/tests.yml) [![License: MIT](https://img.shields.io/badge/license-MIT-2bdca0?style=flat-square)](LICENSE) [![Python](https://img.shields.io/badge/python-3.9%2B-22d3ee?style=flat-square)](https://www.python.org/) [![Source](https://img.shields.io/badge/source-RIPE%20RIS%20Live-2bdca0?style=flat-square)](https://ris-live.ripe.net/) [![Mitigation](https://img.shields.io/badge/mitigation-advisory%20only-ff9f5a?style=flat-square)](#advisory-mitigation-playbook) [![Type](https://img.shields.io/badge/type-BGP%20intel-1c2b27?style=flat-square)](#what-it-actually-does)
一个实时的 BGP 零信任威胁情报引擎。它监听全球 路由数据流,针对实时 RPKI 对路由公告进行密码学验证, 并**评估意图** —— 是无意的错误配置、蓄意的路由泄露, 还是针对性的拦截企图 —— 而不仅仅是标记为“RPKI invalid” 就停止。 ## 它的实际作用 1. **AS-path 遍历** —— 指出确切的“共谋”上游传输 提供商,这些提供商从其源端接收了错误路由并在 未经过滤的情况下继续传播。 2. **意图启发式** —— 两个独立的 0-100 分评分: - *Fat-finger*(误操作):宽泛且过度碎片化的 prefix,RPKI `INVALID_LENGTH`。 - *针对性 MITM*:高度具体的 prefix,命中受监视的关键服务, 与合法持有者没有任何业务关系,破坏了 [valley-free routing](https://en.wikipedia.org/wiki/Valley-free_routing) (Gao-Rexford 属性,RFC 7908 依赖它来定义路由泄露),或者 伴随 AS-path 投毒。 3. **BGP community 解码** —— 标记 RFC 1997/7999 知名 community, 包括 blackhole (RTBH) community,这样由运营商有意发布的 缓解路由就不会被错误分类为劫持。 4. **AS-path 投毒检测** —— 区分良性的自我前缀追加 (流量工程)和植入路径中间的非源 ASN,以绕过 特定网络自身的环路预防机制。 5. **基线偏差检测** —— 学习哪些源 ASN 和上游 之前合法地宣告过每个 prefix,从而即使在没有 RPKI ROA 可以通过密码学验证判定为无效时,也能捕捉到泄露。 (RPKI ROA 的覆盖率仍然远不及路由表的一半 —— 沉默 并不代表无辜。) 6. **影响范围估算** —— 计算有多少个不同的、地理分布广泛的 RIPE RIS 路由收集器看到了相同的错误路由,作为一个可靠的、 可衡量的传播样本(PeeringDB 描述的是对等关系, 而不是实时的 RIB 状态,因此它实际上无法回答“互联网中有多大比例 接受了这个路由” —— 而这可以做到)。 7. **惯犯跟踪** —— 一个小型的 sqlite 账本,记录每个 ASN 累计的 不良路由时间,而不仅仅是事件计数。 8. **Certificate Transparency 交叉检查** —— 可选地轮询 `crt.sh` 以查找在事件窗口附近颁发的可疑证书,这是一种跨层信号, 可以区分“路由泄露”和“有人试图进行 MITM TLS。” 9. **建议缓解手册** —— 生成 RTBH 文本、一条 BGP Flowspec (RFC 8955)规则,以及 Cisco/Juniper/Arista 的 ACL 配置供人工 审查。它刻意绝不开启实时的 BGP 会话或自动推送配置 —— 在*自动化*缓解中出现误报,导致合法流量被黑洞的速度 可能比劫持本身还要快。 10. **运行鲁棒性** —— 将 websocket 接收器和 评分 pipeline 作为独立的、通过队列连接的生产者/消费者任务运行, 因此缓慢的处理(RPKI 查询等)绝不会延迟 socket 的排空 —— 这很可能是早期测试中观察到 ping-timeout 断开连接的原因之一。在瞬时断开时通过退避机制自动重新连接 而不是直接崩溃,可选地通过 SOCKS5 代理(`--proxy socks5://host:port`);将 RPKI 查询缓存几分钟, 这样重复看到相同的路由就不会频繁请求 RIPEstat;`--debug` 显示每个事件的评分,无论是否被标记,因此 沉默是可验证的,而不仅仅是被盲目信任的。 ## 快速开始 ``` git clone https://github.com/rithinkrishnakv/jobless-router.git cd jobless-router pip install -r requirements.txt # 离线演示 —— 六个脚本化场景,零网络依赖: python run.py --replay sample_events.jsonl # 对检测逻辑本身进行健全性检查: python tests/test_demo.py # 真实场景 —— 连接到 RIPE RIS Live 的公共 websocket firehose, # 无需 API key。需要正常的出站互联网访问。 python run.py --live # 缩小范围到一个 prefix 或一个 collector,而不是完整的全局 firehose, # 和/或查看每个事件的 score,即使它没有被标记: python run.py --live --prefix 1.1.1.0/24 python run.py --live --host rrc00 --debug # 捕获从受监控的 block 中划分出的 sub-prefix(真实的 hijack 模式): python run.py --live --prefix 1.0.0.0/8 --more-specific # 通过 SOCKS5 代理,并为不稳定网络设置更宽松的 keepalive 容差: python run.py --live --host rrc00 --proxy socks5://127.0.0.1:1080 --ping-timeout 30 ``` ## 内置演示 (`sample_events.jsonl`) 六个预设的、符合 RIS-Live 格式的事件,无需连接网络 即可端到端测试每个子系统: | # | 场景 | 验证内容 | |---|---|---| | A | 干净的路由,用于建立基线 | 工具在合法流量上保持沉默 | | B | 宽泛的 `/16`,`INVALID_LENGTH` | Fat-finger 启发式正确触发 | | C | 监视列表中的 `/24`,恶意源,无关联关系 | 针对性 MITM 启发式正确触发 | | D | 路径中间重复出现非源 ASN | AS-path 投毒检测器捕捉到它,提升 MITM 分数 | | E | 带有 `65535:666` blackhole community 的 `/32` | Community 解码抑制了误报 | | F | 与 A 相同的 prefix,新源,完全没有 ROA | 基线偏差捕捉到 RPKI 无法察觉的泄露 | 除了一个 watchlist 示例 Cloudflare 的公共 `1.1.1.0/24` 解析器(仅用于展示 watchlist 机制的工作原理,并非声称发生了任何真实事件)外, 使用的每个 prefix 均来自 IANA 保留的文档范围(RFC 5737: `192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`)。所有的“恶意” 和“客户”ASN 都在 IANA 的私有使用范围内(64512–65534)。 ## 在生产环境中替换为真实数据 - **AS 关系**:`data/sample_as_relationships.txt` 是一个微小的、 手动构建的说明性子集。要进行真实的 valley-free 检查,请从 [CAIDA 的 AS 关系项目](https://publicdata.caida.org/datasets/as-relationships/serial-2/) 下载实际的数据集(相同的 `as1|as2|relationship` 格式),并将 `--relationships` 指向它。 - **Watchlist**:使用对你真正重要的 prefix 编辑 `data/watchlist.json`。 - **RPKI**:`jobless_router/rpki.py` 调用 RIPEstat 免费的 `rpki-validation` API —— 不需要密钥,只需正常的互联网访问。 - **持久化**:传入 `--db-dir /some/real/path` 而不是默认的 `:memory:`,这样基线和惯犯数据库在重启后依然存在。 ## 架构 ``` firehose.py (producer: receives off the websocket, pushes to a queue) | v asyncio.Queue | v run.py (consumer) --> engine.py --(orchestrates)--> rpki.py (cached) |--> path_analysis.py (traversal + poisoning) |--> relationships.py (valley-free / Gao-Rexford) |--> communities.py (RFC1997/7999 decoding) |--> baseline.py (sqlite, learns "normal") |--> blast_radius.py (multi-collector sampling, bounded) |--> heuristics.py (intent scoring) |--> threat_db.py (sqlite, repeat offenders) |--> ct_correlation.py (crt.sh cross-check) |--> mitigation.py (advisory playbook text) `--> report.py (markdown rendering) ``` 生产者和消费者作为独立的 asyncio 任务运行,因此缓慢的评分 pipeline 绝不会延迟 websocket 本身的排空。任何一个任务 崩溃都会立即显现(`asyncio.wait(..., FIRST_EXCEPTION)`), 而不是在另一个任务继续运行时默默死去。 ## 关于范围和诚实的说明
标签:BGP, Python, RPKI, 威胁情报, 开发者工具, 无后门, 网络安全, 计算机取证, 路由监控, 逆向工具, 隐私保护