Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New Protocol] VLESS ALPHA #2583

Closed
RPRX opened this issue Jun 19, 2020 · 29 comments
Closed

[New Protocol] VLESS ALPHA #2583

RPRX opened this issue Jun 19, 2020 · 29 comments
Labels

Comments

@RPRX
Copy link
Contributor

RPRX commented Jun 19, 2020

2020-07-17 更新:

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

2020-07-05 更新:

本 issue 是对初版 VLess 的描述,而 VLess 已大改且迭代了多个版本,Changes 详见 v2ray-vless/releases


What‘s VLess? #2526 #2547

本来指望着有开发组的大佬来实现 VLess,但前段时间 VMessAEAD 公测后好像并没有这个迹象,所以我就抽空熟悉了一下 V2Ray 的代码,并且把新协议 VLess 写了出来。

毕竟 VMessAEAD 似乎比原来的 VMess 更重,所以当基于 TLS 或内网等可信通路时,一个功能同样强大但超轻的协议会是更优的选择(保留实用功能、去掉多余计算)。

测试阶段,你可以通过 rprx/v2ray-vless 获取新协议 VLess 的所有代码,releases 有已编译好的 Windows & Linux x64 版本,需要其它系统、架构的请参考 #2573 自行编译,注意别下载错代码了。

目前这个仓库是 v2fly/v2ray-core 的超集,不同的是 go.mod 中的所有依赖都升至最新版本了。虽然是 Alpha,但 VLess 完全可以日常使用了,且由于是超集,不会影响你使用其它协议,欢迎体验。

VLESS 是一个无状态的、认证方式为 UUID 的简单代理协议

不混淆时,请求和响应的结构分别如下:

16 字节 1 字节 1 字节 2 字节 1 字节 N 字节 1 字节 X 字节
等价 UUID 响应认证,伪随机数 指令 端口 地址类型 地址 混淆方式名称长度,0 实际数据,不分割为若干小块
1 字节 1 字节 Y 字节
响应认证,与请求中的值相同 混淆方式名称长度,0 实际数据,不分割为若干小块

相对于两次握手的 Socks5, VLess 每次请求只多 0.03 KB 左右,基本可以忽略,同样也没有复杂计算。

以混淆方式 shake 为例,此时请求和响应的“混淆方式名称长度”扩展为:

1 字节 5 字节 1 字节 16 字节
混淆方式名称长度,5 名称,shake 种子长度,16 种子,随机值,请求和响应的不同

实际数据都会被分割为 标准格式 的若干小块并应用混淆算法,接收方需要进行小块校验并且解除混淆。

配置文件从 VMess 切换到 VLess 非常简单:

  1. 客户端、服务端的 protocol 都改成 “vless”
  2. 客户端删掉 alterId、security,服务端删掉 alterId、default、detour、disableInsecureEncryption
  3. 客户端与 id 同级的新属性 mess 填 “shake” 是原混淆方式,不填、填其它的均为不混淆

其它一切都不用改,包括 UUID、level、邮箱、统计等。V2Ray 的其它组件均可继续使用,比如底层传输方式、路由、DNS、Mux、反代、日志等(API 动态添加、删除用户也应该是可用的,有对应的代码,但还未测试过这个功能)。服务端可以继续由 Nginx/Caddy 处理 TLS 并路径分流,如果你信任 CDN 则可以套 CDN。请记住,VLess 就只是一个新协议而已,和其它协议是同一级别的,并没有什么特殊地位。

对了,VLess 没有客户端、服务端的时间差限制了,至于更多的区别,请继续往下看。


新协议是对 VMess 的精简,那么它主要精简了哪里?(含 VMess 部分原理解析)

说明:这里的 VMess 指的不是 VMessAEAD

常见误区:VMess 加密选 none 就没有多余计算了吗?并不是这样。只是数据不加密了而已,头部仍然有 Hash、有 aes-128-cfb 加解密等,来回数据会被分割成小块并应用混淆算法,VMess 无法关闭混淆。

