Shadowsocks/Vmess到底怎么选?安全性如何?

Shadowsocks/Vmess到底怎么选?安全性如何?

image

起因

入冬后,准确来说是在秋季,就感觉原来的小机场偶尔会出现大批节点无法连接的情况,今年1月底到期,在考虑几年了是否该更换跑路,不过好在相对便宜,故障一会就好,还能接受。

然而在将要到期的前几天的时间点上,它刚好又出现了中断,且持续了近1个小时,这对打工人来说不太能接受了,于是便舍弃了原来的小机场,投奔朋友推荐的更大一家。

image

但这里有两个问题,一个是用什么代理软件,第二个是用什么代理协议,这两个问题是逐步浮现的。

代理软件

由于个人职业与所处行业原因,接触墙外比较早(小时候到外服体验新版本游戏),也在之前就尝试自己搭过VPS,详见Try-for-V2Ray,后来由于Vultr质量真的不堪入目、WS+TLS需要的域名证书也是一笔费用且麻烦(才不是懒),项目算是咕掉了,但其中学习到的知识与相关技术还没全忘,用到的各种代理软件也还是多的。

Clash

你要我从中选择,移动端PC端我都会毫不犹豫的选择Clash,谁能拒绝可爱猫猫?但是,可爱猫猫在2023年11月寄掉了!与之相关的Core、Pro、X等都闻风而逝(只猫,影逝二度),仅留下永远停止更新的本地客户端。

image

虽然现在才1月底,最后一次release在3个月前,但时间越长,对于一个曾开源项目来说就越危险,必须要有可行的安全性选择(我也曾考虑过不这么麻烦,直接用之前的不就好了,然后我在互联网上“看着不错还蛮正经”的网站上获取的ClashX远程服务端口就被修改过了)。

V2rayU

撰写此文时,我新入职的公司使用的是MAC M2办公,在第一家公司就使用MAC的我并无什么不适应,但是ClashX在我入职前就化作灰烬,我在换机场前就已经在使用V2rayU,这是个专走Vmess协议的Proxy,虽然repo已有两年未更新了,但是release其实作者一直在偷偷更新。

image

然而,当我切换到新的机场订阅时,却发现机场节点的一句提醒:

因V2ray重大漏洞问题,暂时下架全部V2节点。请使用ssr/ss连接方式进行使用

image

代理协议

所以这是怎么回事?

我依稀记得我玩个人VPS那些年还在传VMESS协议更加安全,V2ray可以用更多的传输配置才对啊?这个重大漏洞是什么,CVE编号多少?(啊,这就是职业病)

V2ray重大漏洞

V2ray协议爆发了重大安全漏洞

漏洞的描述简单来说就是:

v2ray的TLS流量可被简单特征码匹配精准识别,vmess协议设计和实现缺陷可导致服务器遭到主动探测特征识别

这两方面的问题不论哪个都会使得用V2ray作为Proxy、VMESS作协议进行传输的墙外访问方式被轻松识别到,虽然不同于传统安全漏洞,但确实是严重问题。

服务器端的 V2ray 更新到 v4.23.4 以及之后的版本可以解决这一问题, 请大家尽快更新.

截止本文撰写,V2ray-Core的最新release已经到5.12.1,可是这个问题应该早已经被修复了,为什么现在订阅还有这样的提示,不让使用VMESS协议?

image

如何选择

绕一大圈,让我们回到文章的主标题:

Shadowsocks/Vmess到底怎么选?安全性如何?

先说结论:它们最新版本的实现都是安全的,也都是不安全的

image

为什么这么说?

对于这两种协议甚至更多种的传输协议,想要去了解它的具体实现及传输形式并不难,以Shadowsocks为例,在Shadowsocks协议解析一文中有清晰明了的叙述,Vmess你也应该都能找到类似的内容。

Shadowsocks/Vmess都会采用一定的加密算法,将传输内容进行加密,在浅谈一下Shadowsocks和VMess的安全性一文的评论中,enfein有提到“shadowsocks 协议现阶段还是安全的,但 VMess 在一些领域做得更好,例如使用依赖于时间的密钥生成办法”,这也佐证了我最初认为Vmess协议的安全性设计比Shadowsocks好的看法,那就能说明Vmess安全性更好吗?

image

主要漏洞

我们回忆一下前文提到的“V2ray重大漏洞”,虽然没有被直接破解出传输内容明文,但能精确地探测标识proxy服务器,与在黑暗森林中点火且大喊无异。

那么Shadowsocks有这样的问题吗?

浅谈一下Shadowsocks和VMess的安全性的原文中,作者例举了两个Shadowsocks的相关漏洞:

