Shadowsocks简介

Shadowsocks上一个大致基于(loosely based on) SOCKS5 的安全分割代理(secure split proxy)

../../../../_images/ss.png

Shadowsocks工作原理图

Shadowsocks 本地组件 (ss-local) 的作用类似于传统的 SOCKS5 服务器,为客户端提供代理服务。它加密并转发来自客户端的数据流和数据包到 Shadowsocks 远程组件 (ss-remote),后者解密后转发给目标。目标的回复同样会被加密,并由 ss-remote 转发回 ss-local,ss-local 解密后最终返回给原始客户端。

通过(官方)上文描述,可以看出Shadowsocks和 SSH Tunneling: 动态端口转发 工作原理非常相似

SSH Dynamic Forward(ssh -D) 和 Shadowsocks(SS)原理对比

步骤

SSH Dynamic Forward (ssh -D)

Shadowsocks (SS)

  1. 客户端发起请求

Firefox 产生流量,发送给本地的 ssh 进程(扮演 SOCKS5 服务端)。

手机上的小火箭(扮演 ss-local )接收系统流量,并提供 SOCKS5 代理。

  1. 本地加密

本地 ssh 进程将数据用 SSH 协议加密。

ss-local 将数据用指定的对称加密算法(如 aes-256-gcm )加密。

  1. 隧道传输

加密数据通过已经建立好的 SSH TCP 隧道传给远端 VPS。

加密数据通过普通的 TCP/UDP 连接传给远端 VPS 的 ss-remote

  1. 远端解密与转发

VPS 上的 sshd 服务收到数据,解密并代表你向目标网站(如 Google)发起请求。

VPS 上的 ss-remote 收到数据,解密并代表你向目标网站发起请求。

  1. 响应返回

目标网站的响应传回 sshd → 加密回传给本地 ssh → 解密给 Firefox。

目标网站的响应传回 ss-remote → 加密回传给 ss-local → 解密给手机。

但是 SSH Tunneling: 动态端口转发 对于翻墙有一个关键性缺陷,也使得和SS有明显的区别:

  • SSH Tunnel 设计初衷是为了远程安全运维,不是为了翻墙,所以握手阶段有非常明显的 协议特征 ,会 明文宣告自己的SSH版本等 )。防火墙(GFW)可以通过深度包检测(DPI)极其轻松地识别出SSH流量,所以在GFW收紧时期常常会出现SSH Tunnel无法稳定使用的问题

  • Shadowsocks 设计初衷是为了穿透防火墙,所以传输时会进行 混淆和全流量加密 (早期时One-Time Auth,现在时AEAD加密如 aes-256-gcm )。对于防火墙来看,SS的流量完全是 无特征的随机乱码(Heuristic/Entropy) ,很难被精准识别和拦截

  • SSH只支持TCP协议,这对于手机上的一些需要UDP协议的应用(如语音通话),SSH Tunnel无法代理这些UDP流量

  • Shadowsocks 原生支持 TCP 和 UDP,小火箭可以通过 SS 完美代理手机上的所有网络请求。

备注

SSH这种握手阶段明文发送版本字符串导致被GFW阻断,这个案例和我之前在阿里云上构建HTTPS服务但是未备案导致拦截,原因就是TLS(HTTPS)的SNI被防火墙检测到导致的( SNI, ESNI 和 ECH (Encrypted Client Hello) )

AEAD 加密

Shadowsocks(尤其是目前主流的 SS-AEAD 协议,如 aes-256-gcmchacha20-ietf-poly1305 )彻底抛弃了传统的“明文握手”阶段。

不过,现在防火墙已经能够利用 "流量指纹分析" (Traffic Fingerprinting / Traffic Analysis)来识别 Shadowsocks:

  • 包长度分布(Packet Length Profile): 浏览器访问网页时,由于 HTTP 请求、HTML 加载、图片下载的顺序和大小是相对固定的,即使被 SS 加密,产生的密文数据包大小依然会呈现出特定的统计学分布。

  • 包到达时间间隔(Inter-Arrival Time, IAT): 浏览网页时的“点击-阅读-再点击”行为,在时序上有着强烈的交互特征。这与 VPS 之间进行纯数据备份(持续、均匀、高速的流量)完全不同。

  • 连接行为特征:单 IP 长期保持一个长连接,且该连接不断有高熵(随机)流量吞吐,而该 IP 并没有注册合法的 SSL 证书或运行标准的 HTTP 服务。

由于上述特征,GFW防火墙还是会大致判断出SS流量,并进行端口阻断或限速。

参考