GFW 主动探测与 DNS 污染
原理与防护科普

面向一般技术读者:用公开学术研究解释 GFW 如何识别代理、DNS 污染为什么不等于主动探测,以及一个多协议代理部署应如何降低暴露面。所有引用链接保留在原文位置。
客户端与服务端
GFW 传感器与探测器

1. 摘要

核心说法是真的,但对象常被说错。GFW 主动探测确实存在:当中国境内客户端连接到一个代理服务器后,分布在中国境内的探测 IP 会反向连接到该服务器的 IP:port,以确认它是不是代理。但它出现在代理或 Web 服务器的连接日志里,不是 DNS 日志里;它也只针对容易被探测的代理协议,不会探测你随便访问的任意地址。(IMC'20)
“马上探测你”只是最快尾部,不是常态。实测最短延迟是 0.28 秒,但中位数约 1 分钟,超过 75% 在 15 分钟内,长尾可到 570 小时。(IMC'20)
“DNS 解析探测”是概念混淆。GFW DNS 污染是链路上的伪造响应,不会额外向你的权威 DNS 服务器发起查询;所谓“DNS 解析请求日志”既看不到 DNS 污染,也看不到主动探测。这里把两个不同的 GFW 子系统混在了一起。(GFWatch/USENIX'21, Citizen Lab)
“封 5 年后释放”有一部分像,但机制不对。GFW 封锁列表会动态变化,GFWatch 也跟踪到过解封;但没有公开证据显示存在固定年限自动释放。这更像政策或人工驱动的名单变化,而且它与主动探测属于不同系统。(GFWatch/USENIX'21)
用阿里云复现实验是可行的。研究者在阿里云北京 VPS 上复现实验,行为没有差别;但它必须作为跨境出站客户端去连接你控制的境外服务器。中国境内到境内的连接不会触发。你要观察的是境外服务器日志。注意服务条款、IP 消耗和研究伦理。(USENIX'23)
确实有现成“python 脚本”groundcat/Block-GFW-Active-Detection。但它本质上是白名单防火墙,不适合公开代理部署,因为公开服务无法枚举成千上万移动和家庭宽带客户端 IP。长期有效的防护应在协议层解决。(repo)
面向代理部署的结论:REALITY、Hysteria2、AnyTLS、SS2022 这类现代协议组合已经是较抗探测的方向。真正的线上风险通常不是“GFW 神秘扫描”,而是配置退化,例如 AnyTLS 错误地对外返回自签或占位证书,让探测器一眼看出“这不是正常网站”。专线中继入口在结构上避开这两个子系统;各地区直连出口才是第一类探测目标。

2. GFW 主动探测到底是什么,以及如何确认一次命中就是探测

两个独立的 GFW 系统:很多误解都来自这里

GFW 至少运行着两个相互独立的检测系统,公共讨论里经常把它们混在一起:

System A:对代理服务器的主动探测

面向 Shadowsocks、VMess、obfs4、Trojan 等代理协议。它分两步:

  1. 被动标记。链路上的 DPI 先观察你的连接。对 Shadowsocks 来说,它会看首个数据包的长度与 Shannon entropy;握手后的一个包就足以触发标记,高熵包被探测的概率约高 4 倍。(IMC'20)
  2. 主动探测。随后 GFW 会主动连接你的 IP:port,发送刚才真实客户端流量的部分重放,外加随机长度探测包。如果服务器“像代理一样响应”,这个 IP/端口组合就可能被封锁。(IMC'20, net4people #58)

System B:对“全加密流量”的被动封锁

这个系统在 2021 年 11 月部署,是现代更主要的实时封锁器,而且它根本不主动探测:超过 99% 的测试中,GFW 在封锁前没有发送主动探测,而是“纯粹基于被动流量分析”做判断。它通过豁免工作:看起来像已知协议(TLS/HTTP)的流量,或者包含足够多可打印 ASCII / 低 set-bit ratio 的流量会被放过;高熵的“全加密”流会被实时 RST 或丢弃。一个具体豁免条件是:前 6 个字节都在可打印范围 0x20–0x7e 内。(USENIX'23, PDF)

所以:“未知 IP 来探测”描述的是 System A。今天占主导的实时封锁器是 System B,它不会探测。说“GFW 总是先探测再封锁”并不符合当前事实。

验证信号:怎样知道一次连接就是 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 / Carol 检测链路

链路:Alice → Bob 触发 GFW 被动标记 → Carol 探测 Bob 进行确认 → 封锁。

ALICE 中国客户端 BOB 境外服务器 CAROL GFW 探测器 GFW DPI

3. 对常见聊天说法的核查

#常见说法判断修正与细节
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)

4. 如何复现:家庭宽带 vs 中国境内云服务器

家庭宽带与 Aliyun/Tencent:已验证的差异

家庭宽带Aliyun/Tencent 中国境内 VPS
能触发探测吗? 能,且已验证行为一致。研究覆盖阿里云北京(AS37963)与 Tencent 北京(AS45090)。(USENIX'23)
成本与便利性 需要真实中国线路 成本最低,不需要住宅宽带
硬性限制 必须跨境 必须作为出站客户端跨境连接到境外服务器。中国境内到境内不会触发;论文明确写到 “could not be triggered from outside China.” (USENIX'23)

最低成本复现实验

  1. 一台你控制的境外 VPS,使用可丢弃 IP,因为它可能会被封。在上面运行可疑服务,或者用 nc/echo listener,并开启完整抓包:tcpdump -ni any 'port <port>' -w /root/probe-$(date +%s).pcap
  2. 中国侧客户端 = Aliyun-CN 或 Tencent-CN VPS,研究已验证它与家庭宽带等价。
  3. 从中国侧机器向外连接,发送真实的高熵或已认证 payload。真实握手才会触发标记。触发成本很低:常常一个 1 字节 TCP payload 就够;只有 TCP 触发,UDP 不触发。(USENIX'23)
  4. 观察境外服务器日志,看是否有新的中国来源 IP 跟进连接。再放一台没有被连接过的境外对照主机,它应该保持安静;这个负例用于证明因果关系。
  5. 用残留封锁确认:同一客户端重连,预期同一 (client,server,port) 三元组会被封锁约 180 秒。(USENIX'23)

重要注意事项

5. 现有工具与抗探测设计

防火墙/封禁工具:多数不适合公开代理部署

工具 / 设计作用适合公开协议节点吗?维护与风险
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% 检出率;这些数字仅作提示,不是同行评审结论。
“共同胜利原则:先认证,再差异化响应。未认证探测器看到的应该是随机字节、超时,或者一个真实但无关的网站,绝不能看到代理形状的响应。”
gfw.report ss_advise, USENIX'23

6. 多协议代理部署的暴露面排序

威胁模型:一个协议要“赢”,需要同时做到两件事:(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 研究中的主要目标。 应确认迁移后没有残留监听

会削弱抗性的部署缺口:真正的风险

专线中继 vs 直连出口的攻击面

直连出口 GFW 专线中继 私有线路 暴露给探测 结构上规避

7. 推荐防护动作(按优先级)

无需调整(设计上已经正确):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 证书覆盖风险是部署工程中的高置信度风险。社区检测比例只作为提示,不应当当作同行评审结论。