Skip to content

Instantly share code, notes, and snippets.

@galaxy001
Created February 17, 2017 19:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save galaxy001/ecc158c58c3b781f35e4aa3d021bbc72 to your computer and use it in GitHub Desktop.
Save galaxy001/ecc158c58c3b781f35e4aa3d021bbc72 to your computer and use it in GitHub Desktop.
clowwindy设计Shadowsocks的思路分析以及设计理念

clowwindy设计Shadowsocks的思路分析以及设计理念

鄙人不才,尝试站在原作者clowwindy的角度,来分析一下原版协议的设计思路和理念。 没参与过最初开发,不过设计了AEAD这个协议。读了一些资料,评论。

7:58 PM, 31 Aug 2015 作者发了这么一段话,我很好奇其中的指代内容,遂有本文。

眼睁睁看着一群人把一个东西搞错然后朝着错误的方向走了。不过懒得管了 =。=

先放一个众所周知的东西:https://gist.github.com/clowwindy/5947691

SSL 设计目标:

  1. 防内容篡改
  2. 防冒充服务器身份
  3. 加密通信内容

而翻墙的目标:

  1. 不被检测出客户端在访问什么网站
  2. 不被检测出服务器在提供翻墙服务

SSL 和这个目标还是有一些出入。其中最大的问题是,2. 防冒充服务器身份 这个功能多余了。他会导致墙嗅探出证书信息,继而墙会知道服务器身份。如果墙知道一个服务器身份是用来翻墙的,它要做的仅仅是封掉使用这个证书的所有 IP。

好了,引用基本结束。

总论:这里翻墙的两个目标是协议设计的指导方针,两者是递进的关系。

协议做的事情是把要访问的目标放在 TCP request里面的dst.addr(atyp用来区分种类,属于实现细节) 和 dst.port里面,之后通过加密把这个目的“封装”起来,暴露出来的就是一个中转服务器的tcp.addr 和 tcp.port

对于加密来说,主要目的是隐藏掉前面的tcp request中的信息,这样你就不知道我要去连接谁,而加密payload算是一个副产品,属于顺便做的,为的是防止payload中也包含访问的目标信息。所以加密的总体目的是隐藏访问目标。

更进一步:shadowvpn把目的封装起来,暴露出一个中转服务器的 udp.addr 和 udp.port

这样自然就引出两个问题,进行到如何的程度才能『不被检测出客户端在访问什么网站』,第二个是服务端要做什么才能『不被检测出服务器在提供翻墙服务』

clow最初选择了类似凯撒变换的table,但是由于一些攻击方式,改成了stream cipher,这里面涉及到一个设计哲学

  1. 速度快
  2. 保证1的情况下,隐藏目的

因为stream cipher可以不必等待整个数据块到达再进行解密,而是随来随解。

通过简单的流加密达到目标一,通过小范围私下使用以及可组合的加密参数达到目标二。

这里面的重点在于第二点『不被检测出服务器在提供翻墙服务』,解释很简单:如果墙知道一个服务器身份是用来翻墙的,它要做的仅仅是封掉使用这个证书的所有 IP。这里我们改一下字眼,如果墙知道一个服务器身份是SS,它要做的仅仅是封掉 IP

很多基于stream cipher的增强,包括OTA,AEAD,以及breakwa11的各种探测,这些全是基于一个假设进行的:已经开始做有罪推定,也就是开始怀疑服务器身份,或者是通过了广撒网式的摸索,确定几个可疑分子进行进一步的验证的时候。这里面有个逻辑问题,如果我已经知道这个属于ss/ssr的数据格式,我为什么要去尝试解密,我直接封锁掉服务器不就可以了吗。 所以重点在于indistinguishability from random bytes,只要还不能区分出ss/ssr,这个协议就是安全的。

这时候我们还有第二个防护网:加强引发怀疑之后的消除动作。比如SSR里面的redirect功能,这个思路非常正确,就算引起了怀疑,我们想方设法把它引到正常网站上去,达到消除疑虑的目的;或者是通过混淆将流量转成一般的访问,在一开始就不引起怀疑。

有一句话是解决目标二的终极方法:If you want to keep a secret, you must also hide it from yourself.

对于广泛使用的多人公开服务器,属于violate 目标二,在流量大的时候很容易引起关注。

几个链接:

https://github.com/shadowsocks/shadowsocks/issues/169

https://github.com/shadowsocks/shadowsocks/issues/69