设计理念的不同请看 #2526,协议结构的不同请看 #2547,这里我写的是代码层面的主要不同。

  1. 去掉了客户端、服务端中头部&数据加解密及相关的取随机、Hash、校验等代码(即结构、函数、逻辑、运算等),这些都是高度耦合的,不详述。而现在的 VMessAEAD 还要更复杂一些。

  2. 去掉了 alterId、时间差限制、相关 Hash 等代码,其实这些也是高度耦合的。
    alterId 的原理是用预设的算法根据一个 ID 衍生出多个 ID,客户端每次随机选一个并结合时间因素多次 Hash 后加入请求头。众所周知 Hash 不是加密,所以服务端要提前准备好用同样方式计算出的所有 ID 的所有可能的 Hash 值,以便与客户端提供的值进行对比(这也是客户端的 alterId 可以少于服务端的原因)。由于有时间因素,服务端准备的 Hash 值每 10 秒就要更新一次,即计算出新的所有可能的值,并删掉几分钟前的值。很显然 VLess 并不需要这种机制,所以我重新给服务端写了一个简洁的 validator(含 API 动态添加、删除用户功能),没有衍生 ID,也无需定期更新 Hash。

  3. 前面提到过,VMess 是无法关闭混淆的,对性能也会有些影响。对于是否混淆、混淆方式等,原本基于 Option 的结构扩展性很差且不专一、相关逻辑散落四处。于是你可以看到我设计了全新的可无限扩展的结构及相关逻辑把它们替换掉了,并且允许关闭混淆,此时实际数据不会被分割成小块。

  4. 服务端原本有一个 sessionHistory 机制,记录并对比请求中的一些数据用于抵抗重放攻击(同样也要定期删掉过期数据)。它记录的数据和加密部分有关,不过也可以使之无关,但由于 VLess 是用于可信通路的协议,所以这个机制被去掉了。

  5. VLess 没有“动态端口指令”,因为本来就没多少人用,可信通路上更不需要它,所以它也被去掉了。虽然这个功能没多少人用,但服务端、客户端用于实现它的代码却更多、更杂,各种结构、函数、逻辑等散落更广,幸好我最终还是把它们全部剥离掉了。如果你需要动态端口,别忘了还有 VMess。梳理代码逻辑时发现,default 并不是 detour 专用的,API 也会用到,官方文档描述有误。 2020-06-25 更新:进一步整理代码时发现,default 还真的只有 detour 用到了。。。

其它小的改变不详细描述,而且我是几天前写的代码,现在也难以列全。

总而言之,相较于 VMess,基于 TLS 或内网等可信通路时用 VLess 性能更好,更省双边的内存和 CPU、耗电更少。 游戏等对性能要求高的场景需要它,手机等移动设备、配置低的服务器也需要它,路由器、树莓派等透明代理更是需要它(竟然开始推销了。。。)

不混淆时,性能理论上和 Socks5 差不多,甚至由于无需两次握手,初次访问还会快一些。
加上 TLS,不混淆时性能可能和 Trojan 差不多(非 WSS),至于和它的区别,请看 #2547 正文末。


关于混淆

说明:这里的混淆指的是改变流量时序特征,不是伪装

可以看到,VLess 协议中混淆的架构设计很强大,不仅可以无限扩展、附加自定义数据(甚至多级结构),其实请求和响应还可以采用不同的混淆方式(响应的混淆方式默认和请求的相同)。

不过目前配置中的新属性 mess 只存在于客户端,并且还没有采用 #2547 中说的随机选择(auto)、每次请求随机选择(rand)等逻辑,一是因为现在只有从 VMess 拿来的 shake 混淆方式,二是因为我想到了更强大的描述方法。在用户配置中,mess 实际上是对 alterId 的原位替换,并将类型改成了 string,所以以后它可以这样描述:auto/rand/must:all/shake|etc。看不懂没关系,因为具体的描述方法还有待敲定。