Shadowsocks AEAD 加密方式设计存在严重漏洞,无法保证通信内容的可靠性

shadowsocks redirect attack exploit

前者也会使proxy服务器因为流量特征被标识而封禁,后者则更致命地可导致传输内容密文被解析。

image

最佳实践

既然大家都是卧龙凤雏,有什么不那么烂的方式吗?

首先要明确的是,最新版本的协议都已经将已知漏洞修复,可以认为两者安全性相近,也都有可能被流量分析与主动探测(即使你采取了防范与伪装)。

针对Shadowsocks,防御GFW主动探测的实用指南一文中指出了Shadowsocks理应达到的最佳实践;相应的,Vmess支持和TLS组合,也可以实现动态端口等,这些在我搭建VPS的时候就已经是个人可以不算复杂的实现了。并且在【还Shadowsocks一个清白】Shadowsocks是如何被检测和封锁的,兼谈ss配置策略一文中,也有提到可以采用国内转国外双重代理的方式,规划ip白名单,规避一些探测(但文章内容主观性较强,观点接纳需分别):

image

此外,在搭建与使用的过程中,不能过分信任某些教程,并不是说它们的方法有问题,而是很多一键部署的脚本为了运行的稳定性与一致性,是写死了引用版本的,那么就很有可能还在利用存在漏洞的协议版本;同时也需要注意客户端的选择,个人现在使用的是Clash Verge Rev(回来吧我的牢猫!),Clash Verge的原repo也因为2023年11月的风波停止更新,Rev是抛弃了原Clash Core(repo removed)采用mihomo重新构建并仍在更新的版本。

image

那为什么不使用V2ray相关的客户端?

一方面是新的机场不支持Vmess(前情提要),一方面是V2ray Core做出的客户端确实没有猫猫可爱(猫猫也支持Vmess等多种协议),再一方面是有些V2ray的客户端的最新release用的Core版本仍处于风险版本(V2rayU:所以爱是会消失的对吗?)

image

机场顾虑

最后一个问题,既然Shadowsocks和Vmess都可以,为什么有些机场不提供Vmess节点了?

这个问题在关于科学上网的流行说法一文中可见一斑:

  • 大部分机场都是中转线路,使用 V2RAY 显得太重,消耗服务器资源大
  • V2RAY在防标识的场景下相比已经搭好的Shadowsocks没有明显优势

所以对于机场线路,公网隧道、专线,没有一定要再采用哪种协议的需求,更多地在考虑带宽等费用与访问流畅度。此外,机场躲避封锁的方式,在文章中也有谈及,同时文章中也有谈到订阅转换的技术,在一些机场也有提供(在逐渐收敛)。

个人小注

对于浏览访问来说,机场提供的服务已经完全够用,除了不能登录服务器进行配置这部分不便,这也是我为什么暂时放弃了自己搭建VPS的想法;

但对于未来的渗透测试来说,虽然简单的OOB可以Dnslog/Ceye,但如果要弹shell,或者境外测试,就还是需要国内云与国外云的服务,这些机场就完全无法支持了。

image

参考引用

Try-for-V2Ray

V2ray协议爆发了重大安全漏洞

Shadowsocks协议解析

浅谈一下Shadowsocks和VMess的安全性

Shadowsocks AEAD 加密方式设计存在严重漏洞,无法保证通信内容的可靠性

shadowsocks redirect attack exploit

防御GFW主动探测的实用指南

【还Shadowsocks一个清白】Shadowsocks是如何被检测和封锁的,兼谈ss配置策略

关于科学上网的流行说法

关于科学上网的流行说法

关于科学上网的流行说法

本文转自Clouder 并作补充

前言

本文意在分析一些经常被提及、引起争论的问题。

为什么不用 V2RAY/Trojan

由于直连打击力度较大,个人自建需要使用更不易被封锁的协议。很多人宣传 V2RAY Trojan 等,事实上对直连也许是有一定帮助的。

但是大部分机场都是中转线路,使用 V2RAY 显得太重,消耗服务器资源大,而实质上并没有什么帮助,因此更青睐老牌的、生态更好的 Shadowsocks 及 ShadowsocksR。

Trojan 也是类似的。

因此发表一些“不用 V2RAY 不怕被封吗”之类的言论,并不明智。

以下是部分大佬对此的看法。(如有冒犯,请联系删除)

image

image

image

image

(本句在当时语境下类似于玩笑话,其本人无任何贬低 Trojan 的意思。)

不可否认,新的协议的出现是必然且有意义的,但其出现一般都是为了解决现有问题。

