从 V2Ray 到 Xray 的体验之旅

knitting-maze

最近偶然通过 Youtube 的推荐视频,发现 Xray 又出了新玩意儿:REALITY

说实话,我目前使用的架构还是 20 年那一套,基于 Docker + Watchtower 实现全自动更新,已经使用 2 年没变了,一直没啥问题,只是 4 月上去支持了下 WARP 用于访问 ChatGPT。

上次关注 Xray 的消息都还是 21 年吃分叉瓜的时候了。于是乎我跑去 Xray 项目上了解下最新的进展,可惜官网介绍不多,只能从各种 issues 中找到一些蛛丝马迹。

评估了下迁移成本后,我从 V2Ray 迁移到了 Xray,整体的架构没变,还是 Nginx 分流那套,只是网络工具变了,顺带加了一些新的协议(VLESS、Vision、gRPC)

Xray 是什么?与 V2Ray 有什么关系?

本是同根生,起源于同一个项目,后面分叉迭代了。详细请参考这篇文章 🍉

REALITY、Vision 诞生的原因是什么?

以 Trojan 为代表的 TLS 通信工具,存在 TLS in TLS 问题,「加密套娃」使得它可能具有某些统计学特征,详细分析请看这篇讨论里面的「生死 5 包」章节。

RPRX 因此还专门起了 Trojan-killer 项目,源码大家自己解读,我看了下整体的思路就是验证「加密套娃」。

XTLS、Vision、REALITY 是什么?工作原理是什么?

XTLS 是早期解决 TLS in TLS 的思路,实现上需要修改 TLS/uTLS 官方库,所以在可维护性上不被看好,但是思路验证是没问题的。

Vision 算是 XTLS 的稳定版,也是为了解决 TLS in TLS 问题,现在称它为流控,使用 xtls-rprx-vision 标识。

XTLS 和 Vision 的工作原理之前有介绍过 👉 V2Ray、Trojan、XRay

REALITY 是为了进一步消除服务端 TLS 指纹特征,解决 SNI 封锁等问题,工作原理分布在各个 issues 里面,结合项目代码我简单分析了下 REALITY 的工作原理。

整体上是依靠伪装来骗过检查者,找正规大网站借用握手包特征来伪装,然后里面加一些自己的鉴权东西,大体流程是:

  1. Server 端请求 Apple、Bing 等正常网站获取 TLS 握手期间的 Server Hello 包
  2. 拿着这个正常的握手包和 Client 交互,当然里面填充了一些 Xray 自己构造的校验内容
  3. 因为包内容被修改,所以 Client 正常无法直接处理这个 Hello 包的,需要做一些校验处理,通过后才能继续通信

整个过程单从特征上来看,都像是在和 Apple、Bing 等大网站在交互,也无法通过证书链等方式攻击,因为只是批了大网站的皮,内核其实是自己校验算法。

TLS 握手流程之前也介绍过 👉 Trojan 共用 443 端口方案的开头就是。

总的来说 REALITY 的设计思路确实比较清奇!

相关的 GitHub Issues:

获取伪装包

通信校验

Client MITM

REALITY 可能的缺点是什么?

首先是配套工具的支持,任何东西要易用、易上手才能推广开,目前支持的工具还较少。

其次是协议的打磨,目前看思路说得通,但伪装行为本身是否会带来新的特征,这个无法证伪,还需要通过时间再验证。

然后是性能,交互上多了一次 Server 端去 Apple 等网站拿握手包的过程,本身就是一次网络开销,这块还可以优化(最近的消息说是准备加缓存)。

最后是有个 issues 提到的 DNS 问题,本质上是流量分布问题。虽然交互伪装成了大网站的流量,但是 IP 是大家都能看到的,所以从统计上能看到:某个 IP 突然有了不少 Apple、Bing 等域名流量 😂,这本身是否也是一种特征?这个同样无法证伪,还需要通过时间再验证。