至于 TLS 上是否需要不止一种混淆方式,我认为是有必要的,至少要留这个口子而不能硬编码,毕竟这是少有的有意义的变量了。对于墙来说,TLS 上不同混淆方式所带来的不同流量时序特征就是一种不同的协议,VLess 甚至可以混淆得像友军的协议。即使哪天墙能根据流量时序特征识别出现有协议,友军的协议都歇菜,VLess 只需加几个新混淆方式即可。遇到 VLess 这种随心混淆的,想必墙也会觉得很烦吧。某种程度上来说,VLess 这种模式是 TLS 翻墙的终极解决方案(当然还要解决指纹等问题)。

下一个测试版本可能会将混淆相关结构提前,让头部也参与混淆。

关于加密

如果你看了代码,会发现我并没有删掉客户端配置中的加密属性(只是现在不管填不填、填什么都不会实际生效)。我的考虑是,未来或许可以通过客户端与服务端提前约定的方式在外面套一层弱特征加密,那样 VLess 就真正实现了“核心协议-混淆方式-加密方式”可随意解耦的层层嵌套。有了加密,最终效果只是配置中 mess 属性原位替换 alterId 而已。根据 VLess 的风格,加密方式当然也不会只有一种选择。

“提前约定”并不会影响到承载物(内层协议)的结构,所以无需现在就实现,目前也没有任何实现该想法的时间计划。如果你开发图形客户端,建议留着这个属性并且只能选 none,以提醒用户现在没有加密。

其它

rprx/v2ray-vless 这个项目并不打算成为长期并行项目,只想几轮测试、优化之后正式提交 pr,同时会写相关文档。当然,如果到时不被 merge,可以作为超集长期并行发布。

下一个版本是 Beta,将会确定是否将混淆相关结构提前、确定 mess 的描述方式、加入 _test.go 等代码、进一步提升代码质量等,也会带来一点点性能提升。

若客户端、脚本开发者对 VLess 感兴趣,可以提前适配,等 VLess 正式版推出后再发布出去会比较好。

性能测试建议控制这几个变量:Mux、mess、WS(Base64 编码会使数据量膨胀)、TLS,可以和 Socks5、VMess、SS、Trojan 等进行对比。如果你的网速比较慢,换用 VLess 的速度提升可能并不明显,但还是可以帮你省些内存和 CPU 的,同时省电。

关于 VLess 的问题或想法请直接在本 issue 下讨论。

@RPRX
Copy link
Contributor Author

RPRX commented Jun 21, 2020

VLESS ALPHA 2 协议结构即将大改:

1 字节 16 字节 1 字节 M 字节 1 字节 2 字节 1 字节 S 字节 X 字节
协议版本 等价 UUID 附加信息长度 M 附加信息 ProtoBuf 指令 端口 地址类型 地址 请求数据,混淆时分割为若干小块
1 字节 1 字节 N 字节 Y 字节
协议版本,同上 附加信息长度 N 附加信息 ProtoBuf 响应数据,混淆时分割为若干小块

晚些时候补充详细信息。

@zxlhhyccc
Copy link

zxlhhyccc commented Jun 21, 2020

VLESS ALPHA 2 协议结构即将大改:

1 字节 16 字节 1 字节 M 字节 1 字节 2 字节 1 字节 S 字节 X 字节
协议版本 等价 UUID 附加信息长度 M 附加信息 ProtoBuf 指令 端口 地址类型 地址 请求数据,混淆时分割为若干小块
1 字节 1 字节 N 字节 Y 字节
协议版本,同上 附加信息长度 N 附加信息 ProtoBuf 响应数据,混淆时分割为若干小块
晚些时候补充详细信息。

目前路由器使用ssrplus+、openclash等插件好像还没实现Vless功能。。。。,因此,路由上目前的插件使用Vless时候无法实现混淆。。。。

@RPRX
Copy link
Contributor Author

RPRX commented Jun 22, 2020

@zxlhhyccc

VLess 的混淆指的是“改变流量时序特征”,不是 SSR 那种伪装成别的流量的混淆(其实应该叫“伪装”)

防止误解,我有点想把“混淆方式”的表述改成“流量时序特征”了

虽然 VLess 是无状态协议(即前后两次请求没有必然关联),但以后出的混淆方式可以做到从宏观层面控制多次请求的大流量总特征,这样想象空间就很大了。我记得看到过 https 和 wss 都是可以被区分的

刚刚搜到了一个有趣的 issue,大致看了看:v2ray/discussion#513
相对于 Socks5,VLess 是 0-RTT 的,而且不开 Mux 也可以 UDP over TCP(以及熟悉的 UUID、API 等)

又看到了一个有趣的东西:https://guide.v2fly.org/advanced/tcp_tls_shunt_proxy.html
不过我一直觉得 v2ray 中 Domain Socket 的定位很迷,为什么不把它放在出入站那里?

@kslr
Copy link
Contributor

kslr commented Jun 23, 2020

正好我也在读这份资料
parrot.pdf

@RPRX
Copy link
Contributor Author

RPRX commented Jun 24, 2020

正好我也在读这份资料
parrot.pdf

这篇论文对现今的意义是 TLS 指纹与 TLS 之上的混淆(但由于它不是深度学习的论文,所以意义也比较有限)

之前在 #2526 @tomac4t 就发过这篇论文,在这里我正好写一下我对这篇论文的看法。

这篇论文的标题是”鹦鹉已死“,”鹦鹉“即”模仿“,论文内容也主要是谈在 TCP 层面模仿其它协议。
其实 TCP 层面的伪装是比较愚蠢的做法 —— 还不如直接用被伪装的协议,就像论文结尾写的那样。
比如把流量伪装成 HTTP,不如直接把流量嵌入 HTTP;把流量伪装成 RDP,不如直接用 RDP 上谷歌。

那么,伪装是那个年代的主流做法:这篇论文的时代局限性是,没有预见到 TLS 的全面普及、性能提升。
TLS 不等于 HTTPS,也不等于 WSS。它是传输层安全性协议,它被发明出来就只是为了这件事。
任何流量都可以用这个协议,也不存在”将低延迟网络服务(例如Tor)嵌入另一个协议是一项艰巨的任务“。