例如 V2RAY 试图解决的是严重封锁,而 Trojan 试图解决的是 V2RAY 过重的问题。

而机场线路,公网隧道、专线,大概没有此类需求。

此外,Shadowsocks 与 ShadowsocksR 的生态相对成熟。

关于 Shadowsocks 与 ShadowsocksR 有如下说法:

  1. Shadowsocks 每个用户需要占用一个端口,部署可能不便。而 ShadowsocksR 支持端口复用模式。
  2. ShadowsocksR 停止维护,且加密程度相对 Shadowsocks 更高,意味着效率、性能相对较劣,但有传 ShadowsocksR 能缓解 QOS 问题。

目前看来,Shadowsocks 协议支持最为广泛。

以上内容为笔者个人见解,如有谬误,敬请斧正。

IPLC 天下第一吗?

首先,看看毒药博客中的介绍。

  • IPLC: “International Private Leased Circuit”的缩写,即“国际专线”。不过大部分机场通常看到的 iplc,都只是阿里的经典网络,跨数据中心内网互通,阿里内网,并不是严格意义的 iplc 专线;当然也有其他渠道的,或真 iplc,不过比较少。阿里云的内网互通底层原理是通过采购多个点对点的 iplc 专线,来连接各个数据中心,从而把各个数据中心纳入到自己的一套内网里面来。这样做有两个好处,其一是 iplc 链路上的带宽独享,完全不受公网波动影响,其二是过境的时候不需要经过 GFW,确保了数据安全且不受外界各种因素干扰。但是需要注意一下阿里云的 iplc 也是有带宽上限的,如果过多的人同时挤到同一条专线上,峰值带宽超过专线的上限的话也同样会造成网络不稳定。其他渠道购买到的 iplc 价格很高,阿里云内网这种性价比超高这种好东西且用且珍惜。
  • IEPL 国际以太网专线(International Ethernet Private Line,简称 IEPL),构建于 MSTP 设备平台上,基于 SDH 传输技术,采用 GFP 封装,传输协议透明,物理层隔离,带宽保证,提供一层点对点数据专线服务。IEPL 是以太网接口的增强型的 IPLC 产品,是一个端到端的专享管理频宽服务,拥有高度灵活性及最高物理层网络安全功能,让客户轻松管理广域网和高带宽需求的应用。通俗的总结一下,IEPL 使用某种技术,实现了两点之间的高稳定性的数据传输。这与 IPLC,MPLS 是差不多的效果,只是实现的技术手段有区别而已。其实对机场来说,是 IPLC 或者 IEPL 或是 MPLS-VPN,都没有太大区别。认定是保障带宽的不过墙专线就行了,至于是用哪种技术方案实现的,根本不需要纠结。
  • BGP:BGP 的实际意思通常是一个 IP 在多个运营商的网络中均为直连,不经过第三运营商,利用 iptables 或相关软件通过将去海外 VPS 的流量加一层国内转发。不过不同机场的定义也不一样。正常来说比如 rixcloud,指的是他们入口是阿里云、部分落地节点是自己起了 BGP(去 Peer 了 GitHub、微软、Cloudflare 等等)。不过多数机场把 BGP 定义为阿里云公网中转等。
  • 中转:将数据从一个服务器重定向到另外一个服务器。机场中比较常见的是阿里云公网中转,其实也有很多其他中转,也有自己去买其他的 BGP 来中转的。
  • 「原生 IP」:所谓原生 IP 通常意思为当地运营商原本就拥有的 IP;广播国家一般和注册国家相同(一般的 IP 库不会误判地区),一般不用于公有云计算服务或 IP 声誉好,一般能够用来解锁 Netflix、HBO、Hulu 以及其它有限制的流媒体服务
  • 流媒体解锁:很多流媒体服务平台如 Netflix 会出于版权原因而限制一些特定 IP 的访问。一般来说网络运营商(如 HKT)自己持有的 IP,比如商宽、家宽,极少被屏蔽,因为这些 IP 大多是流媒体服务商的目标客户在使用。家宽 IP 被屏蔽的几率是最低的,很多 ISP 的家宽都是动态 IP 的,很难精准封杀。固定 IP 的商宽其次。这些流媒体服务商也怕误杀导致投诉,比如 GCP 的 IP 段被投诉之后又可以看 Netflix 了。IDC 商家所持有的 IP 一般会被屏蔽,越大越有名的 IDC 持有的 IP 被屏蔽的几率越高。很多 IDC 会租用运营商的 IP 从而绕过此类封杀,但是这种方式并不是万无一失的,翻车案例比较多我就不再一一例举了。所以除非是商宽、家宽,其他所谓的“原生 IP 解锁流媒体”都是有几率翻车的。
  • CN2:是电信的精品骨干网。首先 CN2 是一张运营商骨干网,就像电信 163、中国移动这一类是同样性质的东西,但相对电信 163 来说会有更好的稳定性。不是什么专线(和 iplc 那类东西区分清楚)。既然是公网,那它本质上就是个很多人共享使用的东西。共享的东西都存在一定程度的不稳定性。区别在于它的超售比较低,相对电信 163 来说会有更好的质量。CN2 的跨国数据通讯也需要经过 GFW 审查,不存在不过 GFW 的公网。

