本篇文章的作者是Anonymous, Anonymous, Anonymous, David Fifield, Amir Houmansadr,发布时间2019年12月30日。
在中国,Shadowsocks 是最流行的翻墙软件之一。从2019年5月起,大量的中国网民反馈他们的Shadowsocks服务器被封锁了。这篇报告是我们对中国的防火长城(GFW)是如何检测和封锁Shadowsocks及其衍生翻墙软件的初步调查结果。
通过网络测量实验,我们发现GFW会被动的监视网络流量从而识别出疑似Shadowsocks的网络流量;然后对对应的Shadowsocks服务器进行主动探测已验证其怀疑的正确与否。Shadowsocks的封锁程度可能受人为因素在特殊敏感时期的控制。我们提出一种规避方法,即改变网络数据包在Shadowsocks握手阶段的大小。这种方法被证明可以在现阶段有效减少主动探测。我们会继续与开发者合作让Shadowsocks及其衍生工具变得更加难以封锁。
一、主要发现
防火长城(GFW)已经启用主动探测的手段来识别Shadowsocks服务器。GFW采用被动监测与主动探测相结合的方式:其首先监测网络连接找出疑似Shadowsocks的连接,然后再把自己伪装成一个客户端,尝试对疑似Shadowsocks的服务器进行连接,从而验证自己的猜测。我们知道GFW可以对多种翻墙工具进行主动探测,现在Shadowsocks也成了其中一员。
主动探测系统可以发送多种不同类型的探测。其中一些探测是基于对之前合法客户端建立的连接的重放;而另一些探测则似乎与之前的合法连接并不相关。
如同之前的研究发现,主动探测来自大量不同的源IP地址。这使得基于源IP来过滤GFW探测包不太可行。亦如之前的研究发现,网络层面的侧通道显示这些来自数以千计的IP地址的主动探测并非完全相互独立,而是源于GFW的集中控制。
很少量的(大于13个)合法连接即足以触发对于Shadowsocks服务器的主动探测。只要合法客户端还在使用服务器,主动探测就会持续下去。GFW通常在合法连接到达服务器后的数秒内发送第一个主动探测。
一旦GFW主动识别出Shadowsocks服务器,GFW可能会丢弃所有发送自服务器IP地址,或服务器Shadowsocks端口的数据包。但GFW也可能不立即采取封锁措施。Shadowsocks的封锁程度可能受人为因素在特殊敏感时期的控制。
GFW的被动监测模块至少会根据网络数据包的长度来怀疑可疑流量。改变数据包的长度,比如所在服务端安装brdgrd,即可通过干扰被动监测模块对Shadowsocks流量的识别,进而显著减少主动探测的数量。
二、我们怎么知道的?
我们在境外搭建了自己的Shadowsocks服务器并从中国用客户端连接它们,与此同时,在服务器和客户端两端抓包进行分析。所有的实验都是在2019年7月5号到2019年11月11号之间进行的。其中的绝大部分实验都是在2019年9月16日开始的一次大规模封锁后进行的。
在绝大部分实验中,我们使用了shadowsocks-libev v3.3.1作为客户端和服务端,因为它是一个被积极维护且具有代表性的Shadowsocks实现。我们相信我们所发现的这些弱点在其他Shadowsocks及其衍生工具,如Outline VPN,中同样存在。
若非明确指出,我们未对任何实验中的客户端及服务器的网络功能进行修改,比如更改防火墙的设置。Shadowsocks可以使用不同的加密设置,我们对Stream ciphers和AEAD ciphers都进行了测试。
三、主动探测的一些细节
Shadowsocks是一项加密通讯协议,其数据包的内容被设计得(应)不包含任何固定特征。其两种加密模式都基于一个主密码,两种模式分别为:Stream(不推荐使用) 和 AEAD (推荐)。这两种加密模式虽都要求客户端事先知道主密码;但是Stream加密模式的服务器仅能对客户端进行较弱的验证。除非使用额外的技术手段,两种模式都不能防御对之前发送过的验证数据包的重放攻击。
主动探测的类型及审查者意图
我们目前观察到五种不同的主动探测荷载。
基于重放的探测:
1. 重放某一合法连接中第一个携带数据的数据包中的荷载。
2. 重放某一合法连接中第一个携带数据的数据包中的荷载,但更改第0字节。
3. 重放某一合法连接中第一个携带数据的数据包中的荷载,但更改第0–7和第62–63字节。
看似随机的探测(并非基于我们所观察到的合法连接):
4. 荷载长度为7到50字节,占所有看似随机的主动探测的70%。
5. 荷载长度为221字节,占所有看似随机的主动探测的30%。
我们怀疑GFW的主动探测系统根据服务器对这几种不同类型的主动探测的反馈来判定其是否为Shadowsocks服务器。
Shadowsocks-libev有一个重放过滤器; 但是大多数的Shadowsocks实现则没有。重放过滤器可以防御一模一样的重放(类型1),如果载荷的最初几字节被改变了(类型2和3)那么过滤器就无法防御了。过滤器本身也不够阻止主动探测模块去比较服务器对多种探测的反应。
多少次合法连接就能触发主动探测
对主动探测的触发似乎需要达到一定的阀值。比如在一项实验中,仅仅13次连接就足以引起GFW的怀疑并触发主动探测。初步结果显示,使用了AEAD的Shadowsocks,可能需要稍微多一点点的连接才会触发主动探测。