常见的 GFW 技术

Posted on Wed, 25 Dec 2024 10:11:05 +0800 by LiangMingJian


DNS 污染

这是最容易绕过,也常常是最先被应用的干扰.。

DNS 可以使用 UDP 或是 TCP 来传输,但由于 DNS 数据量通常非常小,因此出于降低延迟的考虑,各种操作系统中的 DNS 都默认使用 UDP 连接。UDP 不基于连接的特性极大地便利了中间人给数据动手脚,因此在查询一些网站的 IP 时,防火墙会返回错误的 IP 地址。比如查询 Reddit 的 IP 地址时:

drill www.reddit.com @8.8.8.8
;; ANSWER SECTION:
www.reddit.com.	65	IN	A	31.13.69.129

可以看到返回了 Facebook 的地址,因此显然不能建立到 Reddit 的连接。

对 DNS 请求进行抓包可以看到 GFW 是如何实现这一特性的:

GFW 通过运行商部署的 DNS 污染系统,在检查到在屏蔽列表中的域名时,且该次请求访问的是境外服务器的 53 端口时,会立即返回一个假的 DNS 查询结果。因为 DNS 唯一的标识是以明文写在请求中的 Transcation ID,因此这个结果显然会比真正的结果返回的更快,之后系统就会把这个结果当作本次 DNS 请求的结果.。这带来的一个奇妙的现象是:在境内对任意境外服务器的 53 端口查询被屏蔽的网站,都会返回查询结果,即使服务器不开放 53 端口。

可以看出这个机制非常简单粗暴,因此绕过干扰的方法也很容易,大致可以归为以下几个思路:

  1. 使用境内的无污染 DNS
  2. 使用境外的非标准端口 DNS
  3. 使用特殊的 DNS 查询机制, 可以识别并丢弃 GFW 制造的假数据

TCP RST

TCP 标准中规定了 Control Bits 中的第四位为 RST,如果置 1 则立即中止当前的连接。GFW 恶意使用该机制来对 TCP 连接进行干扰。

识别一个 TCP 连接需要识别一个四元组,包括被存放在下层的 IP 包中源 IP 和 目的 IP,被存放在 TCP 头中源端口和目的端口,然后在计算出 TCP 包的序列号并记录下源和目的的 MAC 地址后,就可以向请求者和服务器双方发出伪造的 RST 包,造成 TCP 连接中断。

同样以对 8.8.8.8 发起的 DNS 请求为例,只不过这次加上了强制 TCP 的选项:

我们可以清晰地看到这次请求被中断的过程。

首先和服务器进行三次握手,建立 TCP 连接,之后向服务器发出数据,此处为 DNS 请求,GFW 检测到了本次请求需要干扰,向双方发送了伪造的 RST 数据包。 在收到 RST 之后,连接立刻中断。

RST 攻击是 GFW 最常见也是运用最广泛的屏蔽手段之一,因此一一列举它的所有应用场合是不可能的,此处将会举出影响最大的几种:

  1. 使用 TCP 的 DNS
  2. 包含敏感词的 HTTP 请求,这在互联网逐渐 HTTPS 化之后逐渐失去了意义
  3. SNI 和 HTTPS 证书中包含被屏蔽网址的 HTTPS 请求

针对 GFW 的这一策略,可以使用下面这些方法绕过:

  1. 使用各种代理
  2. 找到 RST 攻击的漏洞并进行反干扰
  3. 在使用了 HTTPS 的网站上,使用 ESNI 来避免 SNI 触发 GFW。也可以仅代理 HTTPS 握手,之后的数据直连
  4. 对于使用了 HTTPS 以及 CDN 的网站,可以通过指定 HOST 的方式隐藏 SNI

IP 黑洞

这是最严重的封锁方法。在 GFW 尚未完善的时候,这是唯一的屏蔽手段,因此很多早期就被屏蔽的网站诸如 Facebook 等等均被使用该手段屏蔽。其实现方式是使用 BGP 协议,把无效的路由黑洞加入到主干路由器的路由表中,然后让它们把到指定 IP 的包给丢弃掉。

对抗 IP 黑洞没有什么好办法,只有使用代理。对于 Google 或是 Facebook 这样拥有巨量 IP 的公司,常常能找到尚未被屏蔽的地址,但这样只能短暂地解决问题,更不用说该手段常常结合其他手段使用。

参考文件 1: 墙, 墙和更高的墙 @shockwave