在谈及 IPLC 时,一般泛指专线。专线相对于公网中转有如下优点:

  1. 不经过 GFW,也就是所谓的不过墙。
  2. 链路宽带独享,不受公网波动影响。

一个中转节点应该是这样的:

image

IPLC 速度快

一般来说,用户更关心的速度是“网速”,也就是宽带大小。

而使用专线并不能改变宽带的容量,因此盲目地认为 IPLC 网速快是毫无根据的。

IPLC 延迟低

专线传输,理论上延迟的确更低。 排除掉机场过度超售、宽带跑满丢包、软件出锅等问题,专线在此方面的确有优势。 虽然一般用户无需过多在意延迟。

IPLC 稳定

专线传输的稳定,主要体现在链路宽带独享,不容易受公网波动影响。 但上游依然会出问题,例如机房事故等等。 而高质量的公网可靠性并不差。

IPLC 安全

不经过 GFW 的处理,在某种意义上安全了。 但专线传输数据仍受到监管,如 ssrcloud 的中日专线有人访问邪教网站遭到警告。

注重隐私请使用 no-log VPN、多层跳板等方式,而不要轻信提供科学上网服务的机场还能保护你的安全。 一般人无需对此过于敏感。

IPLC 贵

专线宽带的价格的确高昂。

下图为花卷科技的 IPLC 专线宽带价格。

image

即使有钻石分销的六折,每 Mbps 也高达 210RMB,每 100 Mbps 价格要达到两三万元。

然而,其实还有更高贵的。如下图,北京动态 BGP 全穿透多线宽带。

image

上图为微网聚力官网的价格表,可以看到最高贵的宽带每 100 Mbps 高达五万元每月。

事实上,单比较价格意义不大,因为可以这样部署:

image

总结

以上内容亦非绝对,笔者目的不在于否定专线等等,而在于提醒各位读者更理性、全面地看待线路,而不要迷信专线等。

100Mbps 的专线给 100 人用,体验可能并不如 1Gbps 的公网隧道给 100 人用。

其实,用户对节点线路无需过多关注,而只需要关注用户体验。用起来好就行,不必在意机场主用了什么神秘的操作。

最后,来点佩奇笑话。

image

image

订阅转换偷订阅

不可否认,在技术上的确是可行的。 然而,让我们看看搭建订阅转换服务的都是什么大佬吧。

bianyuan

边缘订阅转换 API,笔者使用的第一个订阅转换 API。

Sabrina,博客地址为 https://merlinblog.xyz/,N3RO 机场的大佬。

撰写了大量教程,对社区的贡献毋容置疑。对于转换偷订阅的说法,其本人亦有过回应:

image

nameless13

https://api.nameless13.com/,也是相当知名的订阅转换 API 了。

Nameless13,魅影的管理员,撰写了魅影各类教程

gfwsb.114514.best

https://gfwsb.114514.best/,这域名震撼我一万年……

TindyX,subconverter项目的作者。

总结

以上只是订阅转换的一部分。笔者想借此说明的是,搭建这种公益服务者通常为大佬,并不会眼馋你的订阅。 当然并不排除有作恶者存在。 实在担心,建议使用本地版的 subconverter,避免此问题。

Surfboard 快

笔者无端猜测,有小白看了某知名 youtuber 的各大软件速度对比后,认为 Surfboard 更快。

笔者未进行相关测试,但必须指出: 软件并不是网速的主要影响因素,且无明显缺陷的软件,在速度上并不会有太大差异。

网速的主导因素,是线路质量。包括但不限于设备到路由器、家庭宽带到国内入口、国内入口到国内出口、国内出口到国际落地、国际落地到目标服务器的线路质量。

Surfboard 是一个相当优秀的客户端,但请不要以“网速最快”等说法夸赞推荐它,否则可能引发不必要的争端。

关于网速的一些思考

使用 youtube 进行网速测试,会受到硬件性能等因素影响,测速应使用更专业的工具。

据传,旧版本的 Clash For Android 使用的内核有一定的性能问题,已经更换。(来源不详,不必当真)

理想的中高端机场,应当能达到 100Mbps 及以上的速率,选用软件对网速的影响不必多虑。

关于软件速度的一些思考

一般来说,功能越复杂,速度就越慢。在路由器上跑规则复杂的 Clash,可能对网速有较大影响。

使用 PC 客户端,基本不用考虑。移动设备可能有一定影响,但并不大,无需太在意。

此处速度为泛指,结论纯粹笔者臆想,不足为据。

总结

撰写本文的目的,并不是想否定、批评广为流行的某些说法,而是想否定盲目地迷信某些说法的行为。 例如,对机场不提供 V2RAY 提出质疑的小白,吹捧 IPLC 强无敌的小白,认为 Surfboard 天下第一的小白等等……

本文也无意提出什么说法,而仅仅想说明:没有什么是绝对的。请理性评判,不要迷信权威。

That’s All.

引用

  1. ShadowsocksR 端口复用 原文 ↩︎
  2. ShadowsocksR 缓解 QOS 问题 原文 ↩︎
  3. 花卷科技钻石分销 原文 ↩︎
  4. 微网聚力价格表 原文 ↩︎
  5. 几乎所有订阅转换都基于 subconverter↩︎
  6. CFA Release ↩︎

防御GFW主动探测的实用指南

防御GFW主动探测的实用指南

本文转自Great Firewall Report 并作补充

在近期的IMC’20的工作中(论文, 演讲),我们揭示了中国的防火长城采用流量分析主动探测相结合的手段来检测和封锁Shadowsocks服务器。

在这篇短文中,我们将分别向技术小白和翻墙软件开发者提供防御GFW主动探测的实用建议。 我们还将介绍Len et al.展示的partitioning oracle攻击的缓解办法。 如果在遵循了本文的建议后,你的Shadowsocks服务器仍被封锁,请将封锁情况汇报给GFW Report以及相应的开发者。

给用户的建议

根据我们的测试和来自开发者的报告,在采用了适当的配置后,以下两个Shadowsocks实现的最新版本已经可以抵御来自GFW的主动探测:Shadowsocks-libevOutlineVPN

针对Shadowsocks-libev的使用建议

如果你决定使用Shadowsocks-libev,我们强烈建议你根据这篇教程来部署一台抗封锁的Shadowsocks-libev服务器。我们会时刻更新那篇教程的,以应对之后新出现的针对Shadowsocks的识别和攻击。

如果你已经拥有了一台Shadowsocks-libev服务器,你可以根据以下规则来确认你的服务器是否配置得可以对抗GFW的主动检测和封锁。

截止2021年1月,你需要做到以下几点来防止你的Shadowsocks-libev服务器被封锁:

  1. 确保你的服务器版本为v3.3.1及以上。你可以通过以下命令查看服务器的版本ss-server -h
  2. 使用AEAD ciphers, 而不用 stream ciphers。换句话说,仅在以下几种加密方式中进行选择:chacha20-ietf-poly1305 (推荐), aes-256-gcm, aes-192-gcm或者aes-128-gcm

为了缓解针对Shadowsocks的partitioning oracle攻击,你需要:

  1. 使用一个长的随机密码。这样的密码可以用以下命令在终端生成: openssl rand -base64 16;
  2. 禁用UDP模式。

注意:针对客户端没有特殊的要求,任何与Shadowsocks-libev服务器兼容的客户端均可。

针对OutlineVPN的使用建议

为了防止你的OutlineVPN服务器被GFW封锁,你需要做到以下几点:

  1. 使用最新版的从官网下载的服务端。
  2. 使用最新版的从官网下载的客户端。

注意:

  1. Outline会自动生成一个长的,随机的密码,因此你不必像为Shadowsocks-libev那样手动配置密码。
  2. Outline服务端会自动更新,因此你不必手动升级服务端。
  3. Outline只采用chacha20-ietf-poly1305这一种AEAD cipher作为加密方式,因此你不必手动选择加密方式。

给翻墙软件开发者的建议

下面我们介绍我们发现的GFW的最新审查能力,并附上我们给翻墙软件开发者的相应建议。这些建议不仅对Shadowsocks,而且对其他许多翻墙软件都有用。 我们欢迎你加入我们的讨论,分享你的想法,评论,疑惑和关切。

正确的校验

首先,我们强烈建议翻墙软件的开发者们彻底废除不具备校验的加密构造。仅仅有保密性是不够的。

  • 对于新开发的翻墙软件来说,这意味着根本不应考虑支持不具备校验的加密构造。
  • 对于现存的翻墙软件来说,这意味着开发者应该勇敢地移除所有与不具备教研的加密构造相关的代码,即使以不向下兼容为代价。

我们这看似大胆的建议实际上出于合理的原因。如我们在论文中所介绍的, 一些类型的GFW主动探测会利用Shadowsocks的stream ciphers的malleability。这已经不是第一次不具备校验的加密结构造成漏洞了。事实上,不具备校验的加密结构是许多Shadowsocks和其他翻墙软漏洞的根本来源。

早在2015年8月,BreakWa11发现了一个关于Shadowsocks的stream ciphers的漏洞。这个漏洞是由于缺乏数据完整性保护而造成的(英文总结)。 在2020年,类似的漏洞又被发现存在于V2Ray中(总结)。

当Shadowsocks开发者试图引入one time auth模式来缓解2015年的那个漏洞时,另一个因数据长度缺乏完整性保护的主动探测又被引入了英文总计)。

2020年2月,Zhejiang Peng发现了一个关于Shadowsocks stream ciphers的灾难性的漏洞,(英文总结)。 利用使用了stream cipher的Shadowsocks服务器作为decryption oracle,攻击者可以在不需要密码的情况下,完全解密Shadowsocks会话。

其实早在2017年2月,AEAD ciphers就已经成为了Shadowsocks协议的一部分。而校验问题也理应在那时就被解决了。但实际情况是,截止2021年,大量的服务器仍然因为使用被废弃的stream ciphers而存在着安全隐私漏洞,以及被准确识别的风险。

这样的现象表明,在实际操作中,许多的用户不能够正确的选择加密方式。这可能与使用过时的教程或一键脚本有关。 我们因此鼓励开发者从Shadowsocks各实现中彻底移除stream ciphers,帮助用户做出正确的选择。

使用同时基于nonces和时间的重放过滤器

我们建议翻墙软件的开发者们采用同时基于nonces和时间的重放过滤器。 因为采用基于时间的重放过滤器需要对Shadowsocks协议进行根本性地变动,我们建议开发者至少要此采用基于nonces的过滤器,并且做到:

  1. 要么建议用户在每次过滤器重置后修改密码;
  2. 要么开发一个机制,可以让重放过滤器在软件重启后依然记得之前的nonces。

这些建议是基于以下的研究发现和推论。 如论文的section 3.5所介绍的, GFW既可以在观察到一个合法连接的瞬间对其进行重放;也可以等待三周甚至更长时间后才重放。 因此,一个更加合理的主动探测模型应该允许审查者在任意时长后对合法连接进行重放。

这样的一个主动探测模型揭示了纯粹基于nonces的重放过滤所须要面对的不对称性。GFW仅用少量资源就可以记录一些合法的连接,并且在经过任意的时长后再重放它们;但与此同时,Shadowsocks需要大量的资源和相对复杂的实现来永久性地记住所有的合法链接,直至密码被更换。 注意,Shadowsocks服务器必须在重启后还记住这些nonces;否则重放过滤器不会过滤基于重启前的合法连接的重放。

幸运的是,这个不公平的局面可以通过同时引入基于时间的重放过滤机制来扭转:服务器只需要处理并验证时间戳未过期的连接,就像VMess服务器那样。 如此一来服务器就不需要永久性地记住所有合法连接中的nonces。

我们还想强调,对于那些仅仅短暂暴露变化的监听端口的翻墙服务器,重放过滤仍是必要的。因为GFW可以瞬时重放合法连接中的第一个数据包,而这时暴露的监听端口因为未完成数据传输,依然是开启的。

让服务器的反应保持一致

我们建议开发者们确保翻墙服务器在正常运行时,和遇到不合法的连接时都反应一致。理想情况下,可以按照Frolov et al.的建议,让服务器遇到错误连接时“read forever”。 这是因为,审查者会故意触发协议的边边角角等特殊情况,来识别服务器指纹。

除了我们在Shadowsocks-libev和OutlineVPN中发现的服务器反应指纹,Frolov et al.还展示了包括Shadowsocks-python和OutlineVPN在内的多种翻墙软件可以通过关闭连接时的TCP flags和连接时长来识别。studentmain报告,直至2020年12月, 许多的Shadowsocks实现仍存在着我们在Shadowsocks-libev和Outline中发现的问题。

Frolov et al.建议代理服务器在遇到错误连接时不要立即关闭连接,而是“read forever”。这样做不但避免泄漏超时值,而且使得服务器发送与正常连接关闭时相同的TCP flags来关闭错误连接。

