v2ray / v2ray-core

A platform for building proxies to bypass network restrictions.
https://www.v2ray.com/
MIT License
45.31k stars 8.94k forks source link

[New Protocol] VLESS BETA:性能至上、可扩展性空前,目标是全场景终极协议。 #2636

Closed RPRX closed 2 years ago

RPRX commented 4 years ago

官网文档:https://www.v2fly.org/config/protocols/vless.html

终极配置:VLESS over TCP with XTLS + 回落 & 分流 to WHATEVER


2020-07-31 更新:VLESS PREVIEW 1.1 已于两天前合并进 v2ray-core 公测,将出现在 v4.27.0 版本中。

2020-07-23 更新:加入了判断首包长度(原创)的协议回落模式,PREVIEW 版本将很快发布(在此之后,BETA 系列仍会继续)。


这份说明本来应该于一周前 VLESS BETA 发布时就写好的,但因为实在是很麻烦(每次写说明比写代码麻烦多了),所以就鸽到了今天。。。不过上次也差不多。与上一份说明 #2583 不同,这次更加注重 VLESS 本身的设计。

代码在 rprx/v2ray-vless,它是 v2fly/v2ray-core 的超集,只是多了 VLESS 协议,其它的完全一样。releases 已补充历版 VLESS Changes,有已编译好的 Windows & Linux x64 版本,交叉编译可参考 https://github.com/v2ray/discussion/issues/756

若你正在使用 TLS,简单地将 VMess 改为 VLESS 就可以获得性能提升:

  1. 替换服务端和客户端的可执行文件。
  2. 将两边的协议都改为 "vless",具体参考 VLESS 配置文档,相较于 VMess 的只有少许改动。

这只是 VLESS 的短期意义,它的长期意义是:可扩展性空前,适合随意组合、全场景广泛使用,符合很多人的设想、几乎所有人的需求,足以成为 v2ray 的下一代主要协议,乃至整个 XX 界的终极协议。

那么,是时候更新一下对 VLESS 的认知了。

Request & Response

1 字节 16 字节 1 字节 M 字节 1 字节 2 字节 1 字节 S 字节 X 字节
协议版本 等价 UUID 附加信息长度 M 附加信息 ProtoBuf 指令 端口 地址类型 地址 请求数据
1 字节 1 字节 N 字节 Y 字节
协议版本,与请求的一致 附加信息长度 N 附加信息 ProtoBuf 响应数据

VLESS 早在第二个测试版 ALPHA 2 时就已经是上述结构了(BETA 是第五个测试版):

“响应认证”被替换为“协议版本”并移至最前,使 VLESS 可以升级换代,同时消除了生成伪随机数的开销。混淆相关结构被替换为附加信息(ProtoBuf)并前移,赋予协议本身可扩展性,相关开销也极小(gogo/protobuf),若无附加信息则无相关开销。

我一直觉得“响应认证”不是必要的,ALPHA 时为了提升生成随机数的性能,还用 math/rand 替换 crypto/rand,而现在都不需要了。

“协议版本”不仅能起到“响应认证”的作用,还赋予了 VLESS 无痛升级协议结构的能力,带来无限的可能性。 “协议版本”在测试版本中均为 0,正式版本中为 1,以后若有不兼容的协议结构变更则应升级版本。

VLESS 服务端的设计是 switch version,即同时支持所有 VLESS 版本。若需要升级协议版本(可能到不了这一步),推荐的做法是服务端提前一个月支持,一个月后再改客户端。VMess 请求也有协议版本,但它的认证信息在外面,指令部分则高度耦合且有固定加密,导致里面的协议版本毫无意义,服务端也没有进行判断,响应则没有协议版本。Trojan 的协议结构中没有协议版本。

接下来是 UUID,我本来觉得 16 字节有点长,曾经考虑过缩短它,但后来看到 Trojan 用了 56 个可打印字符(56 字节),就彻底打消了这个念头。服务端每次都要验证 UUID,所以性能也很重要:VLESS 的 Validator 经历了多次重构/升级,相较于 VMess,它十分简洁且耗资源很少,可以同时支持非常多的用户,性能也十分强悍,验证速度极快(sync.Map)。API 动态增删用户则更高效顺滑。

引入 ProtoBuf 是一个创举,等下会详细讲解。“指令”到“地址”的结构目前与 VMess 完全相同,同样支持 Mux。

总体上,ALPHA 2 到 BETA 主要是:结构进化、清理整合、性能提升、更加完善。这些都是一点一滴的,详见 VLESS Changes

ProtoBuf

似乎只有 VLESS 可选内嵌 ProtoBuf,它是一种数据交换格式,信息被紧密编码成二进制,TLV 结构(Tag Length Value)。

起因是我看到一篇文章称 SS 有一些缺点,如没有设计错误回报机制,客户端没办法根据不同的错误采取进一步的动作。 (但我并不认同所有错误都要回报,不然防不了主动探测。下一个测试版中,服务器可以返回一串自定义信息。) 于是想到一个可扩展的结构是很重要的,未来它也可以承载如动态端口指令。不止响应,请求也需要类似的结构。 本来打算自己设计 TLV,接着发觉 ProtoBuf 就是此结构、现成的轮子,完全适合用来做这件事,各语言支持等也不错。

