常见的 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 端口。
可以看出这个机制非常简单粗暴,因此绕过干扰的方法也很容易,大致可以归为以下几个思路:
- 使用境内的无污染 DNS
- 使用境外的非标准端口 DNS
- 使用特殊的 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 最常见也是运用最广泛的屏蔽手段之一,因此一一列举它的所有应用场合是不可能的,此处将会举出影响最大的几种:
- 使用 TCP 的 DNS
- 包含敏感词的 HTTP 请求,这在互联网逐渐 HTTPS 化之后逐渐失去了意义
- SNI 和 HTTPS 证书中包含被屏蔽网址的 HTTPS 请求
针对 GFW 的这一策略,可以使用下面这些方法绕过:
- 使用各种代理
- 找到 RST 攻击的漏洞并进行反干扰
- 在使用了 HTTPS 的网站上,使用 ESNI 来避免 SNI 触发 GFW。也可以仅代理 HTTPS 握手,之后的数据直连
- 对于使用了 HTTPS 以及 CDN 的网站,可以通过指定 HOST 的方式隐藏 SNI
IP 黑洞
这是最严重的封锁方法。在 GFW 尚未完善的时候,这是唯一的屏蔽手段,因此很多早期就被屏蔽的网站诸如 Facebook 等等均被使用该手段屏蔽。其实现方式是使用 BGP 协议,把无效的路由黑洞加入到主干路由器的路由表中,然后让它们把到指定 IP 的包给丢弃掉。
对抗 IP 黑洞没有什么好办法,只有使用代理。对于 Google 或是 Facebook 这样拥有巨量 IP 的公司,常常能找到尚未被屏蔽的地址,但这样只能短暂地解决问题,更不用说该手段常常结合其他手段使用。