进一步说,“reading forever”本身不会带来更加独特的指纹。因为Frolov et al.发现互联网上大量的服务器都会有无限超时值(“infinite timeout”)的特征。David Fifield调查显示,许多流行的翻墙软件已经采取了“read forever”策略。这些软件包括OSSH,obfs4,Outline和Lampshade。

强制采用强密码

Len et al. 于2020年展示了针对Shadowsocks服务器的partitioning oracle攻击。利用在Shadowsocks中使用的non-committing AEAD,攻击者可以更高效地猜出密码。我们因此建议开发者强制采用强密码。一种可能的实现方式是要求用户密码的熵高于一定值。

主动探测你的实现

如果你是一个不同于Shadowsocks-libev和Outline的翻墙软件开发者或贡献者,我们鼓励你检查同样的漏洞是否也存在于你的Shadowsocks实现中。我们开源了我们在论文Section 5.1中用到的prober 模拟器

鸣谢

我们想要感谢来自Jigsaw的Vinicius Fortuna,来自APNIC的Robert Mitchell和Dan Fidler,以及来自Qv2ray的DuckSoft和Student Main对本文提供的反馈。

联系

这篇报告首发于GFW Report。我们还在APNIC blog,net4people以及ntc.party同步更新了博文。

我们鼓励您或公开地或私下地分享您的评论或疑问。我们私下的联系方式可见GFW Report的页脚。

Shadowsocks协议解析

Shadowsocks协议解析

本文转自喂草 并作补充

Shadowsocks过程

Shadowsocks是一个代理协议,以下简称SS。当然基于SS协议催生出了许多的代理软件,例如Shadowsocks-NG(MacOS平台)、Shadowrocket(iOS平台)等。不过总归来说SS的流程是一致的:

image

上图简述了SS在整个数据传输中的位置,包含了SS客户端和SS服务端两个部分,一般来说SS客户端是安装在本地的软件,而SS服务端则是运行在VPS上的软件。如果没有SS的话,上图就成了没有代理的用户与目标服务器(例如Google.com)的直接通信。下面一SS代理下的HTTP请求介绍上述过程:

  1. 浏览器要访问Google.com,便生成HTTP请求。由于设置了代理,所以不会直接发送到Google服务器,而是发送到SS客户端(例如127.0.0.1:1086)。
  2. SS客户端把HTTP请求封装成SS请求(后面详细介绍),包含协议封装和加密过程,发送给SS服务器。
  3. SS服务器收到SS请求并解析,包含解密和协议解析过程,获得原始HTTP请求。
  4. SS服务器连接Google服务器,发送用户的原始HTTP请求,并获取Google返回的HTTP响应。
  5. SS服务器对HTTP请求进行加密,并发送到SS客户端。此处没有协议封装。
  6. SS客户端收到SS服务器的响应,进行数据解密得到HTTP响应,发送到浏览器以完成HTTP请求。

Shadowsocks协议

接下来会在字节层面对上述过程进行详细介绍。由于SS在处理TCP连接和UDP报文所使用的协议有所差异,因此也会分开介绍。

TCP连接

TCP连接模式主要包括HTTP、HTTPS和Socket等应用层协议,这些协议有所差异比如说有的协议有握手,有的协议却只有一来一回的数据交互,有的协议可能会保持长时间的连接和数据传输。。但这些对于SS来说都是一样的,因为它们都不过是数据(payload),而SS要做的无非是创建两个通道,一个用于把客户端数据传输到服务端,一个用于把服务端的数据传输到客户端

SS请求

TCP握手很熟悉了,握手的目的是建立数据链路。SS也有握手过程,目的就是建立上述的数据链路,不过这个过程只有半次握手,即SS请求。SS请求的主要功能是建立代理链路,因此需要告诉SS服务器要代理访问的远程服务器地址(如果不知道IP地址的话,给域名也可以),然后可以顺便携带一部分传输数据。根据地址类型的不同,SS请求会有3种形式:

  1. 通过SS请求传输目标服务器的IPv4地址:

image

  1. 通过SS请求传输目标服务器的IPv6地址:

image

  1. 在不知道目标服务器IP地址的时候(比如DNS被劫持),直接传输目标服务器的域名:

image

客户端加密

SS客户端把SS请求组装好了,在向SS服务器传输之前还需要进行加密,否则用户的数据就在网络上明文传输了,这个是很不安全的。下面举例使用SS中最常用的加密方案AES-256-cfb方式进行数据加密,大致步骤如下:

  1. 密钥生成:AES-256意味着其密钥长度是256bit,但用户密码有长有短,而且都是可见的ASCII,把密码作为密钥来用显然安全性是不够的,所以需要根据密码生成安全性达标的256bit长度密钥。SS中使用MD5对密码生成16byte长度的消息摘要,即可作为密钥使用。
  2. IV生成:原始AES加密下,对于相同的明文会生成相同的密文,这也是安全性的一种缺陷。AES-cfb通过引入随机数IV的方式解决该问题,即在随机数IV的加持之下可以实现相同的明文生成不同的密文。在AES-256-cfb中,IV是一个16bit的随机数。
  3. 加密:有了密钥、加密算法、IV,就可以生成加密器,并对数据进行加密了。在此数据就是上述所组装的SS请求,得到密文cypher。为了让SS服务端可以解密,还需要把IV也一同发送,所以最终生成的数据如下:

image

服务端解析

SS服务器和SS客户端所共享的信息有密码和加密方式,这是配置过SS服务器的人都知道的,在收到SS客户端发送的SS请求后,SS客户端进行解析的过程如下:

  1. 密钥生成:根据密码生成密钥,由于和客户端拥有相同的密码和密钥生成算法,所以生成的AES-256-cfb密钥也是一样的。
  2. 获取IV:从SS客户端接收到的数据前16bit提取出来就得到了AES-256-cfb的IV。
  3. 解密:根据密钥、加密算法和IV生成解密器,对收到的数据进行解密,就得到了SS请求明文。
  4. 地址解析:根据SS请求的第1个Byte得知目标服务器地址的类型(IPv4,IPv6或域名),并根据相应的规则进行解析得到其地址与端口。
  5. 代理请求:说到底SS就是一个代理协议,代理的意思就是代替客户端对目标服务器发起请求。通过地址与端口连接目标服务器,并发送解密后的数据,完成请求。

服务端响应

SS服务器收到目标服务器的数据,把数据传输给SS客户端,也需要进行加密,不同的是不需要组装协议了。所以该过程就比较简单:

  1. 生成IV:虽然也是随机数,但该IV与SS客户端发送请求时生成的IV不相等,需要再生成一个。
  2. 加密:根据新生成的IV、密钥和加密算法生成加密器,对目标服务器响应的数据进行加密。同样为了SS客户端可以解密,也需要把IV连同密文一起发送给客户端。

客户端解析

SS客户端收到服务端的数据,通过提取IV就可以生成响应的解密器,对数据进行解密,从而完成用户与目标服务器的通信。
上述的加密器和解密器都是和连接绑定的,即一次TCP连接代理通信只需要互相发送一次IV用于双方创建解密器,而后续的通信内容都只有包括密文部分,使用解密器进行解密即可。
所以其实SS协议的过程是非常简单的,以至于在画下图的时候都不知道有什么可以加上的东西。

image

UDP连接

UDP模式在SS中通过UDP转发选项开启,用于代理UDP流量如DNS查询、即时语音通信等。

UDP模式和TCP模式差异

SS中TCP和UDP大同小异,但由于UDP之于TCP是无连接协议,因此简单探讨一下UDP模式无连接下的一些区别:

  1. TCP连接作为基本单位:在TCP模式中,从握手到挥手的过程就是一次连接,因此一次连接是SS中的基本单位,所以一次连接对应上下行的2个加密通道、2个IV。所以一次TCP连接中无论有多少次数据交互,只需要一次握手
  2. UDP数据分组作为基本单位:在UDP模式中没有连接的概念,其基本单位是每个数据包,所以每个数据包对应1个IV和加密解密器。可以说在UDP模式下有多少个数据包,就会发生多少次SS握手。
  3. 连接方式差异:因为UDP是无连接,所以在socket编程时通常不会像UDP连接一样,先connect然后才数据读写,而是直接进行数据包的收发。
  4. 方向性:TCP模式种中总是SS客户端向SS服务器发起握手,但在UDP模式中由于没有连接的概念,所以每个数据包都是平等的自带握手信息,即使SS服务器向SS客户端发送的数据也是。

UDP下的握手协议

UDP模式中每一个数据包都具有相同格式,无论是从SS客户端发往SS服务器,还是从SS服务器发往SS客户端,其格式与上述SS请求相同:

image

所以不仅SS客户端会把需要代理访问的目标服务器的地址信息告诉SS服务器,SS服务器也会把目标服务器返回的数据连同其地址信息一同返回SS客户端。这主要是因为UDP模式下是没有连接的概念,所以每条数据需要自带一些额外信息,就像每次进商场都要戴口罩测体温一样。

后记

学术交流而已。