https://github.com/shadowsocks/shadowsocks/issues/64

https://github.com/shadowsocks/shadowsocks/issues/108

========

再来说一下在指导方针下的协议设计理由:

做中转的话要知道 Address Type | Destination Address | Destination Port 这三者(当然得有附带的数据)。因为要设计的是一个代理协议,肯定要先找一下目前存在的代理协议,然后分析一下优缺点,之后取长补短,这个也是做研究的一般思路。因为有现成的SOCKS协议,所以就拿来用了,一方面是协议本身简单,二是可以达到高度复用和统一。

这里面拆成三段的原因可以由『不被检测出客户端在访问什么网站』这个思想推知

  1. client-program <=> local-proxy
  2. local-proxy <=> remote-proxy
  3. remote-proxy <=> the-true-target-server

2已经通过加密隐藏了访问目标; 1需要找一个广泛接受并良好实现的协议做本地通信,socks5是个很好的例子; 3没什么可说的,解密之后直接做收发就好.

在socks5基础上做精简可以说是精妙,他把2的最小需求(知道要把数据转给谁,根据五元组)和1的代理和本地交互做到了复用,只需要确定哪些丢掉不要就好了,而不需要重新再写一个与本地通信的新协议。

根据TCP流的特征,以及UDP包的特征,本质上决定原版协议是一个统一的整体

TCP: [IV][data][data][data][data]...
UDP:  [IV][data]..[IV][data]..[IV][data]...

这里唯一的区别就是IV的使用,stream cipher根据(IV,key)出一个keystream,通过keystream和plaintext做xor得到ciphertext

我既然已经有个天然的stream,我就不需要把tcp也改成 [IV][data]..[IV][data]..[IV][data]... 这种形式,在验证通过以及知道要把数据转给谁的情况下,模式就转成单纯的pipe,只是一个管道而已。

总体来说,设计指导思想是:

  1. 速度够快
  2. 在1基础上隐藏访问目标
  3. 不影响2这个目的的情况下,不做任何不必要的加强

对于隐藏目标:分化成两部分,(1)通过加密隐藏数据来往的目标,之前是本地直接和目标通信,现在通过中转把它分成『本地和一个服务器通信』和『一个服务器和目标通信』 (2)通过可变的加密参数等各种配置项达到保护这个中转服务器的目的

以后的发展:

  • 在加密不影响『隐藏访问目标』这个目标的情况下,增强加密属于心理安慰,对ss无影响,大力加强属于走偏
  • 需要在『保护这个中转服务器』上下功夫,不论是防重放确认中转的身份,还是发现可疑的就转给正常网站的SSR的Redirect,都是在尽力保护中转
  • 速度、加密的安全性、协议的隐匿性,这三者有的时候不好权衡,需要找到正确的平衡点

个人续命:

  1. 定期更换key和其他参数,比如加密、端口等等
  2. 绝对要小范围使用,不张扬,If you want to keep a secret, you must also hide it from yourself.

开发者续命:

  1. 保留尽量多的配置组合方式
  2. 努力完善服务端,保护中转不被发现

====

这么来看的话,就可以解释之前有人一直在说 rc4-md5 已经不行了,下一代是google的chacha20,近乎疯狂的崇拜。如果用我上面的理论,加密仅是用来隐藏掉访问的目的,而不是为了强加密。所以说用哪个只能是个人喜好,但是贬斥一个,褒扬另一个就是明显的跑偏,后来作者用了核电火电来调侃也就明了。在现阶段,没有明显证据证明前者真的不行,更可能的应该从上面分析的保护中转服务器上研究可能性。

关于安全性和速度:

放一个引用

Speaking of ScrambleSuit, most people doing anti-censorship research outside China often don't realize that actually we don't care about censorship. They thought we're curious about uncensored news, and we're eager to find out what the government has blocked recently. Unfortunately that's not true. Nobody is gonna do that. Most people just want to watch silly gameplay videos on YouTube, share their silly photos on Instagram, download pirate or porn movies, play online PC or PS4 games that are often too slow without using a proxy. If we really were a freedom loving nation, we won't have such a firewall.

Compared to those projects from outsiders, the tools that Chinese people invented have one characteristic in common: speed. We have high goodput and low latency, even better than most of the VPN protocols.

从这里面你可以看到,这个只是帮你快速穿墙,适用于一般的无价值目标,如果是特定人群,你需要tor。一般人大多数是发发状态,看各种视频,还有H,下载一些pirate,网络游戏。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment