-
Notifications
You must be signed in to change notification settings - Fork 4.5k
VLESS protocol: Add lightweight, Post-Quantum ML-KEM-768-based PFS 1-RTT / anti-replay 0-RTT AEAD Encryption #5067
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
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
fbb0ecf 没问题了,只测功能、不压测 GitHub 测试环境即可, |
|
… memory using Completes #5067 --------- Co-authored-by: wwqgtxx <wwqgtxx@gmail.com>
… memory using; Chores Completes #5067 --------- Co-authored-by: wwqgtxx <wwqgtxx@gmail.com>
e8b02cd 加了可选、可自定义的 1-RTT padding 参数(第一个连接一定是 1-RTT),正文“VLESS Encryption 配置”已更新详细说明 |
…able 1-RTT padding parameters See #5067 (comment) for details
…able 1-RTT padding parameters See #5067 (comment) for details
…able 1-RTT padding parameters See #5067 (comment) for details
6768a22 将 1-RTT padding 参数改为了 "probability-from-to" 格式,更多可能性、更易理解、“图灵完备”,PR 正文配置说明已更新 |
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
|
|
|
难道不是整个校验和来确保完整性吗 |
这是 X25519 公钥,中间人修改的话最终的 sharedKey 不匹配会 break connection,没必要整个验证 |
…t X25519 public key in relays #5067 (comment)
|
…t X25519 public key in relays #5067 (comment)
如果使用XHTTP套CDN,考虑到XHTTP已经自己有padding,内层VLESS的padding可以关了吗 |
不可以,作用不同,而且 VLESS Encryption 那个 padding 只是 1-RTT 握手期间的,几分钟才一次 |
更新了服务端配置填写 ticket 秒数的机制,允许填写范围如 "300-600s",不填写范围的话如 "600s" 每次随机取 50% 到 100% 服务端不再允许 "1rtt" 这样的写法,因为填写 "0s" 就是只允许 1-RTT,这也利于一眼与客户端配置("0rtt" 和 "1rtt")区分 还有如果更换了服务器,最佳实践是重新生成一对认证密钥,否则重放以前的消息到新的 IP 可以知道主人是同一个,我本来想像 REALITY 那样加个加密的时间戳,但这会 break 协议且没有彻底解决问题,应当服务端 nfsAEAD 解密失败也装一下,以后再说吧 TLS 这种非专业反审查协议没考虑这问题,SNI 是固定的,ECH 的 outer SNI 也是固定的,然后我想了下 SS / VMess,卧槽发现问题了,服务端重启的话在允许的时间范围内以前的消息可以被成功重放,除非持久化 salt map,我得更新下对比和表格了。。。 |
多说一下“加个加密的时间戳”的问题,如果采用这种方式的话,考虑到伊朗比如只允许一天内,那么这一天的时间还是能被利用“确定同一个主人的”,除非持久化 salt map 但这就复杂了,而且又不一定是“重放”,原始消息可能根本就没到达过服务端 上一次想加是想防止有人重放 1-RTT 握手来捣乱,但捣乱者可以不重放一天外、只重放一天内的,所以还是得另外配上一天的 salt map,那搞这么复杂还不如现在的直接 ticket map 只存十分钟,反正重放 1-RTT 的后果都只是会导致服务端 map 内加个值而已 所以 VLESS Encryption 现在不需要任何对时的设计挺好的,确保了易用性和通用性 |
经 @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 l
AEAD 头特征,但可选 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。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。更优的性能:无需对时、完美的重放防护、无需多次尝试解密以确定用户、无需加密 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" 是完全穿透、会自动 Linux 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%,但这也与实现有关,比如 *ray 由于用 pipe 传数据而非直接 callback,导致 ReadV 对性能的增幅会很明显,而目前我还没有给非 XTLS 的 VLESS Encryption/REALITY/TLS 实现 ReadV,所以拉非 TLS 会慢,这次先给客户端改了直接 callback,服务端还没改。Read() 时的拷贝次数也很重要,比如 REALITY/TLS 库目前的实现多了一次 copy,也是要改,或者如果 SS 2022/AEAD 对端发来的 AEAD 块较大但本地解密后是 Read(b) 也会导致多一次 copy(VLESS Encryption 标准限制了 8K 从而避免了这种情况,后续会放宽至 16K)。
只是不急,因为实践中大都是 XTLS 裸奔/ReadV/Splice,
或者如果你为了过 CDN 而加个 XHTTP 等传输层,谁也吃不到 ReadV。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 的形式是一个很好的创新,因为它可以为你的赞助留下永久的纪念,
若以后想卖出还可以赚点