技术无罪。
防火长城(英语:Great Firewall,GFW),中国国家防火墙,或简称为墙、防火墙等,中国网信办称其为数据跨境安全网关,是该国政府过滤国际互联网出口内容的软硬件系统集合。———— Wikipedia
要有效对抗 GFW,不应只关注哪些网站被封,而应深入了解其封锁机制。知道 Google 被封并不能直接帮助翻墙,但理解 GFW 如何封锁 Google 对选择和实施翻墙方案至关重要。因此,在讨论翻墙方法之前,必须先深入研究 GFW 的封锁原理。
GFW 在哪
很多人可能想当然:GFW 当然部署在出口网关上,这样就能直接抓到全部出口流量进行审查了。但事实上,据 gfwrev.blogspot.com 考证,GFW “在三个国际出口作旁路监听”,通过分光的方式将所有出入境的 IP 包复制到 GFW 集群上以进行审查。推测的 GFW 网络拓扑如下(图源 gfwrev.blogspot.com):
GFW 希望对不同线路的链路异构性进行耦合,并研究了多种链路的耦合技术(来源:高速网络环境下入侵检测系统结构研究)。根据《国际通信出入口局管理办法》,几大 ISP 在公用国际光缆处汇合,而安管中心(CNNISC)有独立的交换中心,各 ISP 分别接入其交换中心。为了适应不同 ISP 的链路规格,GFW 的交换中心需要对不同链路进行整合,不同 ISP 分别引出旁路接入 GFW。接入的线路主要是光纤线路,所以称为“旁路分光”。实验发现,GFW 的接入地点不一定紧靠最后一跳,所以图中以虚线表示。
关于这些有一篇更严谨的研究论文:Internet Censorship in China: Where Does the Filtering Occur?
早期(2010 年)研究认为,GFW 工程伪装成“虚拟计算环境实验床”计划实施
“虚拟计算环境实验床”是由国家计算机网络应急技术处理协调中心(CNCERT/CC)和哈尔滨工业大学(HIT)协作建设,以国家计算机网络应急技术处理协调中心遍布全国31个省份的网络基础设施及计算资源为基础,对分布自治资源进行集成和综合利用,构建起的一个开放、安全、动态、可控的大规模虚拟计算环境实验平台,研究并验证虚拟计算环境聚合与协同机理。
从“虚拟计算环境试验床”公开的论文:计算网格环境下基于多址协同的作业级任务调度算法来看,2005 年该平台的配置如下:
站点 | 地理位置 | 机型 | 节点数 | 每节点处理器 | 每节点主存 |
---|---|---|---|---|---|
CNCERT/CC | 北京 | 曙光4000L | 128节点 | 2*Xeon 2.4G | RAM2G |
HIT | 哈尔滨 | 曙光服务器 | 32节点 | 2*Xeon 2.4G | RAM2G |
CNCERT/CC | 上海 | Beowulf集群 | 64节点 | 2*AMD | Athlon 1.5G |
当然,如此配置仅是 2005 年的配置,目前 GFW 的软硬件配置已难以考证。
数据处理
GFW 在获取到 IP 包后,需要决定是否允许你与服务器之间的通信继续。它不能过于激进,因为全国性地阻断访问国外网站违背其存在价值。GFW 在理解 IP 包的含义后,才决定是否安全地阻断你与国外服务器的连接。GFW 首先需要进行重建,分析其中的 TCP 协议,以最终重建出一个完整的字节流,供后续在这个重建的字节流上分析具体的应用协议,比如 HTTP 协议。然后在应用协议中查找是否存在不和谐的内容,然后决定采用何种应对方式。
为了简化讨论,假设有如下三个 TCP 包:
IP 包 1:包含 TCP 包:包含的数据:Get /inde
IP 包 2:包含 TCP 包:包含的数据:x.html H
IP 包 1:包含 TCP 包:包含的数据:TTP/1.1
重建需要做的事情就是把 IP 包 1 中的 GET /inde 和 IP 包 2 中的 x.html H 和 IP 包 3 中的 TTP/1.1 拼到一起变成 GET /index.html HTTP/1.1。拼出来的数据可能是纯文本的,也可能是二进制加密的协议内容。具体是什么是你和服务器之间约定好的。GFW 做为窃听者需要猜测才知道你们俩之间的交谈内容。对于 HTTP 协议就非常容易猜测了,因为 HTTP 的协议是标准化的,而且是未加密的。所以 GFW 可以在重建之后很容易的知道,你使用了 HTTP 协议,访问的是什么网站。
重建这样的字节流有一个难点是如何处理巨大的流量?这个问题在这篇博客中已经讲得很明白了。其原理与网站的负载均衡器一样。对于给定的来源和目标,使用一个 HASH 算法取得一个节点值,然后把所有符合这个来源和目标的流量都往这个节点发。所以在一个节点上就可以重建一个 TCP 会话的单向字节流。
最后为了讨论完整,再提两点
- 虽然 GFW 的重建发生在旁路上是基于分光来实现的,但并不代表整个 GFW 的所有设备都在旁路。后面会提到有一些 GFW 应对形式必须是把一些 GFW 的设备部署在了主干路由上,比如对 Google 的 HTTPS 的间歇性丢包,也就是 GFW 是要参与部分 IP 的路由工作的。
- 重建是单向的 TCP 流,也就是 GFW 根本不在乎双向的对话内容,它只根据监听到的一个方向的内容然后做判断。但是监听本身是双向的,也就是无论是从国内发到国外,还是从国外发到国内,都会被重建然后加以分析。所以一个 TCP 连接对于 GFW 来说会被重建成两个字节流。
分析
分析是 GFW 在重建出字节流之后要做的第二步。对于重建来说,GFW 主要处理 IP 协议,以及上一层的 TCP 和 UDP 协议就可以了。但是对于分析来说,GFW 就需要理解各种各样的应用层的稀奇古怪的协议了。甚至,我们也可以自己发明新的协议。
总的来说,GFW 做协议分析有两个相似,但是不同的目的。第一个目的是防止不和谐内容的传播,比如说使用 Google 搜索了 “不该” 搜索的关键字。第二个目的是防止使用翻墙工具绕过 GFW 的审查。
对于 GFW 具体是怎么达到目的一,也就是防止不和谐内容传播的就牵涉到对 HTTP 协议和 DNS 协议等几个协议的明文审查。大体的做法是这样的:
1. 特征检测
2. 拆包
3. 关键词匹配
像 HTTP 这样的协议会有非常明显的特征供检测,所以第一步就没什么好说的了。当 GFW 发现了包是 HTTP 的包之后就会按照 HTTP 的协议规则拆包。这个拆包过程是 GFW 按照它对于协议的理解来做的。比如说,从 HTTP 的 GET 请求中取得请求的 URL。然后 GFW 拿到这个请求的 URL 去与关键字做匹配,比如查找 Twitter 是否在请求的 URL 中。为什么有拆包这个过程?首先,拆包之后可以更精确的打击,防止误杀。另外可能预先做拆包,比全文匹配更节省资源。其次,liruqi/jjproxy 的核心就是基于 GFW 的一个 HTTP 拆包的漏洞,当然这个 bug 已经被修复了。其原理就是 GFW 在拆解 HTTP 包的时候没有处理有多出来的 \r\n 这样的情况,但是你访问的 google.com 却可以正确处理额外的 \r\n 的情况。从这个例子中可以证明,GFW 还是先去理解协议,然后才做关键字匹配的。关键字匹配应该就是使用了一些高效的正则表达式算法,没有什么可以讨论的。
目前已知的 GFW 会做的协议分析如下:
DNS 协议
GFW 可以分析 53 端口的 UDP 协议的 DNS 查询。如果查询的域名匹配关键字则会被 DNS 劫持。可以肯定的是,这个匹配过程使用的是类似正则的机制,而不仅仅是一个黑名单,因为子域名实在太多了。证据是
- 2010 年 3 月,一名智利域名注册商的技术人员发现向位于中国的根服务器查询 facebook.com、youtube.com 和 twitter.com 等域名时的回复不正常。中国根服务器运营商 Netnod 于是暂时切断了其与国际互联网的连接。安全专家认为这与 Netnod 无关,而是中国政府修改某处网络时造成的。
- 2014 年 1 月 21 日下午三点半,中国互联网域名解析异常,大量网站被错误解析到IP地址 65.49.2.178,这个 IP 位于美国加利福尼亚州费利蒙市 Hurricane Electric 公司,被动态网公司租用于翻墙软件连接节点。动态网公司和研究人员认为这是因为防火长城的工作人员操作失误,另一些人认为,不能排除真正的黑客借这一IP地址作为跳板发动攻击的可能。
- 2015 年 1 月 2 日,污染方式有所改变,防火长城不再注入固定、被封锁IP地址,而是境外真实网站的、可访问的地址,这导致了境外服务器遭受来自中国的 DDoS 攻击,部分网站因此屏蔽中国 IP。该年 4 月,CNCERT 发表声明称,劫持是境外攻击所致。
来源:https://zh.wikipedia.org/wiki/防火长城
HTTP 协议
GFW 可以识别出 HTTP 协议,并且检查 GET 的 URL 与 HOST。如果匹配了关键字则会触发 TCP RST 阻断。
TLS 协议
早期 TLS 版本中,服务器握手响应,包括证书,是未被加密的,GFW 可以嗅探它而得知访问站点,自 TLS 1.3 开始,ServerHello 之后的握手信息,包括站点证书,也会被加密后传输,一般可以认为能防止对证书信息的检测
然而现在普遍使用的 SNI 协议是 TLS 的一个扩展协议,在该协议下客户端在握手过程开始时告诉服务器其连接的域名,以便运作多个 HTTPS 网站的服务器选择并提供对应证书,而该扩展也未被加密。GFW 当前也会嗅探 SNI 握手阶段的明文域名以进行阻断。由于 HTTPS 即 HTTP + TLS,对 HTTPS 连接的检测仍可以归类为对 HTTP 的检测。
注意:由于 GFW 无法获取目标域名的证书,GFW 仍然无法解密实际的 HTTPS 内容
流量特征识别
GFW 的第二个目的是封杀翻墙软件。为了达到这个目的 GFW 采取的手段更加暴力。原因简单,对于 HTTP 协议的封杀如果做不好会影响互联网的正常运作,GFW 与互联网是共生的关系,它不会做威胁自己存在的事情。但是对于 TOR 这样的几乎纯粹是为翻墙而存在的协议,只要检测出来就是格杀勿论的了。GFW 具体是如何封杀各种翻墙协议的,我也不是很清楚,事态仍然在不断更新中。但是举两个例子来证明 GFW 的高超技术。
第一个例子是 GFW 对 TOR 的自动封杀,体现了 GFW 尽最大努力去理解协议本身。根据这篇博客 https://blog.torproject.org/blog/knock-knock-knockin-bridges-doors 。 使用中国的 IP 去连接一个美国的 TOR 网桥,会被 GFW 发现。然后 GFW 回头(15 分钟之后)会亲自假装成客户端,用 TOR 的协议去连接那个网桥。如果确认是 TOR 的网桥,则会封当时的那个端口。换了端口之后,可以用一段时间,然后又会被封。这表现出了 GFW 对于协议的高超检测能力,可以从国际出口的流量中敏锐地发现你连接的 TOR 网桥。据 TOR 的同志说是因为 TOR 协议中的握手过程具有太明显的特征了。另外一点就表现了 GFW 的不辞辛劳,居然会自己伪装成客户端过去连连看。
第二个例子表现了 GFW 根本不在乎加密的流量中的具体内容是不是有敏感词。只要疑似翻墙,特别是提供商业翻墙服务,就会被封杀。(几乎可以确定)GFW 已经升级为能够机器识别出哪些加密的流量是疑似翻墙服务的。
GFW 显然近期的工作重心在分析网络流量上,从中识别出哪些是翻墙的流量。这方面的研究还比较少,而且一个显著的特征是自己用没关系,大规模部署就容易出问题。
干扰措施
GFW 通过协议分析,确定你这个字节流是“具有威胁的”,就会通过以下几种方式来干扰继续通信:
IP 封锁
一般常见于人工检测之后的应对。还没有听说有什么方式可以直接使得 GFW 的机器检测直接封 IP。一般常见的现象是 GFW 机器检测,然后用 TCP RST 重置来应对。过了一段时间才会被封 IP,而且没有明显的时间规律。所以我的推测是,全局性的封 IP 应该是一种需要人工介入的。注意我强调了全局性的封 IP,与之相对的是部分封 IP,比如只对你访问那个 IP 封个 3 分钟,但是别人还是可以访问这样的。这是一种完全不同的封锁方式,虽然现象差不多,都是 ping 也 ping 不通。要观摩的话 ping twitter.com 就可以了,都封了好久了。
其实现方式是把无效的路由黑洞加入到主干路由器的路由表中,然后让这些主干网上的路由器去帮 GFW 把到指定 IP 的包给丢弃掉。路由器的路由表是动态更新的,使用的协议是 BGP 协议。GFW 只需要维护一个被封的 IP 列表,然后用 BGP 协议广播出去就好了。然后国内主干网上的路由器都好像变成了 GFW 的一份子那样,成为了帮凶。
如果我们使用 traceroute 去检查这种被全局封锁的 IP 就可以发现,IP 包还没有到 GFW 所在的国际出口就已经被电信或者联通的路由器给丢弃了。这就是 BGP 广播的作用了。
DNS 劫持
这也是一种常见的人工检测之后的应对。人工发现一个不和谐网站,然后就把这个网站的域名给加到劫持列表中。其原理是基于 DNS 与 IP 协议的弱点,DNS 与 IP 这两个协议都不验证服务器的权威性,而且 DNS 客户端会盲目地相信第一个收到的答案。所以你去查询 facebook.com 的话,GFW 只要在正确的答案被返回之前抢答了,然后伪装成你查询的 DNS 服务器向你发错误的答案就可以了。
TCP 连接重置
TCP 协议规定,只要看到 RST 包,连接立马被中断。从浏览器里来看就是连接已经被重置。我想对于这个错误大家都不陌生。据我个人观感,这种封锁方式是 GFW 目前的主要应对手段。大部分的 RST 是条件触发的,比如 URL 中包含某些关键字。目前享受这种待遇的网站就多得去了,著名的有 facebook。还有一些网站,会被无条件 RST。也就是针对特定的 IP 和端口,无论包的内容就会触发 RST。比较著名的例子是 https 的 wikipedia。GFW 在 TCP 层的应对是利用了 IPv4 协议的弱点,也就是只要你在网络上,就假装成任何人发包。所以 GFW 可以很轻易地让你相信 RST 确实是 Google 发的,而让 Google 相信 RST 是你发的。
端口封锁
GFW 除了自身主体是挂在骨干路由器旁路上的入侵检测设备,利用分光技术从这个骨干路由器抓包下来做入侵检测 (所谓 IDS),除此之外这个路由器还会被用来封端口 (所谓 IPS)。GFW 在检测到入侵之后可以不仅仅可以用 TCP RST 阻断当前这个连接,而且利用骨干路由器还可以对指定的 IP 或者端口进行从封端口到封 IP,设置选择性丢包的各种封禁措施。可以理解为骨干路由器上具有了类似 “iptables” 的能力(网络层和传输层的实时拆包,匹配规则的能力)。这个 iptables 的能力在 CISCO 路由器上叫做 ACL Based Forwarding (ABF)。而且规则的部署是全国同步的,一台路由器封了你的端口,全国的挂了 GFW 的骨干路由器都会封。一般这种封端口都是针对翻墙服务器的,如果检测到服务器是用 SSH 或者 VPN 等方式提供翻墙服务。GFW 会在全国的出口骨干路由上部署这样的一条 ACL 规则,来封你这个服务器 + 端口的下行数据包。也就是如果包是从国外发向国内的,而且 src(源 ip)是被封的服务器 ip,sport(源端口)是被封的端口,那么这个包就会被过滤掉。这样部署的规则的特点是,上行的数据包是可以被服务器收到的,而下行的数据包会被过滤掉。
如果被封端口之后服务器采取更换端口的应对措施,很快会再次被封。而且多次尝试之后会被封 IP。初步推断是,封端口不是 GFW 的自动应对行为,而是采取黑名单加人工过滤地方式实现的。一个推断的理由就是网友报道,封端口都是发生在白天工作时间。
反向墙
大部分机场使用的国内中转服务器,GFW 检测到了十分异常的境外大流量,就会在特殊时期,如两会和国庆期间,将该服务器反向墙。具体表现为国外的服务器无法访问该被反向墙了的 IP。ping 该国内服务器就是国外一片红,国内一片绿。解决方法不多,要么更换 IP,或者等敏感时期过去,自动恢复。
本文转载编辑补充自