VLESS protocol: Add lightweight, Post-Quantum ML-KEM-768-based PFS 1-RTT / anti-replay 0-RTT AEAD Encryption#5067
Conversation
…TT / anti-replay 0-RTT AEAD encryption #4952 (comment)
…for native appearance #4952 (comment)
…t like XHTTP (UDS or not) + TLS/REALITY #4952 (comment)
…hange config format #4952 (comment)
Announcement of NFTs by Project X: XTLS/Xray-core#3633 Project X NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/1 VLESS Post-Quantum Encryption: XTLS/Xray-core#5067 VLESS NFT: https://opensea.io/collection/vless XHTTP: Beyond REALITY: XTLS/Xray-core#4113 REALITY NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/2
Announcement of NFTs by Project X: XTLS#3633 Project X NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/1 VLESS Post-Quantum Encryption: XTLS#5067 VLESS NFT: https://opensea.io/collection/vless XHTTP: Beyond REALITY: XTLS#4113 REALITY NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/2
Announcement of NFTs by Project X: #3633 Project X NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/1 VLESS Post-Quantum Encryption: #5067 VLESS NFT: https://opensea.io/collection/vless XHTTP: Beyond REALITY: #4113 REALITY NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/2
Announcement of NFTs by Project X: #3633 Project X NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/1 VLESS Post-Quantum Encryption: #5067 VLESS NFT: https://opensea.io/collection/vless XHTTP: Beyond REALITY: #4113 REALITY NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/2
Announcement of NFTs by Project X: XTLS/Xray-core#3633 Project X NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/1 VLESS Post-Quantum Encryption: XTLS/Xray-core#5067 VLESS NFT: https://opensea.io/collection/vless XHTTP: Beyond REALITY: XTLS/Xray-core#4113 REALITY NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/2
Announcement of NFTs by Project X: #3633 Project X NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/1 VLESS Post-Quantum Encryption: #5067 VLESS NFT: https://opensea.io/collection/vless XHTTP: Beyond REALITY: #4113 REALITY NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/2
|
我想問一句,在不過牆的情況下直接vless+enc(ML-KEM-768)+tcp 是否可行的加密方式 |
|
Announcement of NFTs by Project X: #3633 Project X NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/1 VLESS Post-Quantum Encryption: #5067 VLESS NFT: https://opensea.io/collection/vless XHTTP: Beyond REALITY: #4113 REALITY NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/2
不封就行,打了删除线,是不是不行啊 |
| @@ -0,0 +1,202 @@ | |||
| package encryption | |||
@RPRX 如果周期清理时直接按照 last := i.Lasts[minute] 的位置截断 i.Tickets,可能出现误将未过期 Ticket 删除的情况, 因为 last 事实上是于 minute 分钟过期且创建时间最晚的 Ticket,i.Tickets 中 last 前面可能还存在尚未过期的 Ticket。(虽然每张 Ticket 是按创建时间顺序加入 i.Tickets 尾部的,但每张 Ticket 的过期秒数 seconds 都是在创建时在区间内随机赋值的,不一定满足先创建者先过期的约束,因而 i.Tickets 不一定满足按过期时间递增的约束。) |
|
其实有一种办法 用 time.AfrerFunc 按原样创建清理任务 timer只是一个堆对象不会占用大量goroutine |
|
@IconHHw 有人 review 协议是好事,不过有没有一种可能
|
经 @gfw-killer 一人 多次 血书,VLESS 自带加密它终于来了!我想把这个 spec 写得言简意赅,想要了解更多设计过程中的取舍,请参考 #4952 (comment) 开始的相关讨论,以及 https://t.me/projectXtls/1005 开始的 Q/A 碎片,非常感谢 @Fangliding @wwqgtxx @ForestL18 @xchacha20-poly1305 等人参与讨论、反馈
VLESS Encryption 设计理念与通信流程
就像一年前说过的那样,鉴于 GFW 已经将全随机数外观列入黑名单,VLESS 加密原生外观并非全随机数(头部有公钥特征,流量为 TLSv1.3 的
23 3 3 l>>8 lAEAD 头特征,但可选 XOR 以变成全随机数外观),重点是有 SS 2022/AEAD、VMess 等协议都没有的 更高的安全性(前向安全且抗量子),以及更好的性能(且建议开 XTLS 避免二次加解密),并且同样是 0-RTT,以确保它可以成为更好的替代品,适用于 CDN(避免暴露 UUID 及被代理的 SNI)、中转(禁 HTTP/TLS)、non-TLS(伊朗 HTTP)等场景特别注意这个加密不是让你直接过墙用的,类似的协议早已不适合直接过墙,直接过墙应使用 REALITY、XHTTP、Vision 等协议
REALITY 则不需要再加密 VLESS,但如果你用机场,你也可以把机场线路当中转,转到你的免费 VPS,从而绕过机场的审计就像五年前 VLESS BETA 里提到的加密设计理念与当时预留的配置结构一样,VLESS 加密的设计是在明文 VLESS 协议外加一层 conn,而不与内层 VLESS 协议耦合,易于实现、易于替换,并且最大字节限制为 8K/16K,避免了额外 copy,从而不损失性能
我写了两版加密,最终留下的是第二版,它非常简洁,实现细节请看代码,这里简单说一下通信流程:
若选择了 "xorpub",客户端会对 ivAndRelays 中的公钥进行 XOR 以消除 X25519 public key 和 ML-KEM-768 ciphertext 的特征
若选择了 "random",客户端、服务端还会对
23 3 3 l>>8 l进行 XOR 以实现全随机数外观,占整体流量的万分之六,成本极低关于“解密前的多次中转”,是因为我看 SS 系列很喜欢搞 relay 这种东西,
说实话我也不太清楚应用场景甚至还在频道调研了一下,最终还是给 VLESS Encryption 加上了,毕竟也就是加个 for 的事,不同的是每一级都基于公私钥机制,且有对下一级 relay 的关联机制以使其不可被替换,因为我比较喜欢开脑洞去想如何攻击代理协议,就像代码中有多处注释说明了关于避免“移花接木”等攻击的考虑,服务端那个 for 其实就一次,因为到服务端只剩最后一级了,所以接下来还会出一个 vless-relay/core 项目以方便滥用中转VLESS Encryption 对比 SS、VMess
客户端配置安全、前向安全、0-RTT
我最后悔的事情就是两年前没有放出 REALITY 的文章,使得 REALITY 加密/认证/伪装的设计取舍没有清晰地呈现出来,尤其是至今一众小白仍傻傻分不清不同协议的加密/认证安全等级,以为加了密就是一样的,这次正好把概念给大家讲清楚,不重蹈覆辙。客户端配置安全:若攻击者拿到了客户端配置,无法解密以前、以后的通信内容,无法对以后的通信进行 MITM(中间人攻击)。 这个安全概念没有前向安全那么常见,
不知道是不是代理领域独一份,但它非常重要,因为通过读取剪切板、输入法上传、通讯软件分享、国产反诈手机等方式想拿到你的客户端配置可以说是没有难度。前向安全:若攻击者拿到了长期密钥(一般指服务端的),无法解密以前的通信内容。一般来说对以后的通信内容也无法直接解密,而是只能 MITM。 实现前向安全一般基于 TLS/REALITY ECDHE 或抗量子的“双方临时密钥交换”,但是会增加 1-RTT。
比如 SS 2022/AEAD(以及基于它们的 ShadowTLS)、VMess 采用对称 PSK 的设计,并没有实现客户端配置安全、前向安全,都是看似加密但实际上没有任何保障,GFW 拿到了你手机上的配置后,甚至还能直接解密你电脑等其它设备的流量(
即使只是 SNI 也方便了监控)。 还有一些协议是拿到客户端配置即可 MITM,只能说是一言难尽。并且随着 X25519 受到未来量子计算机的威胁与日俱增,也不只是 SNI 了,人家确实可以现在记录、未来破解你 SS 中的一些 TLS。确实不止是 SNI 了,GFW 现在就可以对内层 TLS 进行 MITM 从而甚至解密被代理的 TLS,问题很大:net4people/bbs#526
VLESS Encryption 类似于 REALITY,每一级 relay 都通过预共享 ML-KEM-768/X25519 密钥对的方式实现了客户端配置安全,并且通过双方临时 MLKEM768X25519 密钥交换的方式实现了前向安全。 密钥交换过程也是加密的,其实比 REALITY/TLS 更安全,比如说后者可能会因为明文 X25519 被未来的量子计算机破解而被解密流量,但对于 VLESS Encryption 则必须先拿到服务端私钥。
然而“双方临时密钥交换”会增加 1-RTT,这是用户不愿意看到的,所以 VLESS Encryption 通过跨连接复用 pfsKey 的方式实现了首次密钥交换后的 0-RTT。可能有人会说你都跨连接复用 pfsKey 了还“前向安全”吗,1-RTT 加多路复用岂不是更符合定义?然而多路复用若 pfsKey+nfsKey 泄露了同样是能解密出所有被代理的连接,多路复用十分钟与跨连接复用 pfsKey 十分钟是等价的,甚至我每个 0-RTT 连接实际加密都是不同的 unitedKey,安全性更高。无论哪种方式,实践中十分钟复用级别的前向安全已经足够,如果你把书读死了非要把最小粒度定义为单个代理请求、每次都“双方临时密钥交换”,那有的请求就一点数据,连 H2 都是多路复用。
抗量子的密钥交换与身份认证
既然为了前向安全我们引入了“双方临时密钥交换”,由于 X25519 可以被未来的量子计算机破解,VLESS Encryption 选择了 TLS 的抗量子的 MLKEM768X25519,为了方便实现,身份认证也是基于 ML-KEM-768 或 X25519(客户端配置中那一串 base64)而非引入额外的 ML-DSA-65,所以 1-RTT 时会至少有 nfsKey、pfsKey 两个相互独立的密钥交换(就像 REALITY)。最初的设计是两个共享密钥的使用相互独立,前者仅被用于认证服务端的身份,后者作为 unitedKey,但出于避免被蛐蛐 CK 模型下的安全性的考虑,我把 unitedKey 改为了由两个共享密钥联合,也是想弄个与 REALITY 不同的东西出来,这下即使未来 ML-KEM-768 也不可靠了,仅靠“先记录、后解密”是无法破解流量的(况且第二版的前向安全密钥交换也被加密了,又叠了一层防御,想破解太难了)。
还可以把 1-RTT 密钥交换放到 REALITY 或 TLS CDN 里(伊朗限速 TLS 但够用),然后 0-RTT 走 non-TLS,可以实现分离。对于 relays 的最后一级身份认证,第一版仅允许 ML-KEM-768,第二版也允许 X25519,客户端配置以及请求头会短一千字节,在可以稳定破解 X25519 的量子计算机出现前你可以使用它,毕竟身份认证的有效期仅限当下,无法被未来的量子计算机逆转。
于是你也可以把 VLESS 加密用于加强不抗量子的连接,
比如如果你 REALITY 选的目标网站尚未支持 X25519MLKEM768。更优的性能:无需对时、完美的重放防护、无需多次尝试解密以确定用户、无需额外 AEAD length
连接头无需像 SS AEAD、VMess 一样多次尝试解密以确定是哪个用户,0-RTT 时 O(1) 直接按 ticket 查 map,然后 O(1) 直接按 UUID 查 map(1-RTT 时也没有多次尝试解密),无论何种 XOR 模式,这对于有非常多用户的服务端可以显著减轻负担。
对于 0-RTT 时的重放防护,最流行的 SS AEAD 由于没有引入任何时间机制,所以它补上了一种很容易出错的防重放机制,时间越长出错概率越高所以需要清空,从而无法防御长期重放,且 SS AEAD 有可被“移花接木”的设计问题和安全漏洞。VMess 将时间戳融入加密,需要对时且又多了尝试解密。SS 2022 在内层明文发时间戳,若只允许一分钟则需要对时,若对时困难(伊朗)则需要服务端缓存更多数据。且这些协议的 salt map 都本应有持久化机制但各大实现基本没有,重启服务端即可被重放近期消息(最好静置几分钟再开放公网,或写代码来强制规避)。VLESS Encryption 的 0-RTT 重放防护是相对完美的,不需要对时、不需要尝试解密,O(1) 直接按 ticket 查 map,然后 O(1) 直接按 nfsKey 查 map,防御了短期重放,重启后或十分钟后 ticket 过期(在服务端设置时间,客户端自适应),天然防御了长期重放,且它所附带的 nfsKey map 也会被扔掉,不需要缓存太多数据,无论何种 XOR 模式。
当然 1-RTT 加多路复用天然不存在重放问题,也避免了我之前提的 EMP 攻击,但 GFW 已将全随机数拉黑,已经无意义了。其实对于任何代理协议来说,后续数据的加解密才是最关键的,比如同样选 AES-256-GCM / ChaCha20-Poly1305 时(VLESS Encryption 面向抗量子设计所以只有 256),VLESS Encryption 的 "native"、"xorpub" 不需要像 SS 2022/AEAD 一样对 length 部分调用一次 AEAD(虽然加密的数据很少但会有一次完整的 AEAD 调用开销,这是以前为了创造全随机数的外观以及防止 GFW 修改从而暴露特征,但还是出于众所周知的原因,已经没必要了),从而每次加解密都省了一次完整的 AEAD 调用开销
并省了 13 字节。VLESS Encryption 的 "random" 只会对 5-bytes header 进行 AES-256-CTR 的 XOR,每次都省了 MAC并且同样省了 13 字节。VLESS Encryption 虽然没有额外 AEAD length,但不对的话本来就会解密失败,且加解密时 header 是作为 AD 的,就像 TLSv1.3。
实测不额外 AEAD length 会快 10%,是否 XOR 区别不大,都是快 10%。而 AES-128-GCM 用于代理只比 256 快 3%,没有必要。
性能最大化:建议开 XTLS 避免二次加解密,可再叠上 XHTTP、WS 等传输层
其实上面对比性能也没什么意思,毕竟 VLESS Encryption 可以直接开 XTLS 外挂。话说 XTLS 都出来五年了,像 SS 一样无需域名却可以叠加 XTLS 的 REALITY 也出来三年了,但你若问小白什么协议性能最好,小白回答:SS。唉,顺便纠正一下刻板印象。
XTLS 是性能最好的协议,
不违反广告法,因为这就是 simple fact,毕竟它根本就不需要加解密:XTLS flow 把最关键的被代理的 TLSv1.3 Client Hello、Server Hello 以及前面的极少量数据 padding、并由外层的 TLS 或 REALITY 或 VLESS Encryption 加密后,后面所有的流量直接穿透到外层,没有加解密了,如果是 Linux 的服务端、路由器什么的,还会自动 Splice,让内核自己对拷。对于 "native"、"xorpub" 是完全穿透、会自动 ReadV/Splice,对于 "random" 是只 XOR 5-bytes header,只占流量万分之六。
并且 VLESS Encryption 的 XTLS 是支持 XHTTP、WS 等所有传输层的(Vision Seed PR 也即将合并,
耽搁了两年简直闹麻了)。所以 AES-128-GCM 更没必要了,有 XTLS 就够了。群里有人说打游戏,哎,拉满才快 3%,就那点可怜的 UDP 数据量,根本就没有任何压力,并不会让你减 3% 延迟。说到代理 UDP,VLESS Encryption 同样默认 XUDP、自动 UoT Migration(
也是没放出文章),并且早有计划在此基础上实现 PLUX 以让 UoT 也适合打游戏,预计不久后与 MUX 增强一起推出。将以上对比按顺序做成直观的表格
需要说明的是,无 XTLS 时理论性能 VLESS Encryption 与 REALITY/TLS 持平,都比额外 AEAD length 的 SS 2022/AEAD 快 10%,但这也与实现有关,比如 Xray-core 为绝大多数裸协议默认启用了 ReadV,但 Xray-core v25.9.5 还没有为 "ramdom" 或非 XTLS 的 VLESS Encryption/REALITY/TLS 实现 ReadV,所以本地回环测代理非 TLSv1.3 的吞吐量可能会低,
以后再实现 ReadV。Read() 时的拷贝次数也很重要,比如 REALITY/TLS 库目前的实现多了一次 copy,也是要改,或者如果 SS 2022/AEAD 对端发来的 AEAD 块较大但本地解密后是 Read(b) 也会导致多一次 copy(VLESS Encryption 标准限制了 8K 从而避免了这种情况,后续会放宽至 16K)。最佳性能是 native/xorpub + XTLS ReadV/Splice,
但如果你为了过 CDN 而加个 XHTTP 等传输层,所有协议都没有 ReadV/Splice。ReadV/Splice 只适用于 RAW 传输层,所以中转机场换 VLESS Encryption + XTLS 性能拉满,
服务端能 Splice 故能承载更多用户。0-RTT 过 CDN 应当用 VLESS Encryption + XTLS Vision + XHTTP XMUX,而不要用 WS + MUX,因为 MUX 不兼容 XTLS 裸奔。
VLESS Encryption 配置
服务端配置:(原生外观 / 只 XOR 公钥 / 全随机数。1-RTT 每次下发随机 300 到 600 秒的 ticket 以便 0-RTT 复用 / 只允许 1-RTT)
填写 "600s" 会每次随机取 50% 到 100%,即相当于填写 "300-600s",你还可以使用
./xray vlessenc生成直接可用的完整配置客户端配置:(若要用 XTLS,两端需配置 flow。 若收到的 ticket 中秒数不为零则 0-RTT 复用,连接时长不受限 / 只使用 1-RTT)
/是只能选一个,后面 base64 至少二选一,无限串联,使用./xray x25519和./xray mlkem768生成,替换值时需去掉括号Padding 是可选的参数,仅作用于 1-RTT 以消除握手的长度特征,双端默认值均为 "100-111-1111.75-0-111.50-0-3333":
服务端、客户端可以设置不同的 padding 参数,按 len、gap 的顺序无限串联,第一个 padding 需概率 100%、至少 35 字节
属于是狠狠吸取了两年前没及时写 REALITY Spider X 文档、没及时推出 Vision Seed 的血泪教训,好在 fragment 和 noises 是有的"mlkem768x25519plus" 代表未来可以无感并联其它密钥交换,若未来有更安全的密钥交换,升级双端即可,向后兼容
双端更新 Xray-core 并配置即可,分享链接无需更新,GUI 客户端不一定需要更新,因为早在五年前就预留了
encryption参数"fallbacks" 不可与 "decryption" 一起用,另外 VLESS 还更新了 vlessRoute,对于同一个落地机、多个不同地区出口而言非常方便
VLESS NFT
如此盛会怎能少了新的 NFT,所以 VLESS NFT 它虽迟但到原计划是 Project X NFT 发一百个,REALITY NFT 发一千个,VLESS NFT 发一万个,
但看到 REALITY NFT 那 0.01 ETH 的标价才换来多少 owners,哎我就不说了,以前有人说什么 NFT 便宜点赞助的人就很多都是骗人的,大多数人屯 VPS 吃灰也不会主动赞助所以计划变更:VLESS NFT 自成一个系列,每个图片都不同且只有一个,你可以选择自己喜欢的图片来收藏,先到先得
https://opensea.io/collection/vless 首发放出了二十个不同的 VLESS NFT 图片,由 @iambabyninja @kastov 参与设计
这次也放出了两个 Project X NFT,还有我刚发现 OpenSea 现在改图片很方便,以后大概是这样三足鼎立的格局:
Project X 的赞助采用 NFT 的形式是一个很好的创新,因为它可以为你的赞助留下永久的纪念,
若以后想卖出还可以赚点