什么是 XTLS Vision?
在 TLS 隧道内部跑一个 HTTPS 会话,意味着把同一批字节加密两遍。这浪费 CPU,而且——不那么显而易见地——留下一种分类器能够识别的长度模式。XTLS Vision 就是同时解决这两点的机制。
嵌套 TLS 的问题
设想通过一条基于 TLS 的隧道加载一个普通 HTTPS 页面时会发生什么。你的浏览器为那个站点加密自己的请求。然后隧道客户端把这份已经加密的数据,为了传输再加密一遍。服务器解开外层,把依然加密的内层转发给它的目的地。
外层加密保护的是本来就已受保护的数据。代价体现在两个地方。
- 处理开销。每个字节出站时被加密两次,入站时被解密两次。在手机上这是电量;在繁忙的服务器上这是吞吐量。
- 可检测性。TLS 记录带有长度头。把一串 TLS 记录包进另一条 TLS 流里,会在内层与外层记录长度之间产生一种特征性的关系——这种模式在普通流量中不会出现,并且在公开研究中已被用于高置信度地识别嵌套 TLS。
Vision 的做法
XTLS 背后的观察是:内层数据已经被应用妥善加密过了。如果隧道能够认证这条连接,并随后识别出它所承载的东西本身就是 TLS,那么它就可以直接转发这些记录,而不必再包一层。
正常认证
会话以一条普通的 TLS 连接开始,包含完整握手及其带来的全部保护。这一阶段什么都不会被跳过。
识别出负载本身是 TLS
数据开始流动后,实现会识别出内层流本身就是 TLS——而不是需要隧道自身保护的任意明文。
直接放行记录
从那一刻起,内层记录被直接转发,不再套第二层加密。它们本来就不为隧道、也不为路径上的任何人所可读,因此不会暴露任何原本受保护的东西。
塑造可见的模式
Vision 会在会话的前段加入填充,那里正是嵌套 TLS 长度关系最明显、对分类器最有用的地方。
这个名字区分了不同世代。更早的 XTLS flow 模式实现了直通,但后来发现它们留下了各自可被检测的特征;Vision 就是修正这些问题的修订版,主要靠它的填充策略,也是当前在用的版本。
跳过一层会削弱什么吗?
这个问题问得对,而答案取决于被跳过的那一层原本在保护什么。
直通只在内层负载本身已经是 TLS 时才启用——也就是说,应用对自己的目的地有自己的端到端加密,而这本来就是隧道无论如何都读不到的。外层提供的机密性,内层早已提供过。拿掉一层多余的包装,和拿掉保护并不是一回事。
本身没有端到端加密的流量不符合直通条件,会照常在隧道自身的加密内部传输。这个判断是按连接逐条作出的,而不是对整个会话一次性决定。
真正发生变化的,是路径上观察者可见的元数据:内层记录边界变成了外层记录边界。填充存在的原因正在于此,而这是一个真实的取舍,不是白捡的好处——这也正是 Vision 取代早期 flow 模式、而非仅仅在其上扩展的原因。
这在实践中意味着什么
- 两端的 CPU 开销都更低,表现为移动端更好的续航和每台服务器更高的承载能力。
- 在以 HTTPS 为主的连接上吞吐量更高,而今天几乎所有连接都是如此。
- 消除了针对嵌套 TLS 被引用最多的那种长度特征,这是检测层面的收益。
- 对使用者而言没有任何配置负担:它是连接配置档的一个属性,不是需要你去调的东西。
Vision 通常与 REALITY 一起讨论,因为它们处理的是同一个问题的不同一半。REALITY 让连接的建立显得平平无奇;Vision 让建立之后发生的事情显得平平无奇。单用其中之一,都会留下另一个才能补上的缺口。
常见问题
XTLS 比普通 TLS 安全性更低吗?
对它所适用的那部分流量而言,并没有。直通只用于负载已被应用端到端加密的场合,因此被跳过的那一层保护的本来就是隧道无论如何都读不到的数据。没有自带加密的流量仍然保留隧道的加密。
XTLS Vision 与更早的 XTLS flow 有什么区别?
更早的 flow 模式实现了直通,但后来发现它们有各自可被检测的特征。Vision 是修正这些问题的修订版,主要手段是在会话前段加入填充——那里正是嵌套 TLS 长度模式最明显的位置。
我需要同时用 REALITY 和 Vision 吗?
它们解决的是不同问题:REALITY 关乎连接如何建立、以及端点如何回应一个陌生人;Vision 关乎流量开始传输之后的形态。它们常被一起使用,因为各自都会留下对方才能补上的缺口。