目前“附加信息”只有 Scheduler 和 SchedulerV,它们是 MessName 和 MessSeed 的替代者,当你不需要它们时,“附加信息长度”为 0,也就不会有 ProtoBuf 序列化/反序列化的开销。其实我更愿意称这个过程为“拼接”,因为 pb 实际原理上也只是这么做而已,相关开销极小。拼接后的 bytes 十分紧凑,和 ALPHA 的方案相差无几,有兴趣的可以分别输出并对比。

为了指示对附加信息(Addons,也可以理解成插件,以后可以有很多个插件)的不同支持程度,下个测试版会在“附加信息长度”前新增“附加信息版本”。256 - 1 = 255 字节是够用且合理的(65535 就太多了,还可能有人恶意填充),现有的只用了十分之一,以后也不会同时有那么多附加信息,且大多数情况下是完全没有附加信息的。真不够用的话,可以升级 VLESS 版本。

为了减少逻辑判断等开销,暂定 Addons 不使用多级结构。一个月前出现过“可变协议格式”的想法,pb 是可以做到打乱顺序,但没必要,因为现代加密的设计不会让旁观者看出两次传输的头部相同。

下面介绍 Schedulers 和 Encryption 的构想,它们都是可选的,一个应对流量时序特征问题,一个应对密码学上的问题。

Schedulers Flow

中文名暂称:流量调度器(2020-09-03 更新:中文名确定为“流控”),指令由 ProtoBuf 承载,控制的是数据部分。

我之前发现,VMess 原有的 shake “元数据混淆”在 TLS 上完全不会带来有意义的改变,只会降低性能,所以 VLESS 弃用了它。并且,“混淆”这个表述容易被误解成伪装,也弃用了。顺便一提,我一直是不看好伪装的:做不到完全一样,那不就是强特征吗?做得到完全一样,那为什么不直接用伪装目标?我一开始用的是 SSR,后来发现它只是表面伪装骗运营商,就再也没用过了。

那么,“流量调度器”要解决什么问题?它影响的是宏观流量时序特征,而不是微观特征,后者是加密要解决的事情。流量时序特征可以是协议带来的,比如 Socks5 over TLS 时的 Socks5 握手 ,TLS 上不同的这种特征对于监测者来说就是不同的协议,此时无限 Schedulers 就相当于无限协议(重新分配每次发送的数据量大小等)。流量时序特征也可以是行为带来的,比如访问 Google 首页时加载了多少文件、顺序、每个文件的大小,多套一层加密并不能有效掩盖这些信息。

Schedulers 没必要像下面的 Encryption 一样整个套在外面,因为头部的一丁点数据相对于后面的数据量来说太微不足道了。

BETA 2 预计推出两个初级的 Scheduler:Zstd 压缩、数据量动态扩充。进阶操作才是从宏观层面来控制、分配,暂时咕咕。

Encryption

与 VMess 的高度耦合不同,VLESS 的服务端、客户端不久后可以提前约定好加密方式,仅在外面套一层加密。这有点类似于使用 TLS,不影响承载的任何数据,也可以理解成底层就是从 TLS 换成预设约定加密。相对于高度耦合,这种方式更合理且灵活:一种加密方式出了安全性问题,直接扔掉并换用其它的就行了,十分方便。VLESS 服务端还会允许不同的加密方式共存。

对比 VMess,VLESS 相当于把 security 换成 encryption,把 disableInsecureEncryption 换成 decryption,就解决了所有问题。目前 encryption 和 decryption 只接受 "none" 且不能留空(即使以后有连接安全性检查),详见 VLESS 配置文档。encryption 并不需要往外移一级,一是因为无法复用很多代码,二是因为会影响控制粒度,看未来的应用就明白了。

加密支持两类形式,一类是加密完全独立,需要额外密码,适合私用,另一类是结合已有的 UUID 来加密,适合公用。 (若用第一类加密形式,且密码是以某种形式公开的,比如多人共用,那么中间人攻击就不远了) 重新设计的动态端口可能会随加密同时推出,指令由 ProtoBuf 承载,具体实现和 VMess 的动态端口也会有很多不同。

套现成加密是件很简单的事情,也就多一层 writer & reader。BETA 3 预计支持 SS 的 aes-128-gcm 和 chacha20-ietf-poly1305: 客户端的 encryption 可以填 “auto: ss_aes-128-gcm_0_123456, ss_chacha20-ietf-poly1305_0_987654”,auto 会选择最适合当前机器的,0 代表测试版,最后的是密码。服务端的 decryption 也是类似填法,收到请求时会逐一尝试解密。

并不是所有组合都需逐一尝试:VMess 的加密分为三段,第一段是认证信息,结合了 UUID、alterId、时间因素,第二段是指令部分,以固定算法加密,指令中含有数据部分使用的加密算法,第三段才是重要的数据部分。可以看出,VMess 的加解密方式实际上是多对一(服务端适配),而不仅是结合 UUID。但仅是结合 UUID 来加密也是件相对麻烦的事情,短时间内不会出,鉴于我们现在有 VMessAEAD 可用,也并不着急。若 VLESS 推出了结合 UUID 的加密方式,相当于重构了整个 VMess。

UDP issues

由于 VLESS 是对 VMess 的精简且同样存在于 v2ray 中,目前 VLESS 的 UDP 能力与 VMess 完全相同,也就是:

  1. 整个 v2ray 对 UDP 的处理广泛存在问题,这是影响 FullCone 实现的障碍之一,参考 https://github.com/v2ray/v2ray-core/issues/1429#issuecomment-549667805
  2. VMess 没有为 UDP 建立持久的隧道,这是影响 FullCone 实现的障碍之二,参考 https://trojan-gfw.github.io/trojan/protocol
  3. VMess 只支持 UDP over TCP,不支持直接 UDP(至于 mKCP、QUIC,它们不属于 VMess,且 UDP 实际上经历了两次转换)

对于第一个问题,要改 v2ray 很多地方的代码,希望 @xiaokangwang 大佬可以解决。

对于第二个问题,我先几句话讲清突破本地的层层 NAT 限制实现 FullCone 的原理:

简单来说就是把远端 VPS 的一些 UDP 端口“映射”到本机,使其效果完全等同于本机的端口(但本机的端口并不一定被实际占用)。因为 VPS 一般都是有公网 IP 的,NAT 环境最佳,核心原理就是利用 VPS 的公网 IP 来提升本机的 NAT 等级,或者某个游戏/应用的实际 NAT 等级。此时它们使用的实际上是远端 VPS 的端口,就绕过了本地的层层 NAT 限制。而要做到保持映射,至少连接要保持住。

VLESS BETA 系列后期,预计客户端可选:

"udp": {
    "nat": "origin" / "tunnel" / "tunnels",
    "tcp": true / false
}

Sharing link

为了避免 VMess 分享链接生态混乱的情况,VLESS 要求图形客户端等仅支持官方分享链接标准,即将出炉。

一开始,我只是简化了 VMess,并推出 VLESS 协议,追求性能极限,不断进行优化,同时注重可扩展性,为下一步铺路。

而现在,不同于前几个版本主要做减法,BETA 系列的目标是好好利用可扩展性,做可选的加法,成为终极协议。

我一直在强调,这些加法都是可选的,如果你不需要那就不用开启,并不影响性能极限,这也是最重要的、贯穿始终的。

到处可扩展、可组合、层层完美解耦不失性能,并不只是我一个人的设想,很多人都是这么想的,这个解决方案可以使所有人满意。

而 VLESS 将会成为有史以来可解耦性(性能)、可扩展性(功能)、安全性等都最强大、完美的终极协议,一个协议解决所有问题。

当然,这也离不开 v2ray 已有的模块,感谢大家的贡献。我相信对于 v2ray 来说,这也会是一个全新的开始。

若还有什么没考虑到的情况,欢迎提出改进建议,这个 issue 还会持续跟进 VLESS 的更新。

LESS IS MORE.

RPRX commented 4 years ago

现实例子:https://github.com/hq450/fancyss/issues/1022#issuecomment-684874868

cjwddtc commented 4 years ago

关于提升1rtti延迟,从文档里没看出哪里能够提升1rtti,可否说明下? 关于性能的问题,只能说看问题的角度不一样,就像我前面说的,工具本身的性能瓶颈毕竟在加解密上面,其他方面的优化能做的提升就很有限,即使优化了,比如那个实际的例子,我直接换成ss+obfs+chacha20,直接40mbps+,即使aes也能跑30mbps+,因为换工具>换协议,真的一定要arm翻墙的,真的建议ss-libev比较好,至少在那个xtls做出来之前是这样。

RPRX commented 4 years ago

关于提升1rtti延迟,从文档里没看出哪里能够提升1rtti,可否说明下? 关于性能的问题,只能说看问题的角度不一样,就像我前面说的,工具本身的性能瓶颈毕竟在加解密上面,其他方面的优化能做的提升就很有限,即使优化了,比如那个实际的例子,我直接换成ss+obfs+chacha20,直接40mbps+,即使aes也能跑30mbps+,因为换工具>换协议,真的一定要arm翻墙的,真的建议ss-libev比较好,至少在那个xtls做出来之前是这样。

减少 1-RTT 指的是去掉 WS,后者是 VMess 现在最流行的用法。

其实你总是提到换用 SS,当然可以,那 TLS 的隐蔽性和目前的抗封锁性就直接扔了?性能并不是唯一的选择因素,但在选择 TLS 的前提下,表现当然是越优越好。

xTLS 即将出炉(我现在就在写它的代码)。

RPRX commented 4 years ago

另外问那个生产环境那个,你不要想太多,生产环境可以参考v2ray开发了多久才开始有机场支持vmess。好几年前了,我也不记得了。反正至少要等标题中那个大大的beta没了之后才有可能。

基于已有生态,机场后端已经开始纷纷支持 VLESS 了,虽然我并不希望它过快普及。

cjwddtc commented 4 years ago

性能的确不是唯一的选择因素,但是目前并没有任何明确的证据直接表明tls有更好的穿过防火墙的能力,没有人真的测试过tls的抗封锁效果,ss被封了换tls没事并不能证明tls有更好的抗封锁能力,和运气以及gfw刚好搞事情有很大的关联度。 我当然理解tls理论上有更好的抗封锁性,但是理论和实际是两码事,事实上搬瓦工自家的just my socks到现在还在提供ss的服务,有很多机场仍然在使用ss和ssr作为翻墙的协议,如果性能足够,使用tls多一份保障当然是好的,事实上我也在用。但是当性能并不足够的时候仅仅因为一个猜测就要网速砍半,还是40m变20m显然非常不划算。

ghost commented 4 years ago

性能的确不是唯一的选择因素,但是目前并没有任何明确的证据直接表明tls有更好的穿过防火墙的能力,没有人真的测试过tls的抗封锁效果,ss被封了换tls没事并不能证明tls有更好的抗封锁能力,和运气以及gfw刚好搞事情有很大的关联度。 我当然理解tls理论上有更好的抗封锁性,但是理论和实际是两码事,事实上搬瓦工自家的just my socks到现在还在提供ss的服务,有很多机场仍然在使用ss和ssr作为翻墙的协议,如果性能足够,使用tls多一份保障当然是好的,事实上我也在用。但是当性能并不足够的时候仅仅因为一个猜测就要网速砍半,还是40m变20m显然非常不划算。

机场和个人vps用户很不一样,你不能这么比。 首先机场一台vps要提供很多服务,性能瓶颈在服务器。个人vps,性能瓶颈大多数在客户端。所以机场会选择性能更强的ss,以节约服务器成本。这是第一。 其次,机场往往不需要考虑抗封锁问题,因为当它向外提供服务的时候,就已经告诉所有人,”我这个服务器是翻墙用的“。这个时候再用tls和web伪装,又有什么意义呢? 第三,机场是比较大的,运维是很麻烦的,不像个人vps用户,没有配置好可以自己多花一点时间去配置。而机场要保证对外提供服务,ss/ssr配置简单,自然成为了第一选择。

RPRX commented 4 years ago

性能的确不是唯一的选择因素,但是目前并没有任何明确的证据直接表明tls有更好的穿过防火墙的能力,没有人真的测试过tls的抗封锁效果,ss被封了换tls没事并不能证明tls有更好的抗封锁能力,和运气以及gfw刚好搞事情有很大的关联度。

我感觉这个已经有点反智了,目前基于 TLS 的代理比 SS 这类代理更抗封锁是长期经验与常识,包括特殊时期仍然可用。

可以看一下 Trojan-Go 的介绍:https://p4gefau1t.github.io/trojan-go/basic/trojan/

badO1a5A90 commented 4 years ago

性能的确不是唯一的选择因素,但是目前并没有任何明确的证据直接表明tls有更好的穿过防火墙的能力,没有人真的测试过tls的抗封锁效果,ss被封了换tls没事并不能证明tls有更好的抗封锁能力,和运气以及gfw刚好搞事情有很大的关联度。

我感觉这个已经有点反智了,目前基于 TLS 的代理比 SS 这类代理更抗封锁是长期经验与常识,包括特殊时期仍然可用。

可以看一下 Trojan-Go 的介绍:https://p4gefau1t.github.io/trojan-go/basic/trojan/

所以VLESS over TCP with TLS + 回落,现在是最安全同时性能还可以最高的模式。 被动主动探测都有抗性。速度上限高,延迟低。 接下来比较期待TLS的加强,除了去掉TLS over TLS,还希望有TLS版本和加密套件(现在都不可选)方面的增强。

cjwddtc commented 4 years ago

我很清楚地知道tls和ss的区别,我早就说过我很明确的清楚tls理论上有更好的效果,或者说在面对某一种封锁方式时有更好的效果,但是事实上没有人知道gfw是怎么工作的,说句不客气的话,那个的主动探测,真的有人抓到过gfw发来的主动探测的数据包了吗?我当然知道tls面对主动探测可以以假乱真,但是你怎么知道gfw真的采用了这种手段?自己全靠猜测全无证据,给自己观点加持一个”长期经验“就说别人反智?可能我智力不够,你智力足够高到不需要实验证据,猜测是啥就是啥,或者作过gfw相关的技术吧。

另外ss也有类似的手段就是tls混淆,我相信如果just my socks的ss很快就会被封禁,tls却总能安然无恙,官方一定不会一直头铁换ip然后继续提供ss的服务。just my socks也在频繁的更换节点的配置,看上去像试图再找出一个比较稳定的方法。

另外关于机场不需要混淆的问题,并非如此,机场骗过的也是gfw(白名单和iplc不算),大部分机场(尤其大机场)都需要付款才能看到翻墙服务器的域名,甚至对自身的节点ip和域名都会做出很严格的限制(比如禁止散播机场服务器的ip和域名,包括官方tg群中也不允许发送包含ip和域名的图片),所以机场同样需要伪装。

badO1a5A90 commented 4 years ago

我很清楚地知道tls和ss的区别,我早就说过我很明确的清楚tls理论上有更好的效果,或者说在面对某一种封锁方式时有更好的效果,但是事实上没有人知道gfw是怎么工作的,说句不客气的话,那个的主动探测,真的有人抓到过gfw发来的主动探测的数据包了吗?我当然知道tls面对主动探测可以以假乱真,但是你怎么知道gfw真的采用了这种手段?自己全靠猜测全无证据,给自己观点加持一个”长期经验“就说别人反智?可能我智力不够,你智力足够高到不需要实验证据,猜测是啥就是啥,或者作过gfw相关的技术吧。

主动探测应该是有的,例如参考 https://gfw.report/blog/gfw_shadowsocks/ https://ensa.fi/active-probing/

cjwddtc commented 4 years ago

我承认,确实我用ws+tls从没有被封过,我自建的翻墙最近一段时间也一直用的这套配置,因为我觉得这套配置确实很牛逼可以无法被发现,但是如果说就必须用ac68u科学上了,换了ss速度能从20m提升到40m,我觉得至少在非敏感时期可以用ss来提高自己的速度。20m和40m区别还是很大的。 你是代码贡献者,我只是个白嫖的,我一直很尊重你们的贡献,也很认可这些内容的价值,我只是从用户的角度给用户提出一些建议,并没有认为这些工作没有用。 我从来没有否认你们工作的价值和tls的作用,因为我不是开发者,我更多的是从使用者的角度考虑问题,如上面的链接所说,ss并不是一定会被封锁,使用ss以提高速度是一个很好的选择,这并不涉及到ss和v2ray工具的优劣,事实上我已经快3年没有用过ss了,但是在速度真的很慢(比如ac68u)的情况下,确实v2ray是一个痛点。

RPRX commented 4 years ago

xTLS 已完成测试,只剩与 VLESS 的深度整合,以及进一步优化算法,痛点可被解决。

RPRX commented 4 years ago

服务端使用 xTLS 的网站仍可接收正常请求。

相信以后众多代理协议将进入选择性不加密的新时代,相比原来,可以去掉 80% 以上的加密开销。

对于路由器、服务器等中间设备,几乎只剩简单的数据传输。

此外,毫无疑问,开销比 SS 更少。

ghost commented 4 years ago

xTLS 已完成测试,只剩与 VLESS 的深度整合,以及进一步优化算法,痛点可被解决。

这么快的吗??

RPRX commented 4 years ago

xTLS 已完成测试,只剩与 VLESS 的深度整合,以及进一步优化算法,痛点可被解决。

这么快的吗??

是的,几个小时就写完且测试完了,本来就是很简单的原理。

ghost commented 4 years ago

xTLS 已完成测试,只剩与 VLESS 的深度整合,以及进一步优化算法,痛点可被解决。

突然想到一个问题,假如你和v2ray服务端之间使用的加密方式是唯一的,比如tls 1.3 AES_128_GCM,而你和不同网站之间使用的加密方式多种多样。这样会不会形成特征?

RPRX commented 4 years ago

xTLS 已完成测试,只剩与 VLESS 的深度整合,以及进一步优化算法,痛点可被解决。

突然想到一个问题,假如你和v2ray服务端之间使用的加密方式是唯一的,比如tls 1.3 AES_128_GCM,而你和不同网站之间使用的加密方式多种多样。这样会不会形成特征?

不会的,TLS 的加密方式,密文部分都接近于随机数。

XTLS 今天又迭代了一个版本,改进了算法,绝大多数 TLS 数据包都无需二次加密了,包括分几次才能收完的很长的包(写了缓存策略)。但发现其中 YouTube 视频的长包(16406)长期来看可能会成为特征,所以打算继续修改,彻底重组 TLS 数据包。

badO1a5A90 commented 4 years ago

xTLS 已完成测试,只剩与 VLESS 的深度整合,以及进一步优化算法,痛点可被解决。

突然想到一个问题,假如你和v2ray服务端之间使用的加密方式是唯一的,比如tls 1.3 AES_128_GCM,而你和不同网站之间使用的加密方式多种多样。这样会不会形成特征?

不会的,TLS 的加密方式,密文部分都接近于随机数。

XTLS 今天又迭代了一个版本,改进了算法,绝大多数 TLS 数据包都无需二次加密了,包括分几次才能收完的很长的包(写了缓存策略)。但发现其中 YouTube 视频的长包(16406)长期来看可能会成为特征,所以打算继续修改,彻底重组 TLS 数据包。

是因为不符合普通网站的表现吗(访问普通网站不应该一直有这种长包)?那也就是说现在也存在这样的特征。

RPRX commented 4 years ago

是因为不符合普通网站的表现吗(访问普通网站不应该一直有这种长包)?

是的。

那也就是说现在也存在这样的特征。

没有,V2Ray 的单个 buffer size 为 2048,经测试,V2Ray 的 TLS 数据包长度一般最大为 2070(此时应该是 5 + 2048 + 17)。

但是 2070 刷屏极大可能成为 V2Ray 独有特征了(会暴露 2048 这个值),如果只有 V2Ray 是这样的话。

RPRX commented 4 years ago

我看了下 uTLS 的代码,也没有修改 TLS 核心传输部分,那么 TLS 数据包长度特征应该是基于 TLS 的代理普遍存在的问题。

网站的 TLS 数据包长度不一,印象中 1208 比较常见(应该是 5 + 1186 + 17),但也可能只有 Google 是这样。

mclovin-2k commented 4 years ago

Can't wait.

ghost commented 4 years ago

@rprx 新型协议回落模式 能否新增sni匹配的 这样能把nginx丢掉

ghost commented 4 years ago

我看了下 uTLS 的代码,也没有修改 TLS 核心传输部分,那么 TLS 数据包长度特征应该是基于 TLS 的代理普遍存在的问题。

网站的 TLS 数据包长度不一,印象中 1208 比较常见(应该是 5 + 1186 + 17),但也可能只有 Google 是这样。

使用nginx+tls 1.3(openssl 1.1.1) 的数据包长度是多少?

judawu commented 4 years ago

@rprx 关于fallback我不是太理解,能否解释一下。比如我的Client有3个 Vless, Vless1 是Vlless+TCP+TLS, Vless2是VLess+WS+TLS, Vless3是VLess+H2+TLS, 然后我把端口都指向Server的Vless1的444, 在Server上我也配置了3个Vless, Vless1 是Vlless+TCP+TLS 端口444, Vless2是VLess+WS+TLS 端口445, Vless3是VLess+H2+TLS 端口446 . 在Vless1上我设置了Fallbck ` "fallbacks": [ { "path": "/ws/", "dest": 445, "xver": 1 }, { "alpn": "h2", "dest": 446, "xver": 1 }, { "dest": 443 } ]

` 但是我的Vless2和Vless3却没法访问网页,然后我将Nginx配置监听443并转发ws到445, Vless2和Vless3还是不能上网,难道说Vless1,Vless2,vless3的UUID必须一样吗?

ghost commented 4 years ago

@rprx 关于fallback我不是太理解,能否解释一下。比如我的Client有3个 Vless, Vless1 是Vlless+TCP+TLS, Vless2是VLess+WS+TLS, Vless3是VLess+H2+TLS, 然后我把端口都指向Server的Vless1的444, 在Server上我也配置了3个Vless, Vless1 是Vlless+TCP+TLS 端口444, Vless2是VLess+WS+TLS 端口445, Vless3是VLess+H2+TLS 端口446 . 在Vless1上我设置了Fallbck ` "fallbacks": [ { "path": "/ws/", "dest": 445, "xver": 1 }, { "alpn": "h2", "dest": 446, "xver": 1 }, { "dest": 443 } ]

` 但是我的Vless2和Vless3却没法访问网页,然后我将Nginx配置监听443并转发ws到445, Vless2和Vless3还是不能上网,难道说Vless1,Vless2,vless3的UUID必须一样吗?

作者说了详细说明之后会写。你可以先参考一下这个:https://github.com/v2fly/v2ray-examples/blob/master/VLESS-TCP-TLS-WS%20(recommended)/config_server.json

RPRX commented 4 years ago

@rprx 新型协议回落模式 能否新增sni匹配的 这样能把nginx丢掉

之前也有人提过这个功能,可以做到,但似乎。。。有点越界,还是先用 Nginx 分流 SNI 比较好?

RPRX commented 4 years ago

我看了下 uTLS 的代码,也没有修改 TLS 核心传输部分,那么 TLS 数据包长度特征应该是基于 TLS 的代理普遍存在的问题。 网站的 TLS 数据包长度不一,印象中 1208 比较常见(应该是 5 + 1186 + 17),但也可能只有 Google 是这样。

使用nginx+tls 1.3(openssl 1.1.1) 的数据包长度是多少?

没测过。目前 XTLS 又确定了新的实现方案,若启用了 XTLS,则不会有这种 TLS 数据包长度十分统一的特征了(如 2070 刷屏)。

ghost commented 4 years ago

我看了下 uTLS 的代码,也没有修改 TLS 核心传输部分,那么 TLS 数据包长度特征应该是基于 TLS 的代理普遍存在的问题。 网站的 TLS 数据包长度不一,印象中 1208 比较常见(应该是 5 + 1186 + 17),但也可能只有 Google 是这样。

使用nginx+tls 1.3(openssl 1.1.1) 的数据包长度是多少?

没测过。目前 XTLS 又确定了新的实现方案,若启用了 XTLS,则不会有这种 TLS 数据包长度十分统一的特征了(如 2070 刷屏)。

我有点担心,就算长度不统一会不会也形成特征。因为不统一也可能有一定的规律可循,假设nginx的长度变化规律是一种特征,apache的长度变化规律是一种特征,v2ray的长度变化规律是一种特征。甚至有可能出现v2ray根据nginx的长度变化规律进行了伪装,但是回落的服务器却是apache,,,也可能是我多虑了。

ghost commented 4 years ago

我看了下 uTLS 的代码,也没有修改 TLS 核心传输部分,那么 TLS 数据包长度特征应该是基于 TLS 的代理普遍存在的问题。

网站的 TLS 数据包长度不一,印象中 1208 比较常见(应该是 5 + 1186 + 17),但也可能只有 Google 是这样。

google有使用http3,抓包的时候记得把quic关了,可能会产生影响

RPRX commented 4 years ago

我有点担心,就算长度不统一会不会也形成特征。因为不统一也可能有一定的规律可循,假设nginx的长度变化规律是一种特征,apache的长度变化规律是一种特征,v2ray的长度变化规律是一种特征。甚至有可能出现v2ray根据nginx的长度变化规律进行了伪装,但是回落的服务器却是apache,,,也可能是我多虑了。

一般来说取决于一次性收回的明文数据长度(所以即使 v2 后置,流量应该也会 2070 刷屏),会有一个最大长度而没有“变化规律”,但现在后端部署模式复杂多样,仅凭探测后返回的最大 TLS 数据包长度很难确定异常。即使有一天 GFW 根据这个来封 IP,简单改改参数就可以解决。另外,XTLS 顺便解决的是实际流量中 TLS 数据包长度 2070 刷屏的问题,而不是主动探测(至少目前不包括)。

badO1a5A90 commented 4 years ago

我有点担心,就算长度不统一会不会也形成特征。因为不统一也可能有一定的规律可循,假设nginx的长度变化规律是一种特征,apache的长度变化规律是一种特征,v2ray的长度变化规律是一种特征。甚至有可能出现v2ray根据nginx的长度变化规律进行了伪装,但是回落的服务器却是apache,,,也可能是我多虑了。

一般来说取决于一次性收回的明文数据长度(所以即使 v2 后置,流量应该也会 2070 刷屏),会有一个最大长度而没有“变化规律”,但现在后端部署模式复杂多样,仅凭探测后返回的最大 TLS 数据包长度很难确定异常。即使有一天 GFW 根据这个来封 IP,简单改改参数就可以解决。另外,XTLS 顺便解决的是实际流量中 TLS 数据包长度 2070 刷屏的问题,而不是主动探测(至少目前不包括)。

很随意的看了一些网站,发现长度并没有统一规律,并且看视频/直播,比如iqiyi,douyu,也都是16408的长包(为何和你差了2字节),所以长度也不是问题?(当然长时间16408但是代理的伪装网站不是视频网站确实就很可疑)。

不过这样看来v2ray现在都是5+2065好像反而成为了特征。。。(是否需要先改进一下?)

badO1a5A90 commented 4 years ago

包长度上限貌似只是由谁来处理TLS决定。 因为后置v2,前置nginx,但由nginx处理TLS的话,包长度上限不是2070,比如我用我的代理服务器前置nginx处理TLS翻墙,看youtube时是长包16401上限(这个轻微变化的上限值由什么引起),也就是说,包长度上限由nginx决定了。

RPRX commented 4 years ago

@badO1a5A90

TLS 规定每个 data record 的明文长度最大是 16384,所以对于小包,长度没有统一规律,而最大值都在 16400 多。 Nginx 应该是有一些缓存策略。目前看来,v2ray 的 2070 需要被改掉,不仅仅是服务端,还有客户端的发包。 (其实最简单的办法是把 common/buf/buffer.go 的 Size 调大,如果不改这里,则只能改 TLS 的代码了)

好消息是既然顶格长包很常见,那么 XTLS 可以沿用现在的思路,而不用另寻他路(已经又想了两种实现了,累计七八种)。

badO1a5A90 commented 4 years ago

@badO1a5A90

TLS 规定每个 data record 的明文长度最大是 16384,所以对于小包,长度没有统一规律,而最大值都在 16400 多。 Nginx 应该是有一些缓存策略。目前看来,v2ray 的 2070 需要被改掉,不仅仅是服务端,还有客户端的发包。 (其实最简单的办法是把 common/buf/buffer.go 的 Size 调大,如果不改这里,则只能改 TLS 的代码了)

好消息是既然顶格长包很常见,那么 XTLS 可以沿用现在的思路,而不用另寻他路(已经又想了两种实现了,累计七八种)。

目前的观测常见在于视频流,并且都为最长上限的包长度,这个可以确定。 浏览普通网页似乎不多见(样本并不足,不能定论),且毫无规律。

但如果翻墙看视频时(这是个常见需求),连接到代理服务器均为16000+,而用于伪装的网站并非视频网站,从墙看来可以判定为这是不合理的。 所以似乎还应该有更合理的伪装方式?

RPRX commented 4 years ago

但如果翻墙看视频时(这是个常见需求),连接到代理服务器均为16000+,而用于伪装的网站并非视频网站,从墙看来可以判定为这是不合理的。

大文件应该都是 16400+,且之前的 WSS 部署模式,这种包很常见。(而且若以此判定,各种 TLS 代理的流量大小早就不合理了)

badO1a5A90 commented 4 years ago

但确实现在如果翻墙看视频,一溜的2070可以说是强特征了。

RPRX commented 4 years ago

但确实现在如果翻墙看视频,一溜的2070可以说是强特征了。

是的,所以以后应该广泛应用 XTLS(因为现在客户端发的包也是最大 2070,WSS 可能也差不多)。

badO1a5A90 commented 4 years ago

但确实现在如果翻墙看视频,一溜的2070可以说是强特征了。

是的,所以以后应该广泛应用 XTLS(因为现在客户端发的包也是最大 2070,WSS 可能也差不多)。

我倒是觉得是不是应该非XTLS的情况下也先修正比较好,毕竟不能短时间内要求每个人都用XTLS

RPRX commented 4 years ago

我倒是觉得是不是应该非XTLS的情况下也先修正比较好,毕竟不能短时间内要求每个人都用XTLS

因为 v2ray 还有非 TLS 的传输方式,改调用 TLS 之前的代码会对它们造成一些影响。

RPRX commented 4 years ago