所以,#2526 中有些人没有分清的一点是,我们是在使用 TLS,而不是模仿 TLS。这是有本质区别的、很重要。
回到开头,解决方案已经很明确了:Chromium 代码(或 v2ray/discussion#754 )+ VLESS 可无限扩展混淆方式。

@lxhao61
Copy link

lxhao61 commented Jun 26, 2020

测试了:VLess很不错,速度提升明显(增加15%-30%),且稳定。希望尽快合并到现在中,从而促进图形界面及路由器插件开发。
测试了websocket+vless+caddy(tls)与H2+vless+Caddy,websocket+vless+caddy(tls)效果明显。
最后感谢rprx大神!

@changyp6
Copy link

刚测试了。速度很快。

@RPRX
Copy link
Contributor Author

RPRX commented Jun 27, 2020

@lxhao61 @changyp6

感谢测试!VLess 的确是可以日常使用的,核心代码简洁高效,其实正式版前的外围事务占比更多。

但我认为现在并没有达到 VLess 的速度极限,仍有一些上升空间,以后会继续优化代码。

目前看来,不混淆时 VLess + WSS 的速度和 Trojan 是同级的,如果直接用 TLS 还会更快一些。

其它指标也很重要,比如延迟、内存 CPU 占用率、耗电速度,有兴趣进行这部分测试吗?

@wenjinlibug
Copy link

樓主神人啊,一開始我就覺得現在的發展方向很奇怪,最好的僞裝是“真實”,往VMSS上套一層又一層還不如直接依賴tls加密用最接近真實https的方式來代理,服務器上開個真的網頁除非一個個主動探測否則根本無法區分。

@changyp6
Copy link

changyp6 commented Jun 29, 2020 via email

@wd
Copy link

wd commented Jul 2, 2020

比如把流量伪装成 HTTP,不如直接把流量嵌入 HTTP;把流量伪装成 RDP,不如直接用 RDP 上谷歌。

比较赞同这个,我一直用 tls + ws + vmess。前段时间突然想起来,既然都 tls 了,为啥不直接用一个 https 代理呢,还搞 vmess 干啥。。然后发现 v2ray 也是支持 https 代理的,然而经过测试后发现,支持也是有限制的,还好有人提交了 PR v2fly/v2ray-core#18 了,已经合并等着发布了。

v2ray 部分功能实在是太优秀了,比如有了 sniffing,完全不用关心 dns 污染了,还有功能强大的 routing 等。

当然,对于普通的 https 代理是可能被嗅探的,这是另外一个话题了。我琢磨应该也可以简单的通过支持发送自定义 header 来让服务器端区分是不是被嗅探了。

@kakaruoterl
Copy link

简单做了下vless+ws+tls和vmess+ws+tls速度对比
vless表现确实比vmess优秀

@LsnmxNB
Copy link

LsnmxNB commented Jul 13, 2020

还是等等各大佬出大招解决指纹问题再上tls,上前裸vmess速度超级牛逼哈哈,个人不太喜欢ws+tls戴套,因个人服务器有点多,如果每台都ws+tls哪搞域名都搞死人了~~~~~~~~~

@RPRX
Copy link
Contributor Author

RPRX commented Jul 13, 2020

@LsnmxNB
Copy link

LsnmxNB commented Jul 13, 2020

@LsnmxNB

v2ray/discussion#754 (comment)

谢谢大佬,一直在关注VLess最新动向,不过建议能有个方案能免域名上TLS的,域名实在太麻烦

@RPRX
Copy link
Contributor Author

RPRX commented Jul 13, 2020

@LsnmxNB

感觉那样的 TLS 用的人多了可能会是强特征。。。

多个服务器可以直接用同一个域名的,连接时指定 IP 就行

@LsnmxNB
Copy link

LsnmxNB commented Jul 13, 2020

@LsnmxNB

感觉那样的 TLS 用的人多了可能会是强特征。。。

多个服务器可以直接用同一个域名的,连接时指定 IP 就行

好吧看来只能绑一个域名,客户端连接用 IP 了,不过我感觉大部分人还是自己上WS的,我个人而言服务器多,实在麻烦了点,继续裸VLess ,VMess反而更快

@RPRX
Copy link
Contributor Author

RPRX commented Jul 13, 2020

@LsnmxNB

TLS 有握手等额外步骤,的确会比直接用无状态的协议慢一些

(不过现在千万别直接用不加密的裸 VLess,出了套加密后可以尝试)

@LsnmxNB
Copy link

LsnmxNB commented Jul 13, 2020

@LsnmxNB

TLS 有握手等额外步骤,的确会比直接用无状态的协议慢一些

(不过现在千万别直接用不加密的裸 VLess,出了套加密后可以尝试)

加密VLess,不用WS+TLS而已,加了这两个速度跟反应真有所降低

@lxhao61
Copy link

lxhao61 commented Jul 13, 2020

vless+quic+tls,tls是否不能由v2ray自己套上,必须外部服务套上(如caddy,但caddy好像无法进行HTTP/3转发)?
测试发现:vless+quic使用无问题。vless+quic+tls(服务端v2ray自己套上),客户端(启用了tls选项)无法连接。

@RPRX
Copy link
Contributor Author

RPRX commented Jul 13, 2020

@lxhao61

vless+quic+tls,tls是否不能由v2ray自己套上,必须外部服务套上(如caddy,但caddy好像无法进行HTTP/3转发)?

v2ray 中底层传输方式与承载物是解耦的,所以 QUIC 的 TLS 由谁套上,这个不属于 VLess 或 VMess 能管到的范围

测试发现:vless+quic使用无问题。vless+quic+tls(服务端v2ray自己套上),客户端(启用了tls选项)无法连接。

如果这样配置 VLess 后不行,你可以试一下用同样的方法使用 VMess,应该也是不行的

@UJX6N
Copy link

UJX6N commented Jul 13, 2020

vless+quic+tls,tls是否不能由v2ray自己套上,必须外部服务套上(如caddy,但caddy好像无法进行HTTP/3转发)?
测试发现:vless+quic使用无问题。vless+quic+tls(服务端v2ray自己套上),客户端(启用了tls选项)无法连接。

caddy支持quic要加參數吧,
https://ma.ttias.be/how-run-http-3-with-caddy-2/

里面提到在配置文件需要加
{
experimental_http3
}

另外,如果後端是qiuc的話,proxy後端可能要以
quic://
開頭,類似
proxy /ray quic://localhost:10000

我沒試過,我胡亂查的

@aptx17
Copy link

aptx17 commented Jul 14, 2020

持续关注!哥,能另出个你fork的readme.md的less详细说明么?issues的链接跳转看得累慌。。囧。
现在还是直接vmessAEAD tcp 速度爽死,还在考虑要不要上tls,速度会有点影响吗?

@RPRX
Copy link
Contributor Author

RPRX commented Jul 14, 2020

@aptx17

鸽了一周,BETA 版说明即将发布,没有那么多跳转了

TLS 一般都不是 0-RTT,而且还有额外步骤,会稍微影响延迟和速度

@lxhao61
Copy link

lxhao61 commented Jul 18, 2020

vless+quic+tls,tls是否不能由v2ray自己套上,必须外部服务套上(如caddy,但caddy好像无法进行HTTP/3转发)?
测试发现:vless+quic使用无问题。vless+quic+tls(服务端v2ray自己套上),客户端(启用了tls选项)无法连接。

caddy支持quic要加參數吧,
https://ma.ttias.be/how-run-http-3-with-caddy-2/

里面提到在配置文件需要加
{
experimental_htt

vless+quic+tls,tls是否不能由v2ray自己套上,必须外部服务套上(如caddy,但caddy好像无法进行HTTP/3转发)?
测试发现:vless+quic使用无问题。vless+quic+tls(服务端v2ray自己套上),客户端(启用了tls选项)无法连接。

caddy支持quic要加參數吧,
https://ma.ttias.be/how-run-http-3-with-caddy-2/

里面提到在配置文件需要加
{
experimental_http3
}

另外,如果後端是qiuc的話,proxy後端可能要以
quic://
開頭,類似
proxy /ray quic://localhost:10000

我沒試過,我胡亂查的

@UJX6N
caddy目前是支持HTTP/3,即标准quic传输协议。但好像无法支持HTPP/3反代或转发,即不支持基于path的反代及转发。
另外v2ray支持的quic好像不与现标准quic兼容,也不支持基于path,目前是支持基于header的。
故你目前想让caddy实现HTTP/3基于path的反代及转发是无法的。

@lxhao61
Copy link

lxhao61 commented Jul 18, 2020

@lxhao61

vless+quic+tls,tls是否不能由v2ray自己套上,必须外部服务套上(如caddy,但caddy好像无法进行HTTP/3转发)?

v2ray 中底层传输方式与承载物是解耦的,所以 QUIC 的 TLS 由谁套上,这个不属于 VLess 或 VMess 能管到的范围

测试发现:vless+quic使用无问题。vless+quic+tls(服务端v2ray自己套上),客户端(启用了tls选项)无法连接。

如果这样配置 VLess 后不行,你可以试一下用同样的方法使用 VMess,应该也是不行的

@RPRX
不好意思,找到原因了,是我客户端配置问题。vless+quic+tls,v2ray自己套上tls无问题。习惯"tlsSettings"为空,但vless+quic+tls模式,客户端必须加上域名。

@zhyonc
Copy link

zhyonc commented Jul 20, 2020

Mark

@github-actions
Copy link

This issue is stale because it has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days

@GenshinMinecraft
Copy link

VLESS ALPHA 2 协议结构即将大改:
1 字节 16 字节 1 字节 M 字节 1 字节 2 字节 1 字节 S 字节 X 字节
协议版本 等价 UUID 附加信息长度 M 附加信息 ProtoBuf 指令 端口 地址类型 地址 请求数据,混淆时分割为若干小块
1 字节 1 字节 N 字节 Y 字节
协议版本,同上 附加信息长度 N 附加信息 ProtoBuf 响应数据,混淆时分割为若干小块
晚些时候补充详细信息。

目前路由器使用ssrplus+、openclash等插件好像还没实现Vless功能。。。。,因此,路由上目前的插件使用Vless时候无法实现混淆。。。。

这些插件是调用其他内核的,比如openclash是使用clash内核,与插件无关

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests