2017年10月24日星期二

全面学习GFW

全面学习GFW


GFW会是一个长期的存在。要学会与之共存,必须先了解GFW是什么。做为局外人,学习GFW有六个角度。渐进的来看分别是:
首先我们学习到的是WHAT和WHEN。比如说,你经常听到人的议论是“昨天”,“github”被封了。其中的昨天就是WHEN,github就是WHAT。这是学习GFW的最天然,最朴素的角度。在这个方面做得非常极致的是一个叫做greatfire的网站。这个网站长期监控成千上万个网站和关键词。通过长期监控,不但可以掌握WHAT被封锁了,还可以知道WHEN被封的,WHEN被解封的。
接下来的角度是WHO。比如说,“方校长”这个人名就经常和GFW同时出现。但是如果仅仅是掌握一个两个人名,然后像某位同志那样天天在twitter上骂一遍那样,除了把这个人名骂成名人之外,没有什么特别的积极意义。我更看好这篇文章“通过分析论文挖掘防火长城(GFW)的技术人员”的思路。通过网络上的公开信息,掌握GFW的哪些方面与哪些人有关系,这些合作者之间又有什么联系。除了大家猜测的将来可以鞭尸之外,对现在也是有积极的意义的。比如关注这些人的研究动态和思想发展,可以猜测GFW的下一步发展方向。比如阅读过去发表的论文,可以了解GFW的技术演进历史,可以从历史中找到一些技术或者管理体制上的缺陷。
再接下来就是WHY了。github被封之后就常听人说,github这样的技术网站你封它干啥?是什么原因促成了一个网站的被封与解封的?我们做为局外人,真正的原因当然是无从得知的。但是我们可以猜测。基于猜测,可以把不同网站被封,与网络上的舆情时间做关联和分类。我们知道,方校长对于网路舆情监控是有很深入研究的。有一篇论文(Whiskey, Weed, and Wukan on the World Wide Web: On Measuring Censors’ Resources and Motivations)专门讨论监管者的动机的。观测触发被封的事件与实际被封之间的时间关系,也可以推测出一些有趣的现象。比如有人报告,OpenVPN触发的封端口和封IP这样的事情一般都发生在中国的白天。也就是说,GFW背后不光是机器,有一些组件是血肉构成的。
剩下的两个角度就是对如何翻墙穿墙最有价值的两个角度了:HOW和WHERE。HOW是非常好理解的,就是在服务器和客户端两边抓包,看看一个正常的网络通信,GFW做为中间人,分别给两端在什么时候发了什么包或者过滤掉了什么包。而这些GFW做的动作,无论是过滤还是发伪包又是如何干扰客户端与服务器之间的正常通信的。WHERE是在知道了HOW之后的进一步发展,不但要了解客户端与服务器这两端的情况,更要了解GFW是挂在两端中间的哪一级路由器上做干扰的。在了解到GFW的关联路由器的IP的基础上,可以根据不同的干扰行为,不同的运营商归属做分组,进一步了解GFW的整体部署情况。
整体上来说,对GFW的研究都是从WHAT和WHEN开始,让偏人文的就去研究WHO和WHY,像我们这样偏工程的就会去研究HOW和WHERE。以上就是全面了解GFW的主体脉络。接下来,我们就要以HOW和WHERE这两个角度去看一看GFW的原理。

GFW的原理

要与GFW对抗不能仅仅停留在什么不能访问了,什么可以访问之类的表面现象上。知道youtube不能访问了,对于翻墙来说并无帮助。但是知道GFW是如何让我们不能访问youtube的,则对下一步的翻墙方案的选择和实施具有重大意义。所以在讨论如何翻之前,先要深入原理了解GFW是如何封的。
总的来说,GFW是一个分布式的入侵检测系统,并不是一个严格意义上的防火墙。不是说每个出入国境的IP包都需要先经过GFW的首可。做为一个入侵检测系统,GFW把你每一次访问facebook都看做一次入侵,然后在检测到入侵之后采取应对措施,也就是常见的连接重置。整个过程一般话来说就是:
检测有两种方式。一种是人工检测,一种是机器检测。你去国新办网站举报,就是参与了人工检测。在人工检测到不和谐的网站之后,就会采取一些应对方式来防止国内的网民访问该网站。对于这类的封锁,规避检测就不是技术问题了,只能从GFW采取的应对方式上采取反制措施。另外一类检测是机器检测,其检测过程又可以再进一步细分:

重建


重建是指GFW从网络上监听过往的IP包,然后分析其中的TCP协议,最后重建出一个完整的字节流。分析是在这个重建的字节流上分析具体的应用协议,比如HTTP协议。然后在应用协议中查找是不是有不和谐的内容,然后决定采用何种应对方式。
所以,GFW机器检测的第一步就是重建出一个字节流。那么GFW是如何拿到原始的IP包的呢?真正的GFW部署方式,外人根本无从得知。据猜测,GFW是部署在国家的出口路由器的旁路上,用“分光”的方式把IP包复制一份到另外一根光纤上,从而拿到所有进出国境的IP包。下图引在gfwrev.blogspot.com:
但是Google在北京有自己的机房。所以聪明的网友就使用Google的北京机房提供的GAE服务,用Goagent软件达到高速翻墙的目的。但是有网友证实(https://twitter.com/chengr28/status/260970749190365184),即便是北京的机房也会被骨干网丢包。事实上Google在北京的谷翔机房有一个独立的AS(BGP的概念)。这个AS与谷歌总部有一条IPV6的直连线路,所以通过这个机房可以用IPV6不受墙的限制出去。但是这个AS无论是连接国内还是国外都是要经过GFW的。所以机房在北京也不能保证国内访问不被墙。GFW通过配置骨干网的BGP路由规则,是可以让国内的机房也经过它的。另外一个例子是当我们访问被封的网站触发连接重置的时候,往往收到两个RST包,但是TTL不同。还有一个例子是对于被封的IP,访问的IP包还没有到达国际出口就已经被丢弃。所以GFW应该在其他地方也部署有设备,据推测是在省级骨干路由的位置。
对于GFW到底在哪这个话题,最近又有国外友人表达了兴趣(https://github.com/mothran/mongol)。笔者在前人的基础上写了一个更完备的探测工具https://github.com/fqrouter/qiang。其原理是基于一个IP协议的特性叫TTL。TTL是Time to Live的简写。IP包在没经过一次路由的时候,路由器都会把IP包的TTL减去1。如果TTL到零了,路由器就不会再把IP包发给下一级路由。然后我们知道GFW会在监听到不和谐的IP包之后发回RST包来重置TCP连接。那么通过设置不同的TTL就可以知道从你的电脑,到GFW之间经过了几个路由器。比如说TTL设置成9不触发RST,但是10就触发RST,那么到GFW就是经过了10个路由器。另外一个IP协议的特性是当TTL耗尽的时候,路由器应该发回一个TTL EXCEEDED的ICMP包,并把自己的IP地址设置成SRC(来源)。结合这两点,就可以探测出IP包是到了IP地址为什么的路由器之后才被GFW检测到。有了IP地址之后,再结合IP地址地理位置的数据库就可以知道其地理位置。据说,得出的位置大概是这样的:
但是这里检测出来的IP到底是GFW的还是骨干路由器的?更有可能的是骨干路由器的IP。GFW做为一个设备用“分光”的方式挂在主干路由器旁边做入侵检测。无论如何,GFW通过某种神奇的方式,可以拿到你和国外服务器之间来往的所有的IP包,这点是肯定的。更严谨的理论研究有:Internet Censorship in China: Where Does the Filtering Occur?
GFW在拥有了这些IP包之后,要做一个艰难的决定,那就是到底要不要让你和服务器之间的通信继续下去。GFW不能太过于激进,毕竟全国性的不能访问国外的网站是违反GFW自身存在价值的。GFW就需要在理解了IP包背后代表的含义之后,再来决定是不是可以安全的阻断你和国外服务器之间的连接。这种理解就要建立了前面说的“重建”这一步的基础上。大概用图表达一下重建是在怎么一回事:
重建需要做的事情就是把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协议,访问的是什么网站。
重建这样的字节流有一个难点是如何处理巨大的流量?这个问题在这篇博客(http://gfwrev.blogspot.tw/2010/02/gfw.html)中已经讲得很明白了。其原理与网站的负载均衡器一样。对于给定的来源和目标,使用一个HASH算法取得一个节点值,然后把所有符合这个来源和目标的流量都往这个节点发。所以在一个节点上就可以重建一个TCP会话的单向字节流。
最后为了讨论完整,再提两点。虽然GFW的重建发生在旁路上是基于分光来实现的,但并不代表整个GFW的所有设备都在旁路。后面会提到有一些GFW应对形式必须是把一些GFW的设备部署在了主干路由上,比如对Google的HTTPS的间歇性丢包,也就是GFW是要参与部分IP的路由工作的。另外一点是,重建是单向的TCP流,也就是GFW根本不在乎双向的对话内容,它只根据监听到的一个方向的内容然后做判断。但是监听本身是双向的,也就是无论是从国内发到国外,还是从国外发到国内,都会被重建然后加以分析。所以一个TCP连接对于GFW来说会被重建成两个字节流。具体的证据会在后面谈如何直穿GFW中详细讲解。

分析

分析是GFW在重建出字节流之后要做的第二步。对于重建来说,GFW主要处理IP协议,以及上一层的TCP和UDP协议就可以了。但是对于分析来说,GFW就需要理解各种各样的应用层的稀奇古怪的协议了。甚至,我们也可以自己发明新的协议。
总的来说,GFW做协议分析有两个相似,但是不同的目的。第一个目的是防止不和谐内容的传播,比如说使用Google搜索了“不该”搜索的关键字。第二个目的是防止使用翻墙工具绕过GFW的审查。下面列举一些已知的GFW能够处理的协议。
对于GFW具体是怎么达到目的一,也就是防止不和谐内容传播的就牵涉到对HTTP协议和DNS协议等几个协议的明文审查。大体的做法是这样的。
像HTTP这样的协议会有非常明显的特征供检测,所以第一步就没什么好说的了。当GFW发现了包是HTTP的包之后就会按照HTTP的协议规则拆包。这个拆包过程是GFW按照它对于协议的理解来做的。比如说,从HTTP的GET请求中取得请求的URL。然后GFW拿到这个请求的URL去与关键字做匹配,比如查找Twitter是否在请求的URL中。为什么有拆包这个过程?首先,拆包之后可以更精确的打击,防止误杀。另外可能预先做拆包,比全文匹配更节省资源。其次,xiaoxia和liruqi同学的jjproxy的核心就是基于GFW的一个HTTP拆包的漏洞,当然这个bug已经被修复了。其原理就是GFW在拆解HTTP包的时候没有处理有多出来的rn这样的情况,但是你访问的google.com却可以正确处理额外的rn的情况。从这个例子中可以证明,GFW还是先去理解协议,然后才做关键字匹配的。关键字匹配应该就是使用了一些高效的正则表达式算法,没有什么可以讨论的。
HTTP代理和SOCKS代理,这两种明文的代理都可以被GFW识别。之前笔者认为GFW可以在识别到HTTP代理和SOCKS代理之后,再拆解其内部的HTTP协议的正文。也就是做两次拆包。但是分析发现,HTTP代理的关键字列表和HTTP的关键字列表是不一样的,所以笔者现在认为HTTP代理协议和SOCKS代理协议是当作单独的协议来处理的,并不是拆出载荷的HTTP请求再进行分析的。
目前已知的GFW会做的协议分析如下:

DNS 查询

GFW可以分析53端口的UDP协议的DNS查询。如果查询的域名匹配关键字则会被DNS劫持。可以肯定的是,这个匹配过程使用的是类似正则的机制,而不仅仅是一个黑名单,因为子域名实在太多了。证据是:2012年11月9日下午3点半开始,防火长城对Google的泛域名 .google.com 进行了大面积的污染,所有以 .google.com 结尾的域名均遭到污染而解析错误不能正常访问,其中甚至包括不存在的域名(来源http://zh.wikipedia.org/wiki/%E5%9F%9F%E5%90%8D%E5%8A%AB%E6%8C%81
目前为止53端口之外的查询也没有被劫持。但是TCP的DNS查询已经可以被TCP RST切断了,表明了GFW具有这样的能力,只是不屑于大规模部署。而且TCP查询的关键字比UDP劫持的域名要少的多。目前只有dl.dropbox.com会触发TCP RST。相关的研究论文有:

HTTP 请求

GFW可以识别出HTTP协议,并且检查GET的URL与HOST。如果匹配了关键字则会触发TCP RST阻断。前面提到了jjproxy使用的构造特殊的HTTP GET请求欺骗GFW的做法已经失效,现在GFW只要看到rn就直接TCP RST阻断了(来源u/0/108661470402896863593/posts/6U6Q492M3yY)。相关的研究论文有:

HTTP 响应

GFW除了会分析上行的HTTP GET请求,对于HTTP返回的内容也会做全文关键字检查。这种检查与对请求的关键字检查不是由同一设备完成的,而且对GFW的资源消耗也更大。相关的研究论文有:

HTTP代理协议

TODO

SOCKS4/5代理协议

TODO

SMTP 协议

因为有很多翻墙软件都是以邮件索取下载地址的方式发布的,所以GFW有针对性的封锁了SMTP协议,阻止这样的邮件往来。
封锁有三种表现方式(http://fqrouter.tumblr.com/post/43400982633/gfw-smtp),简单概要的说就是看邮件是不是发往上了黑名单的邮件地址的(比如xiazai@upup.info就是一个上了黑名单的邮件地址),如果发现了就立马用TCP RST包切断连接。

电驴(ed2k)协议

GFW还会过滤电驴(ed2k)协议中的查询内容。因为ed2k还有一个混淆模式,会加密往来的数据包,GFW会切断所有使用混淆模式的ed2k连接,迫使客户端使用明文与服务器通讯(http://fqrouter.tumblr.com/post/43490772120/gfw-ed2k)。然后如果客户端发起了搜索请求,查找的关键字中包含敏感词的话就会被用TCP RST包切断连接。

对翻墙流量的分析识别

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根本不在乎加密的流量中的具体内容是不是有敏感词。只要疑似翻墙,特别是提供商业服务给多个翻墙,就会被封杀。根据这个帖子(http://www.v2ex.com/t/55531),使用的ShadowSocks协议。预先部署密钥,没有明显的握手过程仍然被封。据说是GFW已经升级为能够机器识别出哪些加密的流量是疑似翻墙服务的。
关于GFW是如何识别与封锁翻墙服务器的,最近写了一篇文章提出我的猜想,大家可以去看看:http://fqrouter.tumblr.com/post/45969604783/gfw。
最近发现GFW对OpenVPN和SSL证书已经可以做到准实时的封IP(端口)。原理应该是离线做的深包分析,然后提取出可疑的IP列表,经过人工确认之后封IP。因为OpenVPN有显著的协议的特征,而且基本不用于商业场景所以很容易确认是翻墙服务。但是SSL也就是HTTPS用的加密协议也能基于“证书”做过滤不得不令人感到敬畏了。Shadowsocks的作者Clowwindy为此专门撰文“为什么不应该用SSL翻墙“:https://gist.github.com/clowwindy/5947691
总结起来就是,GFW已经基本上完成了目的一的所有工作。明文的协议从HTTP到SMTP都可以分析然后关键字检测,甚至电驴这样不是那么大众的协议GFW都去搞了。从原理上来说也没有什么好研究的,就是明文,拆包,关键字。GFW显然近期的工作重心在分析网络流量上,从中识别出哪些是翻墙的流量。这方面的研究还比较少,而且一个显著的特征是自己用没关系,大规模部署就容易出问题。我目前没有在GFW是如何封翻墙工具上有太多研究,只能是道听途说了。

应对

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 RST阻断

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的自动应对行为,而是采取黑名单加人工过滤地方式实现的。一个推断的理由就是网友报道,封端口都是发生在白天工作时间。
在进入了封端口阶段之后,还会有继发性的临时性封其他端口的现象,但是这些继发性的封锁具有明显的超时时间,触发了之后(触发条件不是非常明确)会立即被封锁,然后过了一段时间就自动解封。目前对于这一波封SSH/OPENVPN采用的以封端口为明显特征的封锁方式研究尚不深入。可以参考我最近写的一篇文章:http://fqrouter.tumblr.com/post/45969604783/gfw

HTTPS间歇性丢包

对于Google的HTTPS服务,GFW不愿意让其完全不能访问。所以采取的办法是对于Google的某些IP的443端口采取间歇性丢包的措施。其原理应该类似于封端口,是在骨干路由器上做的丢包动作。但是触发条件并不只是看IP和端口,加上了时间间隔这样一个条件。

2017年10月19日星期四

方滨兴等研究如何识别Tor的混淆插件

前北邮校长方滨兴等人在《计算机研究与发展》上发表论文《匿名通信系统不可观测性度量方法》(PDF),报告他们能通过观察Tor混淆插件的流量模式将其识别出来。

为了躲避深度包检查,研究人员开发出了协议混淆工具,Tor匿名网络开发的传输层协议混淆插件包括obfsprox(obfsproxy3和obfsproxy4),meek和fte等。研究人员从Tor官网下载软件,对传输流量进行一番研究后很快发现Tor的混淆插件容易受到时间分析攻击。

他们发现,meek、网桥和HTTPS的流量数据包内部时间间隔基本相同,但meek的数据包在0.5-2秒附近有一个明显的抖动,原因是meek客户端为了与云平台保持长连接而自动在空闲时发送一个心跳包,心跳包是随机在0.1秒-5秒之间选择一个值。他们还观察到了其它两个数据模式:网桥模式下数据包大小在600B附近比较集中,原因也与Tor的数据包设计有关;meek模式下客户端到服务数据包大小在200B左右,服务器到客户端400B左右。


来源:

http://www.solidot.org/story?sid=46354

2017年10月17日星期二

如何忽略防火長城

簡介:本文從TCP/IP協議安全性的角度對中國防火牆系統的工作原理、工作特性和潛在的漏洞、造成的問題進行了詳盡的調查和分析,並從多個角度提出了針對特別是防火長城這類利用TCP/IP協議進行攻擊的反制措施。

如何忽略防火長城

Richard Clayton, Steven J. Murdoch, and Robert N. M. Watson*
University of Cambridge, Computer Laboratory, William Gates Building, 15 JJ Thomson Avenue, Cambridge CB3 0FD, United Kingdom
{richard.clayton, steven.murdoch, robert.watson}@cl.cam.ac.uk

* 致謝:我們感謝一位中國公民的幫助。(我們不會透露他的名字,他對我們實驗的本質完全不知情,他的網頁也不包含任何非法內容)他爲我們理論思考提供了極爲可信的實踐材料。Richard Clayton正爲Intel Research資助的spamHINTS項目工作。Steven J. Murdoch由OpenNet Initiative資助。
摘要:所謂“防火長城”之部分工作原理即是檢測傳輸控制協議(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<cr><lf><cr><lf>
china(http) → cam(53382) HTTP/1.1 200 OK (text/html)<cr><lf> ……
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<cr><lf><cr><lf>
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)<cr><lf> ……
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<cr><lf><cr><lf>
china(http) → cam(54190) HTTP/1.1 200 OK (text/html)<cr><lf> ……
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那麽命令是這樣的:
pfw 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<cr><lf><cr><lf>
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)<cr><lf> ……
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<cr><lf><cr><lf>
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倍。

图1:中国防火墙对“坏”字符串的封锁情况。
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]的一些實驗也揭露了這個防火牆的工作細節,但複位機制是基本不變的。不過他們的測量表明複位現在開始發生在中國互聯網的內部,不僅是邊際路由器;且與我們一年前觀察到的相比封鎖在繁忙時段變得更加斷斷續續。他們的研究手段也讓他們可以發表一份關于被過濾話題的統計列表。


注釋
    * [1] OpenNet Initiative, “Internet Filtering in China in 2004–2005: A Country Study,” OpenNet Initiative, http://www.opennetinitiative.net/studies/china/ONI_China_Country_Study.pdf (accessed October 21, 2007).
    * [2] OpenNet Initiative, “Probing Chinese Search Engine Filtering,” OpenNet Initiative: Bulletin 005, http://www.opennetinitiative.net/bulletins/005/ (accessed October 15, 2007).
    * [3] Ronald J. Deibert and others, eds., Access Denied: The Practice and Policy of Global Internet Filtering (Cambridge: MIT Press, 2007).
    * [4] Nart Villeneuve, “Censorship is in the Router,” June 3, 2005, http://ice.citizenlab.org/?p=113 (accessed October 15, 2007).
    * [5] OpenNet Initiative, “Probing Chinese Search Engine Filtering.”
    * [6] RST標志置位的TCP報文。這種報文表明一方要求立即關閉當前連接不再傳輸。
    * [7] See Maximillian Dornseif, “Government Mandated Blocking of Foreign Web Content,” Security, E-Learning, E-Services: Proceedings of the 17 DFN-Arbeitstagung über Kommunikationsnetze, eds. Jan van Knop, Wilhelm Haverkamp, Eike Jessen, 617–646 (Dusseldorf, Germany: GI, 2004).
    * [8] Richard Clayton, “Failures in a Hybrid Content Blocking System,” in Privacy Enhancing Technologies: 5th International Workshop Cavtat, Croatia, May 30-June 1, 2005 (Berlin, Germany: Springer, 2006): 78–92.
    * [9] Richard Clayton, “Anonymity and Traceability in Cyberspace,” Technical Report (2005), http://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-653.pdf (for details of the complexity, see the extensive discussion in “Anonymity and Traceability in Cyberspace”) (accessed October 15, 2007).
    * [10] Benjamin Edelman, “Web Sites Sharing IP Addresses: Prevalence and Significance,” Berkman Center for Internet & Society, http://cyber.law.harvard.edu/people/edelman/ip-sharing (accessed October 15, 2007).
    * [11] Dornseif, “Government Mandated Blocking,” 626–27.
    * [12] Center for Democracy & Technology v. Pappert, 337 F. Supp. 2d 606 (E.D. Penn. 2004).
    * [13] King Abdulaziz City for Science and Technology: Local Content Filtering Procedure. Internet Services Unit (2004), http://www.isu.net.sa/saudi-internet/contenet-filtring/filtring-mechanism.htm (accessed October 15, 2007).
    * [14] OpenNet Initiative, “Internet Filtering in Burma in 2005: A Country Study,” OpenNet Initiative, http://www.opennetinitiative.net/burma/ONI_Burma_Country_Study.pdf (accessed October 15, 2007).
    * [15] Telenor, “Telenor and KRIPOS Introduce Internet Child Pornography Filter,” press release, September 21, 2004, http://presse.telenor.no/PR/200409/961319_5.html (accessed October 15, 2007).
    * [16] Dornseif, “Government Mandated Blocking,” 642-44; Clayton, “Failures in a Hybrid Content Blocking System,” 78–92.
    * [17] IDS可以將多種不規則的表現轉化爲標准形式,然後與封鎖列表比對作出正確決策。
    * [18] 這種對稱必須存在,因爲防火牆需要同時封禁網絡請求和回應。
    * [19] Villeneuve, “Censorship is in the Router.”
    * [20] SYN(同步)標志標明了打開TCP連接時的第一個報文。
    * [21] 這是對SYN報文的回應,其SYN和ACK(確認)置位,用“SYN/ACK”來表示在TCP連接打開過程中的第二個報文。
    * [22] 關于TCP的准確細節,和發起連接時交換SYN、SYN/ACK和ACK置位報文的方法原因,可以查閱很多好的網絡通信教材,比如W. Richard Stevens, TCP/IP Illustrated, Volume 1, The Protocols (Reading, MA: Addison-Wesley, 1994)。
    * [23] 當我們啓用TCP時間戳且報文包含12字節TCP附加選項的時候,這個值變成1448的倍數。
    * [24] TCP對所有數據報文用序列號進行標記,指示報文包含數據的順序。當報文丟失、延遲或重複時,可以靠序列號來重建數據流。“窗口”是指在沒有收到確認時最多可以發送的數據量。現在的互聯網中,檢查序列號落入窗口(複位報文序列號符合預期)是避免第三方幹擾連接的重要安全措施。
    * [25] Paul A. Watson, “Slipping in the Window: TCP Reset Attacks,” Open Source Vulnerability Database, http://osvdb.org/reference/SlippingInTheWindow_v1.0.doc (accessed October 15, 2007).
    * [26] 存活時間(TTL)初始值由報文發送者確定,通過一個路由就減一。這是爲了確保報文不在路由間無窮循環,當TTL爲零時報文就被丟棄了。于是通過校驗TTL值可以推算報文走過的距離。
    * [27] 如果複位在GET報文之前到達,則此複位報文不會被接受。服務器是FreeBSD系統,在連接的這個階段,TCP棧接受的複位的序列號必須精確匹配上次發送的確認的值,以防止拒絕服務攻擊。在GET報文到達前其值爲+1,于是這時所有的複位都是無效的。
    * [28] SYN/ACK報文含有連接雙方選定的序列號。
    * [29] AS指特定ISP擁有的骨幹網絡。我們采用的是CERNET的“China ASN List”,http://bgpview.6test.edu.cn/bgp-view/cur_ana/ipv4cn /china_asnlist.shtml。互聯網路由器保存有優化路徑列表,而“全球路由表”表達了特定AS對地址的所有權。
    * [30] See Jedidiah R. Crandall and others, “ConceptDoppler: A Weather Tracker for Internet Censorship” (14th ACM Conference on Computer and Communications Security, Alexandria, VA, October 29–November 2, 2007) http://www.cs.unm.edu/~crandall/concept_doppler_ccs07.pdf (accessed October 15, 2007).
    * [31] Earl Carter, Secure Intrusion Detection Systems (Indianapolis: Cisco Press, 2001).
    * [32] 即,檢測報文內容的設備是在實際連接“旁邊的”于是只能檢測“壞”流量而不能對其有任何直接影響。
    * [33] 路由器一般都有根據特定標准進行報文過濾的功能。
    * [34] Yi Wang, Guohan Lu, and Xing Li, “A Study of Internet Packet Reordering,” Information Networking (Heidelberg, Germany: Springer-Berlin, 2004): 350–359.
    * [35] J. Postel, ed., “Transmission Control Protocol, DARPA Internet Program Protocol Specification” (memo, Network Working Group Request for Comments, September 1981) http://www.ietf.org/rfc/rfc793.txt (accessed October 21, 2007).
    * [36] S. Bellovin, memorandum, May 1996, in Network Working Group Request for Comments, “Defending Against Sequence Number Attacks,” http://www.ietf.org/rfc/rfc1948.txt (accessed October 15, 2007).
    * [37] ──譯注,此節所述似已過時。在翻譯完成的時候譯者測試發現,繼發封鎖跟初始端口或者繼發端口沒有關系,所有端口的繼發連接都被屏蔽。
    * [38] HTTP通信不僅在80端口(tcp/http)上被封鎖,還有其他一些端口也受到影響。不過一個端口被封不影響其他鄰近端口,比如80端口被封不影響433端口(tcp/https)。
    * [39] 見圖1。
    * [40] See Clayton, “Anonymity and Traceability,” 81.
    * [41] 未來中國的防火牆還可能通過FIN報文來打斷連接,然而忽略所有FIN報文則會導致不能正常連接,到那時TTL校驗法會更好。
    * [42] Watson, “Slipping in the Window.”
    * [43] Robert N. M. Watson, “Patches Associated with My Academic Research,” http://www.cl.cam.ac.uk/~rnw24/patches (accessed October 15, 2007).
    * [44] Suzanne Goldenberg, “Congress Accuses Google of Collusion,” The Guardian, February 16, 2006, http://www.guardian.co.uk/china/story/0,,1710616,00.html (accessed October 15, 2007).
    * [45] SafeWeb, “TriangleBoy Whitepaper,” SafeWeb, 2003, http://web.archive.org/web/20030417171335/http://www.safeweb.com/tboy_whitepaper.html (accessed October 15, 2007).
    * [46] Psiphon, http://psiphon.civisec.org (accessed October 15, 2007).
    * [47] Stokely Baksh, “US Calls for Fall of Great Firewall,” United Press International, February 15, 2006; Kate Allen, “Today, Our Chance to Fight a New Hi-Tech Tyranny,” Observer, May 28, 2006; Cory Doctorow, “See No Evil?,” Guardian, July 6, 2007.opinion. 47
    * [48] “此法案是近年來孕育期最長的。導致此法案産生的斯科特報告是在五年半前的1996年2月發表的。保守黨政府接受了此報告的提議並立即發出了資訊文書。工人黨1997年的宣言堅定承諾要采取行動。于是1998年出了那本白皮書。不過之後政府就不聞不問于是,過了三年此法案才推出。”Hansard Parliamentary Debates, Commons, 6th ser., vol. 374 (2001), col. 457.
    * [49] 本文中描述的實驗都是在2006年春進行的,本文的初始版發表在2006年6月的隱私增強技術研討會上。
    * [50] ──譯注:見http://www.conceptdoppler.org/。

传说中的性能测试

一直都有人问 V2Ray 的性能问题,一直都很无奈因为没有人测过。被问得烦了,现在给一个比较科学,比较准确的结论。

本次测试的目的

测试 VMess 和 Shadowsocks 各种加密方式,在传输过程中的极限速度。

测试方法

在同一台主机上同时启动 V2Ray 客户端和服务器端,使用环回网络(Loopback)进行网络传输。客户端会接受到预设数量的数据,然后验证服务器端发出同样数量的数据。

测试环境

一台云主机,内存 2GB,CPU 信息如下。显然这台机器本身的性能不怎么样,如果用一台更好的机器,会得到更好的绝对数值,但本次实验结果的数值比例有参考价值。
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                2
On-line CPU(s) list:   0,1
Thread(s) per core:    1
Core(s) per socket:    2
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 61
Model name:            Virtual CPU a7769a6388d5
Stepping:              2
CPU MHz:               2399.996
BogoMIPS:              4799.99
Hypervisor vendor:     KVM
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              4096K
NUMA node0 CPU(s):     0,1

测试工具

特地写了两个小工具:loadgen 和 receiver。
loadgen 用于发送数据,它可以对某个端口建立连接,支持直连和 Socks 协议。可配置并发一定数量的连接,发送指定数量的数据后,验证 receiver 的反馈。如果 receiver 收到了同样数量的数据,则表明传输结束。
receiver 用于接收数据,对于每个连接,每次收到数据后,把总共收到的数据字节数发回,并等待连接发起方关闭连接。
由于 VMess 的正确性已被其它的测试验证,这里只需要验证连接畅通,即收到数据量等于发出数据量即可。

基本信息

我们用 loadgen 和 receiver 直接对接,可以得出环回网络的大致性能。实验结果如下:
数据量:50 GB / 连接
并发连接数124
速度(MB/s)426646544551
对比下面实验中的速度,可以认为环回网络的基本速度不会成为瓶颈。
进一步的基础信息,我们又测了一下使用 V2Ray 直连的速度。实验中只启动一个 V2Ray 进程,配置 Dokodemo-door <-> Freedom。实验结果如下:
数据量:10 GB / 连接
并发连接数124
速度(MB/s)640819787

VMess 测试

测试场景的差别是 VMess 的加密方式,其它都一样。传入依然是 Dokodemo-door,传出是 Freedom。
  • VMess CFB: AES-128-CFB 加密方式
  • VMess GCM: AES-128-GCM 加密方式
  • VMess Chacha: Chacha20-poly1305 加密方式
  • VMess None: 不加密
结果如下(数据量:10 GB / 连接):
解读如下:
  • 速度 GCM > Chacha > None > CFB;
  • VMess 可以同时处理多个连接。由于 CPU 是双核,所以 2 个连接的速度比单个连接快,而 4 个连接对比 2 个连接则没有明显提升;
很有趣的一点是 None 居然比 GCM 慢。不加密反而比加密慢,有一点违反常识。原因是这样的:VMess 不管加不加密,都会进行数据校验,None 中使用的校验算法是 FNV,而 GCM 是一个 AEAD 算法,自带校验。于是带 CPU 加成的校验比软件实现的校验快了不小。这一点也超出了开发人员的预期,之后会考虑提升校验的性能。

与 Shadowsocks 对比

V2Ray 和 Shadowsocks 的比较也是一个常见问题。既然我们有了一个性能测试的工具,那就一起测一下吧。
  • V2Ray SS CFB: V2Ray 中的 Shadowsocks 实现,AES-128-CFB 加密方式;
  • SS-Libev CFB: Shadowsocks libev 2.5.6,AES-128-CFB 加密方式,客户端 ss-tunnel,服务器端 ss-server;
  • SSR-PY CFB: ShadowsocksR 最新的代码(2017-01-20),AES-128-CFB 加密方式。其它的参数都是默认的:auth_aes128_md5、tls1.2_ticket_auth_compatible。
OTA 在所有 Shadowsocks 中都启用了。
实验结果(数据量:10 GB / 连接):
解读如下:
  • VMess 的速度优于 Shadowsocks;
  • 比起 ss-libev 和 ssr-python,V2Ray 在多并发连接的场景中更有优势;

结论

  • 在一台双核 2.4 GHz 的主机上,V2Ray 的极限传输速度超过 400 MB/s。
  • 如果你对速度有需求,请使用 VMess + AES-128-GCM。

后记

  • 在日常使用中,传输速度一般都不会超过 10 MB/s,上述测试的每种方式都可以满足需求。但如果你需要高性能传输,可以按测试结果选择合适的方式。
  • 上述的测试结果都是运行多次的平均值。由于虚拟机的不稳定性,误差在 5% 以下。
  • 其它方面的测试,如 CPU 和内存占用,会在后续的测试中进行。
  • loadgen 和 receiver 可以由 iPerf 替代,唯一的问题是 iPerf 不支持 Socks 协议。
  • 上述所有工具和测试脚本的源代码可以在这里找到

来源:https://steemit.com/cn/@v2ray/3cjiux