毕竟是个新鲜事务,我觉得可以再持续观察下,总是需要创新才能带来新的可能性 👏。

我的选择

整体的选择标准还是:安全性 > 稳定性 > 速度。

最后工具的选择是:

  1. V2Ray => Xray
  2. ClashX => Clash.Meta(Client 配置兼容)

协议的选择是:

  1. VLESS+Vision+TLS(默认,本次新增)
  2. Trojan+TCP+TLS(之前保留)
  3. VLESS+gRPC+TLS(本次新增)
  4. VMess+WebSocket+TLS+CDN(应急,之前保留)

说实话因为我不用机场,所以一直用 Trojan 都没出过问题,即使在各种敏感时期。

我觉得「网络邻居」带来的风险比各种工具协议本身的特征风险会更大一些 🙈

这次切换主要是体验下新工具以及解决潜在风险:

  1. TLS in TLS 特征:使用 Vision,也就是 xtls-rprx-vision
  2. Client TLS 指纹:ClashX 不支持 Vision(VLESS),因此迁移到了 Clash.Meta,自带了 client-fingerprint
  3. Server TLS 特征:REALITY 暂时不用,后面如果要用,我当前架构的迁移成本也很低

对比我 20 年那一套方案,新的方案没有大的变化,还是基于 Nginx 的 SNI 分流架构,容器间的通信换成了 Unix Socket,充分利用了 Fallback 实现多协议共存。

Nginx 层统一管理收敛流量入口,整个主机只用开启 443/80 和 SSH 端口即可,同时各个模块都做了伪装,「非标请求」看到的都是正常的页面,而且 WS + CDN 限定了白名单访问。只有 Client 直接访问的服务才需要处理 TLS,内部统一是 h1/h2c cleartext 协议,尽量减少 TLS 开销。

graph LR
A["Client"] -->|HTTPS Request| B("Nginx")
A["Client"] -->|HTTPS Request| B0("CDN")
B0-->|Only White List \n and No TLS|B
B -->C{"dispatch"}
C -->|SNI Socket|D["VLESS+Vision+TLS"]
C -->|SNI Socket|E["Trojan+TCP+TLS"]
C -->|SNI Socket|F["Nginx Web No TLS"]
C -->|SNI Socket|J["Other Services"]
D -->|Fallback|F
E -->|Fallback|F
F -->|Path Socket|G["VLESS+gRPC"]
F -->|Path Socket|H["VMess+WebSocket"]
F -->|Fallback|I["Default Page"]
J -->|Socket|J0["PHP"]
J -->|Socket|J1["GO"]
J -->|Socket|J2["..."]

各种组合可以参考 lxhao61/integrated-examples 项目,和我目前的比较匹配,性能优化每人不同,自己调整即可。

跑个分 🏃!

速度测试结果出乎意料。VLESS+gRPC+TLS 最拉垮我是没想到的,Multi 和 Signle 模式下速度差不多,可能是链路复用的问题 🤔️。VLESS+Vision+TLS 和 Trojan+TCP+TLS 差别不大,意料之中吧,测速场景下看不出来优势,VMess+WebSocket+TLS+CDN 中规中矩吧,反正是用来应急 🚑。

小结

个人结论依旧保持不变:目前基于 TLS 的协议才是未来的发展方向,「网络邻居」依旧是最大的风险。

虽然当前类 TLS 方案存在 TLS in TLS、Client 指纹、Server 特征等问题,但是很高兴看到目前有非常多人投身于此领域,并致力于解决这些问题。

在此过程中新的协议或者工具层出不穷,但是也请不要将自己的精力过多放在协议试验上,如果你现在用的协议没有受到干扰,那就没有必要去追求其他协议,保持关注即可。

我们的目标是自由访问互联网资源,自由获取你想要的内容,而不是传输工具本身。就像我们我们选择出发是为了感受旅程,而不是为了交通工具。