IP:port,以确认它是不是代理。但它出现在代理或 Web 服务器的连接日志里,不是 DNS 日志里;它也只针对容易被探测的代理协议,不会探测你随便访问的任意地址。(IMC'20)
groundcat/Block-GFW-Active-Detection。但它本质上是白名单防火墙,不适合公开代理部署,因为公开服务无法枚举成千上万移动和家庭宽带客户端 IP。长期有效的防护应在协议层解决。(repo)
GFW 至少运行着两个相互独立的检测系统,公共讨论里经常把它们混在一起:
面向 Shadowsocks、VMess、obfs4、Trojan 等代理协议。它分两步:
IP:port,发送刚才真实客户端流量的部分重放,外加随机长度探测包。如果服务器“像代理一样响应”,这个 IP/端口组合就可能被封锁。(IMC'20, net4people #58)所以:“未知 IP 来探测”描述的是 System A。今天占主导的实时封锁器是 System B,它不会探测。说“GFW 总是先探测再封锁”并不符合当前事实。
信号出现在你的服务器连接日志里。一次探测会有清晰且可证伪的指纹:
| 信号 | 表现 | 为什么有诊断意义 |
|---|---|---|
| 由连接触发,不是随机扫网 | 真实中国客户端连接后不久,探测连接才到来;同机房中没有被连接过的被动对照主机收到零探测。 | 说明这不是互联网背景扫描,而是对你这条流的反应。(IMC'20) |
| 按字节重放的 payload | payload 与刚刚真实握手中的数据完全相同或近似相同(R1 相同;R2 翻转第 0 字节;R3 使用第 0–7 与 62–63 字节;R4 使用第 16 字节;R5 使用第 6 与第 16 字节)。 | 只有刚刚看见你流量的 GFW 才能这样重放。 |
| 固定长度的垃圾探测包 | 非重放探测:正好 221 字节(NR2,约为最常见类型的 3 倍),或者 7–50 字节的小包(NR1)。重放 payload 多数为 160–700 字节。 | 这是特征长度,不是正常业务流量。 |
| 无法完成的握手 | TCP 三次握手完成后,对方丢来一段高熵数据,但无法形成有效会话。 | 探测器无法认证。 |
| 来源 IP 变化快、单 IP 流量低 | 许多不同的中国来源 IP 短暂出现,每个 IP 的访问量很少。 | 探测池很大,而且在不断轮换。 |
| TCP timestamp 相关性 | 约 12,300 个来源 IP 共享少数几条线性 timestamp 序列(斜率约 250 Hz)→ 约 7–9 台物理系统。 | 这是决定性证据:可把集中协调的 GFW 探测器与互不相关的扫描器区分开来。(IMC'20) |
| 残留封锁窗口(免费复核) | 一旦触发,GFW 会对同一 (client IP, server IP, server port) 三元组封锁约 180 秒。从同一客户端重连即可验证。 | 可复现的 RST 窗口确认了 System B 封锁。(USENIX'23) |
规模(已验证、精确):51,837 次探测,来自 12,300 个唯一来源 IP,全部在中国境内;超过 75% 的来源 IP 被重复使用。TCP timestamp 侧信道把它们折叠到约 7–9 个后端系统,这也是天真地封禁探测 IP 为什么失败的原因。(IMC'20)
链路:Alice → Bob 触发 GFW 被动标记 → Carol 探测 Bob 进行确认 → 封锁。
| # | 常见说法 | 判断 | 修正与细节 |
|---|---|---|---|
| 1 | “从中国家庭宽带访问一个地址 → 马上有未知 IP 来探测它” | 部分准确 | 对代理协议(SS/VMess/obfs4/Trojan)是真的,不是对任意网站都成立。“马上”只是最快尾部(最短 0.28 秒);中位数约 1 分钟,长尾可到 570 小时。探测器连接的是 IP:port,不是“解析”你。(IMC'20) |
| 2 | “做一个解析请求日志就能看到它们” | 部分准确,但工具错了 | 你可以观察探测,但要看代理/Web 服务器连接日志,不是 DNS 日志。DNS 注入不会向你的权威 DNS 服务器新增查询;探测是连向服务端口的 TCP/UDP 连接。(GFWatch/Citizen Lab) |
| 3 | “DNS 污染 5 年,然后网站被释放了” | 部分准确,但机制错了 | 封锁列表确实会变化,域名也会被解封,GFWatch 监测的正是这类现象;但没有公开文献证明存在固定 N 年自动释放计时器。这更像策略驱动的名单变化。DNS 污染与主动探测是分离系统。(GFWatch/USENIX'21) |
| 4 | “不用家庭宽带,用阿里云这类 VPS 复现” | 准确,但有关键限制 | 研究者验证过阿里云北京 VPS 行为一致,Tencent 北京也可作为同类中国境内云观测点;但它必须作为跨境出站客户端去连接你控制的境外服务器。中国境内到境内不会触发。要看的是境外服务器日志。(USENIX'23) |
| 5 | “有没有现成 python 脚本可以用或改?” | 准确,但不适合公开服务 | 有:groundcat/Block-GFW-Active-Detection(iptables 白名单防火墙)。它只适合私人单用户服务器;公开 VPN 无法白名单化所有客户 IP。(repo) |
| 6 | “一个多协议代理部署容易被这个影响吗?” | 取决于配置 | 现代协议栈本身较抗探测。真实暴露面通常来自配置退化,例如 AnyTLS 自签证书,尤其是在直连出口上。专线中继路径结构上风险更低。见 §6。 |
| 7 | (隐含)“GFW 总是先探测再封锁” | 误解 | 2021 年后的主导封锁器 System B 在超过 99% 测试中不探测,纯被动封锁。(USENIX'23) |
| 8 | (隐含)“有未知 IP 打我的 nameserver = GFW 侦察” | 误解 | GFW 侦察表现为连向服务端口的出站连接,在服务器侧可见。DNS 注入是链路上伪造响应;除非你的 NS 自身位于或经过中国境内链路,否则在你的 NS 日志里不可见。(net4people #294) |
| 家庭宽带 | Aliyun/Tencent 中国境内 VPS | |
|---|---|---|
| 能触发探测吗? | 能 | 能,且已验证行为一致。研究覆盖阿里云北京(AS37963)与 Tencent 北京(AS45090)。(USENIX'23) |
| 成本与便利性 | 需要真实中国线路 | 成本最低,不需要住宅宽带 |
| 硬性限制 | 必须跨境 | 必须作为出站客户端跨境连接到境外服务器。中国境内到境内不会触发;论文明确写到 “could not be triggered from outside China.” (USENIX'23) |
nc/echo listener,并开启完整抓包:tcpdump -ni any 'port <port>' -w /root/probe-$(date +%s).pcap。| 工具 / 设计 | 作用 | 适合公开协议节点吗? | 维护与风险 |
|---|---|---|---|
groundcat/Block-GFW-Active-Detection (repo) |
生成 iptables 白名单防火墙:只有 DDNS 解析出的客户端 IP 能访问代理端口,其他探测全部 DROP。这就是很多人记得的“python 脚本”。 | 不适合:公开 VPN 无法白名单化成千上万移动和家庭宽带客户端。 | 小型单作者项目,维护有限;强依赖静态客户端 IP。 |
| 白名单防火墙思路 (net4people #246) | 同一原则;还包含粗粒度 TTL gate(--ttl-gt 80)来区分远端客户与探测器。 |
不适合公开代理部署 | TTL 可伪造且会变化,只能算启发式。 |
fail2ban / iptables -m recent |
封禁没有完成有效握手就访问端口的 IP。 | 徒劳 | 12k 轮换 IP 会跑在封禁前面,还可能误伤 CGNAT 客户。(net4people #58) |
中国 IP/ASN 封禁(ipset china_ip_list) |
丢弃中国 CIDR。 | 自毁 | 会挡住自己的中国用户;探测器也会使用非中国 ASN。 |
| Geneva (repo) | 用遗传算法演化出的包操纵策略来绕过 DPI。 | 相邻领域:它是规避研究工具,不是探测封禁器。 | 仅 Linux;策略可能被识别。 |
| 设计 | 机制 | 在典型代理部署中的位置 | 维护与风险 |
|---|---|---|---|
| REALITY (VLESS)+uTLS (README) | 遇到探测时,转发来自高信誉真实 donor 站点的真实 ServerHello 与内容;认证隐藏在握手字段中;uTLS 模拟真实 Chrome JA3。没有 SNI,也没有自签证书。 | 常用于高价值入口或测试节点 | donor dest 必须真实、地理上合理且未被封。仅 TLS 1.3。 |
| SS2022 (2022-blake3-aes-*-gcm) (SIP022) | AEAD + 强制重放保护:8 字节 Unix timestamp(拒绝超过 30 秒漂移)+ 滑动窗口 nonce 过滤,能击败 R1–R5 重放探测。 | 常见于 SS 监听端口 | 主动探测安全,但被动上仍可识别:直连跨境时,高熵流可能被 System B 命中。时钟同步很关键。 |
| Hysteria2 / Salamander (protocol) | QUIC/UDP 让 TCP 探测器无法触达;BLAKE2b-keyed XOR obfs 让它像随机 UDP;认证失败时 masquerade 到真实 Web 服务。 |
常用于 UDP 优化节点 | 设置真实 masquerade 目标,不要只返回裸 404。 |
| AnyTLS (sing-box) | 使用通配符 LE 证书包在 TLS 下;padding_scheme 随机化 record 长度,对抗 TLS-in-TLS 分析。 |
常用于若干 TLS 化节点 | 如果对外返回自签或占位证书,抗性会直接坍塌,这是公开部署中最常见的配置风险。 |
| ShadowTLS v3 (protocol) | 把真实 TLS 握手代理到 donor;检查失败时,流量原样交给 donor。 | 可作为参考或补充 | v1/v2 曾有探测脆弱性;应使用 ≥ v0.2.3。(net4people #322) |
| NaiveProxy (repo) | Chromium 栈 + app-fronting:探测流量由 Caddy 路由到真实后端。 | 参考设计 | 适合学习抗探测思路。 |
GOST probeResist (docs) |
code:404 / web:<url> / host: / file: 等 fallback;绝不返回会暴露代理身份的 407。 |
参考设计 | 适合比较不同 fallback 语义。 |
| Trojan / VMess | Trojan = 真实 TLS fallback;VMess = timestamp 防重放。 | 偏老的兼容协议 | 老化中。社区报告 Trojan 约 90%、VMess 约 80% 检出率;这些数字仅作提示,不是同行评审结论。 |
威胁模型:一个协议要“赢”,需要同时做到两件事:(1) 不像随机高熵流,而是模仿 TLS/HTTP/QUIC,从而避开 System B;(2) 对任何未认证探测都返回与真实服务难以区分的响应,比如真实证书、真实 fallback 或保持读取,从而避开 System A。
| 排名 | 协议类别 | 抗性 | 原因 | 典型部署位置 |
|---|---|---|---|---|
| 1 | REALITY/VLESS+uTLS | 抗性强 | 真实 donor ServerHello、隐藏认证、真实 JA3。当前较先进。 | 高价值入口 / REALITY 节点 |
| 2 | Hysteria2/QUIC (Salamander) | 抗性强 (前提是 obfs + masquerade 配好) | UDP 让 TCP 探测器无法触达;obfs 隐藏特征;masquerade fallback;避开以 TCP 为主的 System B。 | 各地区直连出口 |
| 3 | AnyTLS | 抗性强 → 部分抗性 (取决于证书) | 真实 LE 证书 + padding。一旦变成自签证书,就坍塌为脆弱。 | 若干 AnyTLS 节点 |
| 4 | SS2022 | 抗主动探测 / 被动上部分暴露 | timestamp + 滑动窗口可击败重放探测;但原始高熵流在直连跨境时仍暴露给 System B。 | SS 监听端口 |
| 5 | VMess (AEAD) | 部分抗性 → 脆弱 | 防重放还可以;但 TLS 内高熵流越来越容易被被动识别。协议在老化。 | 兼容或闲置路径 |
| 6 | ocserv (OpenConnect) | 部分抗性 | VPN 指纹相对明显。 | 通常不作为主力 |
| 7 | Legacy SS(stream/AEAD-2017) | 脆弱 | 正是 IMC'20 研究中的主要目标。 | 应确认迁移后没有残留监听 |
masquerade 目标之间,就是“看起来可疑”和“更接近真实网站”的区别。严重度较低,因为 HY2 本身是 UDP + obfs。ss -tulpn 扫一遍,成本最低,应优先做。无需调整(设计上已经正确):REALITY donor 配置;Hysteria2 obfs + UDP 端口跳跃;SS2022 cipher 选择;强制时钟同步。
| 优先级 | 动作 | 做法 | 原因 |
|---|---|---|---|
| P0 | 全量审计 AnyTLS 实际对外证书 | 对每个 AnyTLS 端点执行类似检查:echo | openssl s_client -connect <ip>:<port> -servername <server_name> 2>/dev/null | openssl x509 -noout -issuer -subject;issuer 应是真实 CA,不应为空或 self-signed。 |
关闭最常见的高风险现场缺口。 |
| P0 | 把“实际证书检查”加入部署健康门禁 | 不要只判断进程和端口在线;健康检查必须断言外部客户端看到的是真实证书链。 | 把反复出现的事故类型变成 CI/部署守卫。 |
| P0 (低成本) | 清扫 Legacy SS 残留 | 在每台数据面机器上执行 ss -tulpn,同时检查配置中是否存在非 2022-blake3-* cipher 或迁移遗留监听。 |
旧 stream-cipher 端口是概率最高的真实漏洞之一,几分钟内可验证。 |
| P1 | 确认 Hysteria2 使用真实 masquerade | 逐节点检查配置,确保 fallback 是真实站点或真实文件,不是裸 404。 | 让 HY2 从“较抗探测”升级到“更完整抗探测”。 |
| P2 | 做防火墙卫生,而不是封探测器 IP | SSH/管理端口只允许管理员 IP。不要在数据端口部署中国 IP 段封禁或 Block-GFW-Active-Detection。 |
封禁 12k 轮换 IP 徒劳且会挡住客户。(net4people #58) |
| P3 | 对频繁被消耗的直连出口优先使用专线中继 | 当某个地区直连出口持续遭遇 GFW IP 层封锁,可把入口切到专线中继,出口仍保留在目标地区。 | 专线路径本身不需要同等强度的探测加固。 |
| P4 (实测) | 用中国境内云服务器观测真实暴露面 | (1) 在可丢弃的测试出口节点(示例:198.51.100.20)抓包:tcpdump -ni any 'port <port>' -w /root/probe-$(date +%s).pcap。(2) 从一台中国境内的云服务器(如阿里云/腾讯云)作为观测点发起真实认证连接。(3) 保留 24–72 小时。(4) 识别近似字节重放、221 字节 / 7–50 字节垃圾包、约 250 Hz 相关 TCP timestamp。(5) 按协议重复,验证 §6 排序。 |
上面都是静态姿态。某个具体节点 IP 当前是否被探测或封锁,必须等这类抓包跑完才知道。 |
置信度:协议抗性排序(REALITY ≥ HY2 ≥ AnyTLS ≥ SS2022 > VMess > legacy-SS)来自公开研究与协议设计分析,置信度较高。AnyTLS 证书覆盖风险是部署工程中的高置信度风险。社区检测比例只作为提示,不应当当作同行评审结论。