第 6 章 · 工具箱

检测手段清单:用了什么、为什么不用逆向工具

这份文档回答两个经常被问到的问题:要不要装别的工具才能测准, 以及要不要上逆向工具。


一、不装任何东西能测什么

下面这些只用 Python 标准库 + macOS 自带的 dig / lsof / scutil / ps, git clone 完就能跑:

检测手段答什么
出口 IP / 地区 / 边缘机房向 Cloudflare 的 cdn-cgi/trace 发请求目的地那侧看到的你是谁
出口归属(ASN / 运营商)Team Cymru 的 DNS 接口(读 BGP 全表)这个地址属于谁的网络
出口城市 / 时区ip-api、ipinfo 免费额度国家相同时,靠城市区分两个出口
网段注册信息RDAP(RIR 官方,IANA bootstrap 定位)这个段是机构自有还是运营商分配
是不是大厂机房AWS / GCP / Cloudflare 等自己发布的地址段确证级判定,非推断
机房还是家宽ip-api 的 hosting / mobile / proxy 标志 + 组织名 / rDNS 启发式风控权重差别最大的属性
反向解析dig -x机器叫什么名字,常直接暴露机房
四段延迟裸 socket + ssl,自己掐表慢在 DNS / TCP / TLS / 服务端哪一段
解析对账本机 getaddrinfo vs 两个独立 DoH 源本机 DNS 有没有被改写
实时连接lsof -nP -iTCPClaude 的进程此刻连着谁
TLS 证书读握手拿到的证书公开字段有没有中间人在拆 TLS
时钟偏移cdn-cgi/trace 的 ts= 对比本机时间时钟不准会让 TLS 莫名失败
IPv6 可达性向 Cloudflare 的 v6 地址建 TCP出口在 v4/v6 之间跳是不是双栈造成的
代理端口存活连一下系统代理端口「代理配着但进程挂了」这种最难查的故障
遥测字段strings 读 Claude Code 的 JS bundle遥测会上报哪些字段

二、装了会更准的(可选)

一键装:

bash scripts/install-deps.sh          # 先看缺什么
bash scripts/install-deps.sh --dry-run  # 只检查不安装

mtr —— 唯一真正补上一个维度的工具

没有它,有一类问题答不了:TLS 握手忽快忽慢,是距离远还是链路在丢包? 四段延迟只能告诉你「TLS 这一段耗了 193 毫秒」,答不了那 193 毫秒里 有多少是重传。

装了之后多出来:跳数、每跳延迟、端到端丢包率、抖动。

两个使用上的坑,工具里已经处理了,但值得知道:

  1. 中间跳的丢包大多是假的。 很多路由器给 ICMP TTL-exceeded 做限速, 于是显示丢包但转发流量完全正常。真正算数的是最后一跳的丢包。 看到中间某跳 40% 丢包就去换节点,换了也没用。
  2. macOS 上 mtr 需要 root 才能发 ICMP。 要么每次 sudo mtr, 要么给它 setuid。本工具默认按普通用户调用 —— 一个监控工具不该 要求你用 sudo 跑它自己。所以没给权限时这一块显示"权限不足", 这是预期行为。

jq

纯粹是手工处理 cem probe --json 输出时方便,工具本身不用它。


三、为什么不用逆向工具

先分清两件完全不同的事。

「读字符串」不是逆向,也没有副作用

本仓的 cem telemetry 做的是:对一个已经在你硬盘上的文件跑 strings, 读里面的明文。

  • 不修改任何文件
  • 不注入任何进程
  • 不改变程序行为
  • 不解密任何流量

Claude Code 发行为单文件 JS bundle,没有加密、没有混淆到不可读, 构造上报内容的那段代码本来就是明文。所以这一步的收益极高而代价为零。

它能读出来的东西比想象中多:接入点 URL、client token、攒批间隔、 信封字段的固定值(比如 hostname 是写死的 "claude-code", 不会上报你的真实主机名)、业务字段名、182 个事件名的白名单, 以及几个函数名本身透露的行为(stripPiiFieldsForDatadog —— 上报前会主动剥离 PII 字段)。

真正的逆向工具在这个问题上派不上用场

IDA / Ghidra / Frida 解决的是「这个二进制在算什么」。 而本仓要回答的是「流量去哪」—— 答案在链路上和系统状态里,不在二进制里。

出口 IP 不写在代码里,它是运行时由你的分流规则决定的。 把 bundle 完整反编译出来也读不到那个答案。

唯一需要解密的场景,以及它的代价

想知道「某一次具体发了什么值」(不是「会发哪些字段」), 就必须解密 TLS。做法是起一个本地 mitm 代理 + 装一个根 CA, 让 Claude Code 信任它。

技术上完全可行,Node 对此很友好。但代价是实的:

代价说明
要装根 CA那个 CA 的私钥一旦泄露,你机器上所有 HTTPS 都能被解密。这是真实风险,不是理论风险
工具性质变了从「只读观测」变成「中间人」。之后出的任何网络异常,都无法排除是这个工具自己造成的
和本仓的承诺冲突docs/05-privacy.md 明确写了不解密、不抓包

所以本仓不做,也不提供做这件事的工具。

如果你确实需要,用现成的 mitmproxy 更合适 —— 它是专门做这件事的, 文档齐全,也把风险讲得比我清楚。但请在一台专门的测试机上做, 别在日常机器上装那个 CA。

其他形式的逆向,副作用一并列出

手段副作用
Frida 注入运行中的进程需要调试权限;改变了程序行为,之后任何异常都无法判断是不是自己搞出来的
反编译 / 修改二进制多数服务条款明确禁止逆向工程;分发修改后的二进制有法律风险
抓包(tcpdump / Wireshark)需要 root;能看到 SNI 和目的地,但看不到加密内容 —— 而 SNI 和目的地本工具已经有了,且不需要 root

三点五、证据源分层与置信度

工具用的每个证据源可信度差得很远,所以结论上会标出这条判断有多硬:

置信度什么时候给这一档例子
确证权威来源直接说的,不是判断命中 AWS / GCP / Cloudflare 自己发布的地址段
较可能第三方数据源的判断,通常准ip-api 的 hosting / mobile 标志
推测只有单一弱线索组织名里有 "cloud"、rDNS 形态像机房
判不出什么线索都没有数据源没给标志,组织名和 rDNS 也看不出来

厂商官方 IP 段(确证级,免费无限制)

厂商地址
AWSip-ranges.amazonaws.com/ip-ranges.json
Google Cloudgstatic.com/ipranges/cloud.json
Cloudflarecloudflare.com/ips-v4 · ips-v6
DigitalOceandigitalocean.com/geo/google.csv
Oracle Clouddocs.oracle.com/.../public_ip_ranges.json

实测收录约 2 万个前缀,拉一遍 4 秒。缓存 24 小时,界面上显示拉取时间, 可手动刷新 —— 与其猜多久合适,不如把新鲜度摆出来让人自己判断。

命中 = 一定是机房;没命中 ≠ 一定不是机房。 这里只覆盖几家大厂, 小机房、国内 IDC、住宅代理服务商都不在名单里。所以"没命中"只能降级到 别的证据源,不能当成"这是家宽"。

用它验证过一个之前只是推测的结论:Datadog US5 的 34.149.66.165 命中 Google Cloud 34.149.0.0/16 —— "US5 跑在 GCP 上"从推测变成确证。

其他免费源

  • RDAP(IETF 标准,RIR 官方,免费无限制)—— 已接入。 返回结构化 JSON,带网段名、分配类型、备注、abuse 联系人。 分配注册时写的,比第三方推断硬一档,但不到确证(登记可能陈旧, 各 RIR 命名习惯不同)。

实测的两种典型值,含义差别很大:

类型含义
DIRECT ALLOCATION机构直接从注册局拿的段,通常是自有网络(Google、Anthropic 都是这种)
ALLOCATED NON-PORTABLE运营商分配给客户的段,不可携带 —— 更像宽带线路

必须用 IANA bootstrap 定位该查哪个 RIR,不能挨个试。 RIR 对不归自己管的段返回的是占位记录而不是 404:拿 APNIC 查一个 美国地址会得到 IANA-NETBLOCK-34 + "not allocated to APNIC", 有 name 有 type,看起来完全像一条有效答案。照单全收就等于给出错误的 注册信息 —— 一个看起来正常的错误答案比报错糟糕得多。

  • Team Cymru DNS(已用):读 BGP 全表,ASN 的权威来源。
  • 开源离线数据集:sapics/ip-location-db(CC0/MIT)、ipverse/asn-ip、 X4BNet/lists_vpn。适合完全离线跑,代价是数据没有实时源新。

一个数据源给不了的东西:住宅 vs 企业

免费数据源给的是 hosting 这一个布尔值——只区分"是不是机房", 没有住宅 vs 企业的维度。家里的宽带和公司办公室的宽带在这里是同一类。

所以工具里这一档叫 non-datacenter(非机房宽带)而不是 residential—— 叫 residential 是在宣称一个数据源给不了的结论。要真分开得靠付费数据源 (IPinfo Privacy Detection、IP2Location usage_type、MaxMind GeoIP2 ISP)。

四、判断准不准:每个结论都带判据

工具里所有分类结论都带一行「判据」,说明它是怎么得出来的。这不是装饰:

  • 「机房还是家宽」有两级判据 —— 数据源的标志位(准)和组织名 / rDNS 启发式(不太准)。界面上会说明用的是哪一级。
  • 判不出来时显示「判不出来」而不是猜一个。原因是猜错的方向不对称: 把机房猜成家宽,会让人以为风险比实际更低。
  • 「动态还是静态 IP」单次观测答不了,只能靠观测时长 + 变更次数推断, 所以结论一定带着观测窗口。观测不足 6 小时就明说「还判断不了」, 而不是给一个看起来很确定的答案。