http://www.lightbluetouchpaper.org/2006/06/27/ignoring-the-great-firewall-of-china/
http://bbs.isbase.net/viewthread.php?tid=23766
http://www.cl.cam.ac.uk/~rnc1/
http://www.cl.cam.ac.uk/~rnc1/ignoring.pdf
http://www.williamlong.info/archives/1954.html
防火墙技巧——忽略RESET报文
我们知道,IDS(Intrusion Detection System, 入侵检测系统)的主动响应系统“阻止会话”的机制是:IDS将会向通信的两端(服务器端和客户端)各发送三个TCP RESET包,此时通信双方的堆栈将会把这个RESET包解释为另一端的回应,然后停止整个通信过程,释放缓冲区并撤销所有TCP状态信息,从而实现主动 切断连接的目的。
这时,客户端浏览器看到的现象通常是,打开某一个网页,浏览器提示“连接被重置”而无法查看页面。
IDS在逻辑上是与路由器分离的,很难从路由传输队列中去除或者延迟“有害”报文,通过RESET关闭连接相对较为简单而易于实现,那么,如何绕过IDS“会话阻止”机制呢?
标准的TCP协议,客户端收到RESET包后会中断连接,但是,如果终端两边的节点同时忽略TCP RESET,那样,即使触发了IDS,防火墙也对HTTP传输没有任何影响,这就通过忽略RESET包实现了突破IDS的“会话阻止”功能。
在Linux可以用iptables的此命令实现:
iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP
来丢弃传入的RST置位报文。如果是FreeBSD的ipfw那么命令是这样的:
ipfw add 1000 drop tcp from any to me tcpflags rst in
因此,在网页传输过程中,可以将中间夹杂的一些防火墙的TCP复位报文完全忽略,因为它们对客户端的TCP/IP栈没有任何影响,客户端仍然继续接收网页。
以上思路翻译自Ignoring the Great Firewall of China,原文很长,内容较多。我自己在Ubuntu系统上,在终端中使用iptables测试,的确可以实现忽略客户端RESET报文的功 能,Firefox浏览器再也没有出现“连接被重置”的信息,可惜由于服务器端RESET信号没有被忽略,导致客户端不能与服务端同步握手,浏览还是有问 题,不过,如果服务器段都可以识别并忽略这些伪造的RESET报文,那么两边的通讯就会正常了。
如何忽略防火长城 (忽略我国边境防火墙- – 我的理解)
摘要:所谓“防火长城”之部分工作原理即是检测传输控制协议(TCP)报文中需要封锁的关键词。如果出现关键词,TCP复位报文(即RST标志置位 的报文)即向连接两端发送,连接随之关闭。而原报文完好通过防火墙,如果双方完全忽略防火墙的复位,那么连接仍可顺畅进行而防火墙失效。一旦连接被封锁, 防火墙还会进而尝试封锁双方的继发连接。后种特性可能被利用来对第三方进行拒绝服务攻击。
1 引言
中华人民共和国运行的互联网过滤系统,普遍认为是世界上最复杂的系统之一。[1]其部分工作原理即是检测网络(HTTP)流量判断是否出项特定关键词。[2]这些关键词涉及一些中国政府封杀的组织、不可接受的政治意识形态、不愿讨论的历史事件。[3]
直观判断,关键词封锁发生在连接中国与外界网络的路由器组内部。[4]这些路由器利用基于入侵检测系统(IDS)技术的设备来判断报文内容是否匹配中国政 府制订的过滤规则。[5]如果客户端与服务器的一个连接需要封锁,路由器则会在数据流中注入伪TCP复位报文,于是双方便会断开连接。[6]这种封锁一旦 触发,便会持续数分钟,相同方向上的继发连接都会被伪复位直接打断。
在本文第2节我们将讨论国家阻止其公民访问特定网络内容的方法,以及以往调查者认定的优点和缺点。在第3节我们提供了从中国防火墙系统封锁的连接两端获取 的一组报文。第4节我们提出了这个防火墙的一个模型,来解释我们获得的结果。然后第5节我们将展示,通过忽略防火墙发出的TCP复位我们成功传输了本来应 该被封锁的内容,并讨论为什么这种手段防火墙难以应付。第6节我们展示了防火墙的封锁行为如何可以被利用来对第三方进行拒绝服务攻击。最后在第7节,我们 讨论了这种规避审查的方法的优缺点,并思考了中国以外的网站如何免于封锁降低访问难度,还提出公共政策能怎样鼓励人们规避审查的问题。
2 内容封锁系统
有三种显著的内容封锁手段:报文丢弃、DNS污染、内容检测。研究北威州封锁右翼内容的Dornseif的论文[7],和研究英国电信混合封锁系统封锁恋童癖网站的Clayton[8]的论文,一起确定了以上手段。
2.1 报文丢弃方案
在一种报文丢弃方案中,往特定IP地址的所有流量被全部丢弃,于是网站便无法访问。这种方案费用低廉,易于实施──标准的防火墙和路由器便已提供这些必要 特性。报文丢弃方案有两个主要问题。首先,IP地址列表必须保持最新,如果内容提供者不想让ISP轻易封锁他们的网站,保持更新的困难便暴露出来。[9] 其次,系统会导致“过度封锁”──共用同一IP的其他网站被全部封锁。Edelman调查了过度封锁的潜在程度,发现69.8%的.com、.org 和.net网站与50以上其他网站共用IP。[10](虽然一部分域名只是“停放”在一个普通网页上)其详细数字显示网站共用IP数的连续变化图谱,反映 出在一台主机上尽量多挂网站这种盛行的商业做法。
2.2 DNS污染方案
在一种DNS污染方案中,当用户查询域名服务系统(DNS)将文字的域名转换为数字的IP地址时,可以返回错误的应答或者不返回应答导致用户不能正常访 问。这类方案没有过度封锁的问题,因为禁止访问特定网站不会影响到其他网站。不过,邮件传递也需要DNS查询,如果只是封锁网站而不封锁邮件服务的话,此 类方案实现起来容易出错。Dornseif展示的样本中所有的ISP都至少有一次在实现DNS污染时出错。[11]
2.3 内容检测方案
多数内容检测方案是让所有流量通过一个代理服务器。这个代理通过不提供禁止内容来过滤。这种系统可以做得非常精确,程度可以到屏蔽单个网页或者单个图像而 让其他内容顺利通过。这类基于代理的系统没有普遍使用的原因是,可以应付主干网络或者整个国家网络流量的系统过于昂贵。2004年9月美国宾夕法尼亚州, 要求封锁包含儿童网站的一条州法令以违宪被裁定无效[12]。当初由于经费原因,宾夕法尼亚的ISP采用的是报文丢弃和DNS污染的混合策略,导致的 过度封锁和“前置审核限制”对地区法庭作此裁决起到了相当的作用。不过,基于代理的系统已被部署到若干国家比如沙特阿拉伯[13]、缅甸[14],以及挪 威的一些网络提供商比如Telenor[15]。Clayton研究的英国电信的系统是一种混合设计,利用廉价缓存代理处理特定目标IP的报文。不幸这导 致用户可以逆向工程得到封禁网站的列表,而这些网站提供儿童的非法图像,这违背了此系统的公共政策目标。
进行内容检测的另一种手段则是入侵检测系统(IDS)。IDS设备可以检测通过的网络流量并判断其内容是否可接受。如果需要封禁则会调度邻近的防火墙拦截 报文,或者就中国的情况而言,发送TCP复位报文导致威胁性连接关闭。基于IDS的系统显然比其他方案更灵活,更难规避。Dornseif和 Clayton都对如何规避各种封锁进行了深入探讨。[16]然而如果通信保持清晰不加密不变形到IDS无法辨别的程度,那么无论采取什么规避手 段,IDS方法都能够将其检测出来。[17]
3 中国防火墙如何封锁连接
我们在实验中从英国剑桥(墙外)的若干机器连接了中国内的一个网站(墙内)。当前中国的防火墙系统的工作方式是完全对称的[18]──在两个方向上检测内 容并进行过滤。[19]通过从剑桥的终端发出所有的指令我们完全避免了违反中国法律的可能性。一开始我们以正常模式访问一个中国网页并记录双方的报文流。 接下来我们又发起一次有意触发封禁的请求,观察连接是如何被复位报文关闭的。我们继续“正常”的(不包含触发性词汇的)请求,却发现接下来的连接都意外地 被封锁了。接下来我们将详细描述观测结果。
3.1 复位封锁
刚开始我们只是访问一个普通网页,如预期得到完全正常的返回。如下面的转储报文所示,起始的TCP三次握手 (SYN[20],SYN/ACK[21],ACK[22])之后客户端(此实例中使用了53382端口)向服务端http端口(tcp/80)发出了超 文本传输协议(HTTP)的GET指令获取顶级页面(/),传输正常。我们使用netcat(nc)发出这个请求,没有使用网页浏览器,从而避免了无关细 节。报文用ethereal截取,用一般格式表示出来。
cam(53382) → china(http) [SYN] china(http) → cam(53382) [SYN, ACK] cam(53382) → china(http) [ACK] cam(53382) → china(http) GET / HTTP/1.0 china(http) → cam(53382) HTTP/1.1 200 OK (text/html) …… china(http) → cam(53382) ……其余页面内容 cam(53382) → china(http) [ACK]
……接下来这个页面就完整了。我们发出另一个请求,包含了一小段可能触发封禁的文字,当然这也很快发生了:
cam(54190) → china(http) [SYN] china(http) → cam(54190) [SYN, ACK] TTL=39 cam(54190) → china(http) [ACK] cam(54190) → china(http) GET /?falun HTTP/1.0 china(http) → cam(54190) [RST] TTL=47, seq=1, ack=1 china(http) → cam(54190) [RST] TTL=47, seq=1461, ack=1 china(http) → cam(54190) [RST] TTL=47, seq=4381, ack=1 china(http) → cam(54190) HTTP/1.1 200 OK (text/html) …… cam(54190) → china(http) [RST] TTL=64, seq=25, ack zeroed china(http) → cam(54190) ……其余页面内容 cam(54190) → china(http) [RST] TTL=64, seq=25, ack zeroed china(http) → cam(54190) [RST] TTL=47, seq=2921, ack=25
开头三个复位报文序列号对应了GET报文的序列号+1460和+4380(3 × 1460)。[23]我们认为防火墙发出三个不同的值是想确保发送者接受复位,即使发送者已经从目的地收到了“全长”(1460字节)ACK报文。复位报 文的序列号需要“正确”设定,因为现在多数TCP/IP实现都会严格检查序列号是否落入预期窗口。[24](这个验证序列号的内在漏洞由Watson在 2004年首先提出。[25])
此结果还显示,在连接被打断后仍然收到了从中国机发来的一部分页面。然后剑桥机响应了那两个意外报文,发送了自己的TCP复位。注意它将确认号置零而没有 使用随机初始值的相关值。收到的所有复位报文的TTL[26]都是47,而中国机来的报文的TTL都是39,说明它们来源不同。如果来源的初始值都是 64,这也许说明复位产生的地方距离服务器有8跳(hop)。traceroute显示那是通信从Sprint网络(AS1239)进入中国网通集团网络 (AS9929)后的第二台路由器。
我们也从中国服务器的视角看这次连接封锁:
cam(54190) → china(http) [SYN] TTL=42 china(http) → cam(54190) [SYN, ACK] cam(54190) → china(http) [ACK] TTL=42 cam(54190) → china(http) GET /?falun HTTP/1.0 china(http) → cam(54190) HTTP/1.1 200 OK (text/html) …… china(http) → cam(54190) ……其余页面内容 cam(54190) → china(http) [RST] TTL=61, seq=25, ack=1 cam(54190) → china(http) [RST] TTL=61, seq=1485, ack=1 cam(54190) → china(http) [RST] TTL=61, seq=4405, ack=1 cam(54190) → china(http) [RST] TTL=61, seq=25, ack=1 cam(54190) → china(http) [RST] TTL=61, seq=25, ack=2921 cam(54190) → china(http) [RST] TTL=42, seq=25, ack zeroed cam(54190) → china(http) [RST] TTL=42, seq=25, ack zeroed
我们可以看到,当检测到“坏”报文,防火墙也向中国机发送复位(“[RST]
”)报文,但都在GET报文(以及其响应报文)后面。最后两个复位报文(零确认号)是剑桥机发送的。
其他到中国机的复位(因为有“falun”而生成的)TTL都是61,这意味着它们在3跳以外生成,初始值为64。这跟剑桥观测到的8跳偏移不一样。不过 这说明可能有不止一台设备在生成复位──或者初始值经过调整不是64。我们目前对于观测到的这种不对称性没有确定的解释。
开始三个复位的序列号也设置在一定范围(+25,+1485,+4405)以确保命中,事实上+25报文就已经重置了连接。[27]第四、五个复位报文检查确认号发现,它们可以视作连接重置前中国机成功发送的两个报文的响应。
3.2 直接重置连接
防火墙不仅检测内容,还有其他封锁规则。我们发现,只要进行一次“坏”连接,在短时间内相同两主机之间的所有网络通信在经过检查之前就都被封锁了。前面也是连接被封搜,不过现在开始继发连接也会被封锁了。比如,在上面一例以后立刻继续,我们看到:
cam(54191) → china(http) [SYN] china(http) → cam(54191) [SYN, ACK] TTL=41 cam(54191) → china(http) [ACK] china(http) → cam(54191) [RST] TTL=49, seq=1
复位报文从防火墙而来(也往服务器而去)随之客户端便关闭了连接。如果客户端在复位到达前成功发送GET报文,便会接着收到多个防火墙发来的复位 (即使GET报文是完全无毒的)。接下来便是从服务端来的复位──服务器收到复位后便会立刻在GET到达前关闭连接。由于GET发来时不再存在打开的连 接,服务端便按照协议返回一个复位。值得注意的是,防火墙在SYN阶段(三次握手阶段一)没有试图重置连接,而是等到了SYN/ACK(阶段二)。虽然可 以在客户端一发出SYN就给它复位报文,但只有等到SYN/ACK才能构造出对服务端起作用的有效复位。[28]
在实验中我们发现,节点被阻断通信的时间是可变的。有时候是几分钟,有时候可能是一小时。平均时间大概在20分钟,不过由于观测到时间值有在特定值附近聚 集的显著趋势,我们怀疑不同的防火墙组件有不同的时间延迟设定;这就需要深入理解是到底是谁在处理通信,才能较准确地预测封锁周期。
3.3 其他中国网络的情况
我们获取了中国自治系统(AS)的一个列表,并从中生成了在全球路由表中所有中国子网的列表。[29]然后我们利用了一个修改过的 tcptraceroute,判断出通信是通过哪个AS从国际网络进入中国,并从中得知了中国主干边际网络的实体。结果便 是:AS4134,AS4837,AS7497,AS9800,AS9808,AS9929,AS17622,AS24301和AS24489。然后我们 在各个AS中挑选了样例服务器测试,发现所有网络都有都跟前面描述相似的复位行为(除了AS24489:跨欧亚信息网)。以此我们可以推出:我们的结果正 展示了典型的“防火长城”系统。情况在2006年5月下旬是这样的,但并不一定普遍适用。[30]
4 防火长城的设计
基于以上实验结果,以及中国使用的技术设备类型的描述──比如思科的“安全入侵检测系统”[31]──我们提出以下模型来描述中国防火墙中路由器的工作方式(此模型很符合观测,但仍是推论性的,因为中国的网络提供商没有发布关于这些系统的任何技术规格):
当报文到达路由便被立刻放入适当的向前传输队列。此报文也被送到带外IDS设备进行内容检测。如果IDS(关键词匹配)认为此报文“不好”,那么便为连接两端各生成三个TCP复位报文(有三个不同的序列号)交由路由器传输。[32]
IDS在逻辑上是与路由器分离的,很难从路由传输队列中去除或者延迟“坏”报文。然而发出复位关闭连接是相对简单的。如果路由器相对繁忙,而IDS工作正 常,复位报文会在“坏”报文之前发送;这也是我们在实验中观测到的主要情况,虽然有时候复位报文会拖在后面。复位报文的设定值充分显示出,设计者担心与路 由器相比IDS的拥塞导致“坏”报文跑在复位报文前面。这种设计中如果不发送附加的复位,在繁忙情况下防火墙是无法保证封锁的可靠性的。
一旦IDS检测到需要封锁的行为,它也可以向主路由器添加一条简单的丢弃规则而不发出复位。[33]我们相当怀疑这种做法在主干高速路由器上扩展性差,而在IDS内的封锁简单而廉价。
我们还观测封锁的时长得知,提供防火墙功能的设备不止一个。我们进行了进一步实验,发送256个包含威胁性字串的报文通过防火墙,虽然是从一个机器上发出 的,但将它们的源地址设置分别为256个连续的IP地址值,即中国防火墙会认为这是256个不同机器在发送需要封锁的内容。结果是,我们观测到有时候返回 的复位报文是乱序的。然而现代互联网处理报文基本上是用FIFO(先进先出)队列,[34]那么对于这种失序的最简单解释便是,不同的报文给了不同的 IDS,它们各有各的FIFO队列但在发送复位时负载不一样。可惜我们发现这个实验引起了很多的报文丢失(不是所有的连接都返回了应有的复位报文),不能 对报文失序程度有直观感受。这样我们也没法(通过队列建模)确定平行IDS设备的数量下界。我们计划以后再做这个实验。
4.1 防火墙“状态”
没有证据证明带外IDS设备互相通信,并共享网络连接“状态”的记录。实验表明在一个边际网络触发防火墙不影响通过其他边际网络的通信。
而在“状态”本来应该保留的地方(IDS设备中)却没有关于TCP状态的检查。设备孤立地检查报文,于是将?falun分散到相邻两个报文就足以避免检 测。更有甚者,这些设备对于是否有连接存在也不关注,我们的许多测试中甚至没有进行三次握手打开连接就直接发送GET报文。事实上除了初始检测之后的持续 封锁,没有证据证明IDS设备做了其他什么特别的事情,IDS只是一次检查一个报文而已。
5 有意忽略复位
防火墙完全依赖于终端节点以标准兼容方式实现TCP协议[35],在收到复位报文时中断连接。如上所述,虽然有时候防火墙有点超常,复位报文跑在GET报 文前面结果被仔细验证一番以后丢掉了,不过在下一个报文到达防火墙的时候连接就会被防火墙摧毁所以,总得来说还是没有什么区别。
不过现在考虑如果终端节点不遵守标准然后TCP复位被彻底忽略的情况,我们会想到,即使触发了IDS,防火墙也对HTTP传输没有任何影响。于是我们进行 了深入实验两边的终端节点都忽略TCP复位的情况。这有许多方法可以实现,我们选择设置合适的报文过滤防火墙规则。在Linux可以安装iptables 并使用此命令:
iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP
来丢弃传入的RST置位报文。如果是FreeBSD的ipfw那么命令是这样的:
ipfw add 1000 drop tcp from any to me tcpflags rst in
当双方都丢弃TCP复位时我们发现网页传输确实没有被封锁。在剑桥端检测传输的结果:
cam(55817) → china(http) [SYN] china(http) → cam(55817) [SYN, ACK] TTL=41 cam(55817) → china(http) [ACK] cam(55817) → china(http) GET /?falun HTTP/1.0 china(http) → cam(55817) [RST] TTL=49, seq=1 china(http) → cam(55817) [RST] TTL=49, seq=1 china(http) → cam(55817) [RST] TTL=49, seq=1 china(http) → cam(55817) HTTP/1.1 200 OK (text/html) …… china(http) → cam(55817) ……其余页面内容 cam(55817) → china(http) [ACK] seq=25, ack=2921 china(http) → cam(55817) ……其余页面内容 china(http) → cam(55817) [RST] TTL=49, seq=1461 china(http) → cam(55817) [RST] TTL=49, seq=2921 china(http) → cam(55817) [RST] TTL=49, seq=4381 cam(55817) → china(http) [ACK] seq=25, ack=4381 china(http) → cam(55817) [RST] TTL=49, seq=2921 china(http) → cam(55817) ……其余页面内容 china(http) → cam(55817) ……其余页面内容 cam(55817) → china(http) [ACK] seq=25, ack=7301 china(http) → cam(55817) [RST] TTL=49, seq=5841 china(http) → cam(55817) [RST] TTL=49, seq=7301 china(http) → cam(55817) [RST] TTL=49, seq=4381 china(http) → cam(55817) ……其余页面内容 china(http) → cam(55817) [RST] TTL=49, seq=8761
……接下来这个页面就完整了。网页以正常方式传输,除了中间夹杂一些防火墙的TCP复位报文。由于被完全忽略(一共28个复位),它们对客户端的TCP/IP栈没有任何影响。客户端仍然继续接收网页,正常发送ACK。中国端也能看到类似的正常传输夹杂复位的情形。
这样,只是简单地忽略防火长城发出的报文我们就让它完全失效了!这无疑会让它的实现者大为恼火。
5.1 迷惑封锁
一方面是在连接建立以后通过发出TCP复位来阻断继发连接,另一方面我们也观察到一些防火墙有时还有附加策略。在一些节点(当然是随机的),我们看见了防 火墙发来的伪SYN/ACK报文。显然其序列号是随机而且无效的。如果防火墙的SYN/ACK报文比真报文先到那么连接失效──客户端从伪SYN/ACK 中获取了随机的序列号并发给服务端错误的ACK,于是服务端便返回复位报文,导致客户端关闭连接。实际上,如果客户端发送GET比较快,还会收到一批其他 报文,导致防火墙和服务端的进一步复位:
cam(38104) → china(http) [SYN] china(http) → cam(38104) [SYN, ACK] TTL=105 cam(38104) → china(http) [ACK] cam(38104) → china(http) GET / HTTP/1.0 china(http) → cam(38104) [RST] TTL=45, seq=1 china(http) → cam(38104) [RST] TTL=45, seq=1 china(http) → cam(38104) [SYN, ACK] TTL=37 cam(38104) → china(http) [RST] TTL=64, seq=1 china(http) → cam(38104) [RST] TTL=49, seq=1 china(http) → cam(38104) [RST] TTL=45, seq=3770952438 china(http) → cam(38104) [RST] TTL=45, seq=1 china(http) → cam(38104) [RST] TTL=45, seq=1 china(http) → cam(38104) [RST] TTL=37, seq=1 china(http) → cam(38104) [RST] TTL=37, seq=1
对付这种防火墙的新策略比处理伪复位报文麻烦许多。因为即使客户端忽略了服务端来的(完全真实的)复位,还是会继续错误理解服务端的序列号,导致不 能与服务端同步以完成三次握手打开连接。当然如果有时候防火墙的伪SYN/ACK跑在真报文后面,就会被客户端忽略不造成任何混淆,不过防火墙仍然会坚持 不懈用复位报文来打断连接但是由于复位报文都被忽略了所以也没有用,网页照样显示。
重要的是确定来的两个SYN/ACK报文谁是真的。在样例中我们觉得它们很好区分,防火墙版的TTL值大不相同,没有DF标志,没有TCP选项。这些伪 SYN/ACK在现在为止还是像伪复位一样很好过滤的,防火长城再次失效。另外,由于只有封锁继发连接时才会使用这种策略,那么客户端可以把服务端的 TTL记下来,而防火墙是搞不清该往伪报文里填什么值的。
不过,防火墙越搞越复杂,说不定就能造出没法区分的SYN/ACK报文来了。那客户端直接把第一个收到的SYN/ACK当成防火墙发出的伪报文即可。不过 要是防火墙又来时不时来延时一下才发送伪SYN/ACK(让思维简单的机器通过,打倒思维复杂的机器!)那么这场复杂的“博弈”会升级成更深奥的战略对 决。要注意打开网页常常会有多个连接,那么防火墙即使只是搞掉其中一部分也会觉得有“胜利感”。
一个高效的客户端策略(先决条件是客户端和服务端都丢弃复位报文)是将所有传入SYN/ACK报文视为有效(防火墙以后也许会发好几个过来),然后检查全 部的序列号和确认号直到从服务端收到一个ACK以确认正确的取值。不过这对于像iptables或者ipfw这种简单的报文过滤系统来说太复杂了,超出实 现能力。
新一轮“博弈”也许是防火墙开始针对所有客户端报文伪造ACK。可能客户端可以通过检测从服务端获得的真正RST来看穿防火墙的整个伪连接,于是防火墙连 这些都要开始伪造了──这样下去策略变得不知道有多复杂。不过终端节点确实有优势来最终判断报文是来自(有状态的)对方还是(无状态的)防火墙。要是防火 墙也开始记录“状态”,那么整个主要架构的变化(虽然一定又是一笔巨大的开支)便会带来许多其他可用策略,优势也会决定性地偏向防火墙这边。
可是必须注意到,防火墙的SYN/ACK报文伪造问题不能通过改变服务端的TCP/IP栈来安全地解决。那样的话服务端需要发现客户端持续地响应的那个 “错误”的ACK值并改变自身状态以响应这个从伪SYN/ACK报文中出来的值。但这样就去掉了一个Bellovin记录的重要安全步骤,进而导致恶意主 机伪造源IP地址访问的漏洞。[36]
另外,在可以“嗅探”并伪造报文的对手面前进行安全连接,这在密钥交换协议邻域已经得到充分研究。未决的问题是,如何利用中国防火墙目前的架构性缺陷,通过对现有TCP/IP栈的简单修改来战胜防火长城。
6 拒绝服务攻击
我们前面提到,单个包含?falun之类内容的TCP报文就足以触发节点间至多长达一个小时的封锁。如果伪造源地址,就可以发起(但也是受限的)拒绝服务 (Denial of Service)攻击,阻断特定节点间的通信。不过不同的人有不同的目标,这对某些攻击者来说已经足够。比如,识别并阻止地区政府机构的主机访问 “Windows自动更新”;或者阻止某个部委访问一个联合国网站;或者阻止中国海外使馆访问家乡网站。
我们计算发现,即使是一个人通过单个拨号连接也可以发起相当有效的DoS攻击。这样一个人每秒可以产生大约100个触发性报文,假设封锁时间大约是20分 钟,那么120000对节点便可被永久封锁。当然,现在的DoS攻击几乎不会通过单个拨号方式实现,而是在快得多的网络上以巨大的数量进行。那么 120000便可以乘到你满意。不过防火墙的IDS组件也许没有资源记录如此大量的封锁连接,所以实际的影响要考虑受到此类资源限制的情况。还要注意当 IDS处理DoS攻击的时候它处理其他连接信息的资源就会变少,于是其效用也就暂时降低。
6.1 DoS攻击的限制
进一步实验显示此防火墙的封锁方式比我们迄今为止解释的还要复杂一些;因此DoS攻击的效果不一定有刚才那样说得那么好。
首先,封锁只应用于相似端口上的继发连接。[37]只有端口值前9最高有效位与触发封锁的端口对应时,防火墙才会封锁这一连接,这样的端口每次有128 个。Windows这类系统会连续分配临时端口,于是平均有64个继发连接会被封锁。(有时比如触发封锁的端口是4095那么就不会有继发封锁)反之 OpenBSD之类的系统会随机分配临时端口,于是继发连接被封锁的可能性只有1/500。
我们对防火墙的这种行为没有确定的解释。不看端口直接封锁所有连接似乎还简单有效许多。[38]这么做也许是为了避免误封NAT后面的其他用户,或者是用 来确定发送某报文的IDS。也许这么做只是有意要显得神秘而愈发有威慑力。然而从DoS攻击者的角度,除非有特殊条件可以预测临时端口,要让所有可能端口 段都被封锁所需的报文发送量便增长了500倍。
中国防火墙对“坏”字符串的封锁情况。
2006年二月上旬我们进行了一次10天的试验,每小时一次从256个相邻IP地址进行连接。这里是前128的结果;其余部分模式也十分相似。黑点表明连 接被封锁,白点表明没有封锁,灰点是结果不定(完全没有响应)。在110小时前后可见防火墙策略的显著变化(封锁更多的IP地址)。
其次,并非所有IP地址的流量都被检测过。我们每小时进行一次突发连接,发送一组256个IP地址连续的含有“?falun”的报文。起初每组报文只有约 三分之二被封锁掉,封掉的地址每次不同。不过几天之后几乎所有报文被封锁。我们无法通过逆向工程确定地址选择的算法,不过IP地址选择确有鲜明的模式 [39],暗示背后的机制可能相当简单。最直接的解释是资源匮乏──流量的三分之二也许就是整个系统可以处理的极限。显然某些时候如果一部分机器没有进行 报文检测的工作,DoS攻击也就不可能通过它们发起。
最终需要注意的就是,这些实验只是在中国内外的少量节点上进行的,虽然我们得到了足够一致的结果,但像“防火长城”这种复杂的系统我们还是可能忽略了它的某些重要特性。因此虽然我们认为DoS攻击可以在许多情况下成功,我们也不能保证任一节点对上的任一次攻击都能成功。
7 战略考虑
要让流量顺利通过中国防火墙就必须要求双方忽略复位。“世界其他地方”的机器如果想在中国也能正常访问,只需稍作调整。但在中国这边的人就不那么愿意装一 些特殊软件了。主要问题是防火墙可能做的,不仅是封锁,还有记录。随之而来的可能就是侦查,安装的特殊软件便会被查获,有人便会对你安装此种软件的动机产 生某种看法。
中国防火墙的报文检查功能也可以通过加密的方法规避。如果当局通过对内容的统计分析检测出加密通信,那么安装特殊软件遭到侦查的问题还是一样的。由于加密 系统一般会话结束后便废弃密钥,通信内容还是政治演讲这是无法分辨的。如果用丢弃复位的方法穿墙,防火墙可以通过日志的方法记录封锁触发内容,当局 便可以检查日志并对这两种通信采取不同措施。这两种方法相比有人觉得丢弃复位法更有优势。
如果复位丢弃广泛以毫不相关的理由应用,中国政府可能不得不对复位丢弃软件采取更加容忍的态度。
关于软件防火墙的一些研究指出如果例行丢弃TCP复位会产生一些副作用。[40]复位报文主要是用来快速报告不受欢迎的传入连接。如果远端机工作良好,那么忽略报文而不响应复位只会产生稍微多一点的流量。
然而,对于不想丢掉所有的TCP复位的人来说,当然这里也有另一种策略。[41]目前TTL校验就是一种检测复位报文真伪的简单方法。特别地,我们注意到 Watson提出的通过第三方伪复位造成连接关闭的复位攻击[42],通常的防御手段是仔细验证序列号。如果再加上复位报文的TTL校验,就可以更好地识 别伪复位。本文作者之一编写了一段20行的FreeBDS补丁[43],可以丢弃TTL值严重偏离的复位报文。到现在用户体验都很好。其他操作系统和个人 防火墙大概也不会觉得添加这个功能很麻烦。
当然,中国防火墙也可以改进,让前面提及的规避方法难以实现。特别是它可以较容易地构造正确TTL的复位报文发往触发报文的相同方向。不过要想获得相反方 向的正确TTL就不大容易了,因为网络路由基本上是非对称的,防火墙不能透视通信的两个方向。更复杂的方法是将报文从路由队列中移除(或者延迟到内容检测 完成才放行)。除非报文在抵达终点前被阻止,我们的基本策略──无视防火墙发出的噪音──将继续有效。
另一套完全不同的防火墙策略则是当封禁被触发后不向该站点转发任何报文。不过我们前面提到此法扩展性极差,因为完成这个“内联”过程需要路由器间的快速通路──而且,全面的封锁无疑增加了DoS攻击的威力。
7.1 打破“防火长城”的公共政策动力
特别是在美国,有相当的政治利益关心着中国之外的公司如何帮助中国政府压制信息、锁定持不同政见者和异见网志作者。特别地,在2006年2月的一次国会听 证会上,相当数量的美国大型公司由于其政策和行为而受到了严厉谴责。[44]不过对于如何绕开中国的过滤技术现在也有更多的关注。比如由CIA部分资助的 SafeWeb,在2000到2003年运营了一个匿名网络代理,同时它还开发出一种昵称TriangleBoy的反审查技术。[45]2006下半年发 起的加拿大的Psiphon计划旨在让“不受审查国家的公民向在他们防火墙背后的朋友和家人提供自由的网络连接”。[46]
可以预测本文所描述的通过忽略复位报文规避中国防火墙的方法也会引起相当的兴趣。当然也会有“军备竞赛”的危险,所以双方采取的策略可能复杂得多。让防火 墙立刻失效方法也是相当直接的;不过实现这个方案需要中国外的服务器和中国内的浏览器同时丢弃复位。服务器一方显然会有动力去实现复位丢弃,因为这样就让 在中国的人可以访问。不过要是看看中国国内的情形和人们改变浏览器(或者操作系统)配置的动力就会知道事情远比这复杂得多。虽然都是运行在中国的机器上, 这些软件却都是在中国以外开发,特别是大多数软件都安装在微软开发的Windows上。
我们这里提出一个关于公共政策的问题:是否应该鼓励或者强制微软修改程序以帮助规避中国防火墙?显然对于中国的审查有着广泛谴责,那么反审查措施当然会得 到政治意见和公共意见的赞同。[47]在本节前面我们提到,对这种改进的技术性反对意见是很有限的,这种改进可以提升对第三方攻击(防火墙只是第三方干涉 网络通信的特例)的防御安全性。然而微软(以及其他操作系统和浏览器开发商)很可能不愿意冒犯中国政府,那么在被强制之前他们会一直拖下去。
一般的常识便是软件容易修改,硬件不易修改。不过把硬件改动的时间与制订新法规的时间相比就会知道,在强制供应商提供规避防火墙功能的法律生效之前,中国 政府就会采用新的封锁硬件。[48]可以推测,新的硬件会考虑到我们提到的问题并对复位丢弃免疫。因此我们认为通过立法(强制供应商)并不是实用的办法, 除非立法是普遍意义上的、不关注技术细节的。让供应商少去讨好中国政府多关心其他所有人,这才是最现实的道路。
8 结论
本文我们展示了基于报文内容检测的“防火长城”。当过滤规则触发时,伪复位报文便发向TCP连接两方。然而真正的报文亦完好通过防火墙,于是通过忽略这些 复位,通信便不受干扰。相同方向上的继发连接也被封锁(只有在端口相关的情况下),不过通过忽略复位通信仍可以顺畅继续。
以上结果对于中国当局具有相当的意义,他们也许会加强他们的系统、修补防火墙的漏洞。当然我们在前面也说,这并不容易。[49]然而对于希望自由访问网络 的中国居民来说,以上结果意义就小得多,因为他们的活动仍然受到记录和监视。只有当丢弃复位报文成为普遍做法以后,人们的才能说他们是无意中翻墙的。这种 想法也不能算离谱,因为验证TCP复位是否为伪造也是TCP/IP栈应该做的。
我们还展示了封锁的副作用:为DoS攻击提供了可能性。当然这种DoS攻击只能用在特定节点之间。利用一套封锁机制来封锁什么东西这本身并没什么新意,但如果防火墙不作足够的状态记录,我们也看不到避免这种攻击的简便方法。
我们展示的结果也关系到其他使用类似复位机制来保护自身利益的国家、机构、企业。他们应该谨慎地认识到这种封锁完全依赖于被封锁者的默许。一些相对中国来说的小国家会经受更大的DoS攻击风险,因为他们的终端节点要少得多,防火墙在攻击效果变得显著之前尚不会过载。
9 补记
2007年春另外一组研究者(Jedidiah R. Crandall和其他人的“ConceptDoppler”项目)[50]的一些实验也揭露了这个防火墙的工作细节,但复位机制是基本不变的。不过他们 的测量表明复位现在开始发生在中国互联网的内部,不仅是边际路由器;且与我们一年前观察到的相比封锁在繁忙时段变得更加断断续续。他们的研究手段也让他们 可以发表一份关于被过滤话题的统计列表。