(之前我认为顶格长包和 v2ray 的 2070 都是不合理的,但现在发现前者很常见,而后者的确还是不合理。

RPRX commented 4 years ago

目前 XTLS 计划分为两步使用:

  1. security 填写 xtls,明文上限将为 16384,服务端和客户端都可以消除发出大量数据时 2070 刷屏的这种特征。
  2. VLESS 的 schedulers(流控)填写 xtls 之类的文本,可以启用 XTLS 的避免二次加密等进阶功能。
badO1a5A90 commented 4 years ago

(之前我认为顶格长包和 v2ray 的 2070 都是不合理的,但现在发现前者很常见,而后者的确还是不合理。

观测了一下,顶格长包确实不少见,比如图片较多的网站,实际数据长度一般常见上限是16408.(没+5)

服务器的配置可以影响这个包长度上限,比如nginx的ssl_buffer_size(nginx默认是16K,与maximum TLS record size一样。) 查看了一些资料,很多CDN还支持动态优化这个值,可以配置TLS record size的上下限(非用户自行配置)

ghost commented 4 years ago

(之前我认为顶格长包和 v2ray 的 2070 都是不合理的,但现在发现前者很常见,而后者的确还是不合理。

观测了一下,顶格长包确实不少见,比如图片较多的网站,实际数据长度一般常见上限是16408.(没+5)

服务器的配置可以影响这个包长度上限,比如nginx的ssl_buffer_size(nginx默认是16K,与maximum TLS record size一样。) 查看了一些资料,很多CDN还支持动态优化这个值,可以配置TLS record size的上下限(非用户自行配置)

是否考虑v2ray服务端主动探测回落服务器,根据回落服务器的包长规律来确定包长规律

RPRX commented 4 years ago

是否考虑v2ray服务端主动探测回落服务器,根据回落服务器的包长规律来确定包长规律

这个。。。真的没有“规律”,收回多少发多少,或者就是有缓存,或达到了最大值。

大多数 Web 服务器应该默认是 16384(且带缓存?),XTLS 也进行这样的处理就解决这个问题了。

RPRX commented 4 years ago

其实 Golang TLS 库自带 buffer 设置,应该可以把它利用起来。(又看了看,不是自动化的,不太合适。

badO1a5A90 commented 4 years ago

是否考虑v2ray服务端主动探测回落服务器,根据回落服务器的包长规律来确定包长规律

这个。。。真的没有“规律”,收回多少发多少,或者就是有缓存,或达到了最大值。

大多数 Web 服务器应该默认是 16384(且带缓存?),XTLS 也进行这样的处理就解决这个问题了。

(之前我认为顶格长包和 v2ray 的 2070 都是不合理的,但现在发现前者很常见,而后者的确还是不合理。

观测了一下,顶格长包确实不少见,比如图片较多的网站,实际数据长度一般常见上限是16408.(没+5) 服务器的配置可以影响这个包长度上限,比如nginx的ssl_buffer_size(nginx默认是16K,与maximum TLS record size一样。) 查看了一些资料,很多CDN还支持动态优化这个值,可以配置TLS record size的上下限(非用户自行配置)

是否考虑v2ray服务端主动探测回落服务器,根据回落服务器的包长规律来确定包长规律

通过配置得到的是包长度的上限值,(比如把nginx设置成2k的ssl buffer,最大长度也是2070。) 实际不可能存在规律,因为和实际内容有关。 默认大多是TLS record size 最大值一致,用16K就是通常大多数的默认配置没有什么特征了。

badO1a5A90 commented 4 years ago

是否考虑v2ray服务端主动探测回落服务器,根据回落服务器的包长规律来确定包长规律

这个。。。真的没有“规律”,收回多少发多少,或者就是有缓存,或达到了最大值。 大多数 Web 服务器应该默认是 16384(且带缓存?),XTLS 也进行这样的处理就解决这个问题了。

(之前我认为顶格长包和 v2ray 的 2070 都是不合理的,但现在发现前者很常见,而后者的确还是不合理。

观测了一下,顶格长包确实不少见,比如图片较多的网站,实际数据长度一般常见上限是16408.(没+5) 服务器的配置可以影响这个包长度上限,比如nginx的ssl_buffer_size(nginx默认是16K,与maximum TLS record size一样。) 查看了一些资料,很多CDN还支持动态优化这个值,可以配置TLS record size的上下限(非用户自行配置)

是否考虑v2ray服务端主动探测回落服务器,根据回落服务器的包长规律来确定包长规律

通过配置得到的是包长度的上限值,(比如把nginx设置成2k的ssl buffer,最大长度也是2070。) 实际不可能存在规律,因为和实际内容有关。 默认大多是TLS record size 最大值一致,用16K就是通常大多数的默认配置没有什么特征了。

这样一想,2070也可以是设置成2Kbuff的Nginx,也不属于v2特征。(只是不知道这样设的有多少

badO1a5A90 commented 4 years ago

是否考虑v2ray服务端主动探测回落服务器,根据回落服务器的包长规律来确定包长规律

这个。。。真的没有“规律”,收回多少发多少,或者就是有缓存,或达到了最大值。 大多数 Web 服务器应该默认是 16384(且带缓存?),XTLS 也进行这样的处理就解决这个问题了。

(之前我认为顶格长包和 v2ray 的 2070 都是不合理的,但现在发现前者很常见,而后者的确还是不合理。

观测了一下,顶格长包确实不少见,比如图片较多的网站,实际数据长度一般常见上限是16408.(没+5) 服务器的配置可以影响这个包长度上限,比如nginx的ssl_buffer_size(nginx默认是16K,与maximum TLS record size一样。) 查看了一些资料,很多CDN还支持动态优化这个值,可以配置TLS record size的上下限(非用户自行配置)

是否考虑v2ray服务端主动探测回落服务器,根据回落服务器的包长规律来确定包长规律

通过配置得到的是包长度的上限值,(比如把nginx设置成2k的ssl buffer,最大长度也是2070。) 实际不可能存在规律,因为和实际内容有关。 默认大多是TLS record size 最大值一致,用16K就是通常大多数的默认配置没有什么特征了。

这样一想,2070也可以是设置成2K buff的Nginx,也不属于v2特征。(只是不知道这样设的有多少

klzgrad commented 4 years ago

xTLS是怎么定义的?

RPRX commented 4 years ago

xTLS是怎么定义的?

想了很多种策略,也写了很多种算法,目前最终确定的是:第二个 TLS data record 开始的数据不二次加密而直接转发(发送方)

很多地方都有逻辑闭环,比如发送方(算法接管后)遇到非预期结构则发 alert 且 close,遇到 alert 则转发后 close

XTLS 最终的算法有点复杂,不过这两天就会开源,同时放出 VLESS XTLS,或 VLESS PREVIEW 2.0