Skip to content

Comments

TLS config: Add pinnedPeerCertSha256; Remove pinnedPeerCertificateChainSha256 and pinnedPeerCertificatePublicKeySha256#5154

Merged
RPRX merged 6 commits intomainfrom
cert-pin
Jan 9, 2026
Merged

TLS config: Add pinnedPeerCertSha256; Remove pinnedPeerCertificateChainSha256 and pinnedPeerCertificatePublicKeySha256#5154
RPRX merged 6 commits intomainfrom
cert-pin

Conversation

@Fangliding
Copy link
Member

@Fangliding Fangliding commented Sep 16, 2025

新字段 PinnedPeerCertificateSha256 其为证书的sha256 为一个通用的证书指纹 chrome的证书查看器和crt.sh都以此作为证书的唯一标识符 类似这样 AE243D668EC9C7F74A0DCD1AD21C6676B4EFE30C39728934B362093AF886BF77 还有一种标识符是sha-1 Windows内置证书查看器是使用这个 crt.sh也有 但是觉得太旧而且混一起不方便就没用

PinnedPeerCertificateSha256 这个字段具有两个行为

指定的是叶子证书 → 同证书链hash会直接通过验证
指定的是CA证书 → 暂时通过 将当前被验证身份的CA添加到证书池中
全都没有就是失败(废话)

执行 VerifyPeerCertInNames 它会根据里面指定的name重新验证证书 但是如果 PinnedPeerCertificateSha256 指定了一个CA 那么它将把验证成功添加到CA池进行验证(用于自签名CA 比如自己签发一个CA 在 PinnedPeerCertificateSha256 指定自定义CA的指纹 然后在这里指定SNI)

@Fangliding Fangliding marked this pull request as draft September 16, 2025 08:35
@KobeArthurScofield
Copy link
Contributor

虽然老 break proto 不是很好 不过这个应该可以替换掉原来的选项 一是用 pb 的发现 hash 对不上可以有机会重新配置 二是不用日后清理 而且这个功能只在 release note 出现过

@RPRX
Copy link
Member

RPRX commented Sep 16, 2025

顺便改成 Xray-core 内置 root 证书 net4people/bbs#526 (comment)

以及删掉 allowInsecure、用 PinnedPeerCertificateSha256 代替吧

@RPRX
Copy link
Member

RPRX commented Sep 16, 2025

PinnedPeerCertificateSha256 这个可以加进分享链接里

@Fangliding
Copy link
Member Author

删了allowInsecure不太好吧 我有的时候本地测试都得开(

@MoRanYue
Copy link

((这里认为,将allowInsecure改为环境变量或命令行参数,或许更好呀))

@RPRX
Copy link
Member

RPRX commented Sep 16, 2025

删了allowInsecure不太好吧 我有的时候本地测试都得开(

本地测试也可以 PinnedPeerCertificateSha256

以前好像提过删掉 allowInsecure 这个选项,有人说有时候证书过期了,不开会失联,但现在都是 REALITY 了

@Fangliding
Copy link
Member Author

Fangliding commented Sep 16, 2025

这个东西到底不好提取 要不加个环境变量 XRAY_DEBUG 什么的然后从infra里检测没有这个flag就禁掉这个功能 也不用删代码 以后有其他可能危险的功能也可以加到底下

@RPRX
Copy link
Member

RPRX commented Sep 16, 2025

这个东西到底不好提取

./xray tls cert 顺带输出 sha256 不就行了,再扩展一下 ./xray tls ping 让它输出各级 sha256(或许 InsecureSkipVerify)

还有现在的两个 pin 选项都删了,统一改为 PinnedPeerCertSha256 就行了,留着重复功能的话代码逻辑上较复杂

@Fangliding
Copy link
Member Author

重构了大量有的没的把功能迁移走
自定义证书库参考我之前写的 https://github.com/XTLS/Xray-core/pull/3897/files 它们不太好管理 并且好像没有官方公开的这样的list可供拉取 火狐发布的是他们专有的格式 curl有一个他们自动转换的pem证书 但是是绑一起的只能一块加载
并且还有一个要不要把中国背景CA踹掉的问题 周围很多人喜欢这么干但是我个人还是倾向相信证书透明度监管而不是基于国家背景的简单判断 今天国安局明天CIA都得防着那大家不如别用CA都用预共享去算了

@yuhan6665
Copy link
Member

This is great work that should be continued. I can understand what RPRX would demand for delete "allowinsecure" option. But on the other hand I can also get 2dust's idea to put that in the sharing links (You never know what weird device end user gets and it does solve the problem for them)
To me, it is important to balance the security and 降低门槛. You'd have to admit that performing MITM is very expensive. And I believe 降低门槛 is one of the core values we should promote in Xray.

@RPRX
Copy link
Member

RPRX commented Jan 6, 2026

可以先不删 allowInsecure 但提示迁移

@RPRX
Copy link
Member

RPRX commented Jan 6, 2026

就从这个版本开始吧,弄个统一的 pin 并加到分享链接和 UI 中,给几个月的迁移时间,最后把 allowInsecure 删掉

公网未加密流量也是,会写个配置检测,提示迁移直至完全禁止,以及提示 SS/VMess 迁移至 VLESS Encryption

@Fangliding
Copy link
Member Author

不管allowInsecure和内置证书没关系的话这个可以直接用了
顺便这个pr移除了旧的pin参数 它们会无效

@RPRX
Copy link
Member

RPRX commented Jan 6, 2026

./xray tls cert 加了输出 sha256 吗

@RPRX
Copy link
Member

RPRX commented Jan 6, 2026

还有,证书应该不能同时是 leaf 和 CA 吧

@RPRX
Copy link
Member

RPRX commented Jan 6, 2026

改名 PinnedPeerCertSha256 吧,配置名短一些,分享链接应该是 pcs

@RPRX
Copy link
Member

RPRX commented Jan 6, 2026

还有,证书应该不能同时是 leaf 和 CA 吧

想了下,似乎即使是的话也没有什么攻击面,服务提供者没必要骗客户端是 leaf

@Snow-dash
Copy link

@RPRX 加个xray ping target as sni有没有必要

@Fangliding
Copy link
Member Author

Fangliding commented Jan 6, 2026

./xray tls cert 加了输出 sha256 吗

没有 因为它本来就没有 但是我写了一个新的命令来计算 chrome证书查看器和crt.sh也可以直接查看

还有,证书应该不能同时是 leaf 和 CA 吧

如果一张证书同时isca还包含san 它会被识别成ca 不过我猜这样一张混乱的证书没法通过后续的go verify流程 它的出现是个错误

@Fangliding
Copy link
Member Author

还有一个问题 这个改之前的字段是一个数组 验证逻辑是满足任何一个就行了 我不知道有没有必要改成单个的

@RPRX RPRX marked this pull request as ready for review January 9, 2026 00:06
@RPRX RPRX changed the title 重构部分证书pin逻辑 TLS config: Add pinnedPeerCertSha256; Remove pinnedPeerCertificateChainSha256 and pinnedPeerCertificatePublicKeySha256 Jan 9, 2026
@RPRX RPRX merged commit 0ca1345 into main Jan 9, 2026
77 of 78 checks passed
@RPRX
Copy link
Member

RPRX commented Jan 9, 2026

有点东西,好玩,我顺便删掉了那个 trailing space,看来 AI 还是可以用的,人工 review 一下代码就行,以后就靠这个来 vibe 了

@RPRX RPRX deleted the cert-pin branch January 9, 2026 00:17
@RPRX
Copy link
Member

RPRX commented Jan 9, 2026

理解能力也可以,我一开始打错了配置项名称它也能找到,并且一开始还保留了 * 和那个 trailing space,没有多管闲事挺好的

@RPRX
Copy link
Member

RPRX commented Jan 9, 2026

分隔符最终决定改成 ~,因为 | 会被 URL 转义,想过 _ 但我想让 ~ 成为通用的数组表示方式,后者出现的频率低到几乎没有

这就去 vibe 更多代码,先试试它能不能给 TUN 改出个 FullCone

@Fangliding
Copy link
Member Author

我的意思是url防止被转义可以拼一块 json本来就是数组的最好还是别强行加个连字符改成单选项

@RPRX
Copy link
Member

RPRX commented Jan 9, 2026

我也想过这样有点怪,不过 VLESS 分享链接除了 URL 转义外似乎还没有过需要 UI 额外处理配置项的先例

并且这名字长得就不像数组,99% 的用例也只会填一项,加个 ~ 语法糖只是为了兼容那 1%

@RPRX
Copy link
Member

RPRX commented Jan 9, 2026

哎不对,ALPN 算是孤例吧,不过它的典型用例就是数组,还有 verifyPeerCertInNames 也是数组,不过它没有分享链接和 UI 支持

不过 v2rayNG 还没有搞过数组配置,对于 ALPN 的处理是给出几个选项而不是数组配置

对于 pinnedPeerCertSha256 这种典型用例为单个的,UI 搞个数组就更没必要了,要不就先保持这样,开个单个但兼容数组的先例

@RPRX
Copy link
Member

RPRX commented Jan 10, 2026

@Fangliding 文档写错了,不是 - 而是 ~

@RPRX
Copy link
Member

RPRX commented Jan 10, 2026

@Fangliding 或许设置了 pinnedPeerCertSha256 的话自动开 allowInsecure?不过这少覆盖了一种情况

@Fangliding
Copy link
Member Author

自签证书毕竟是很少数 我觉得没啥必要

@RPRX
Copy link
Member

RPRX commented Jan 10, 2026

因为以后想把 allowInsecure 选项删掉用这个来代替,有点烧脑了。。。

@RPRX
Copy link
Member

RPRX commented Jan 10, 2026

或许两个都留但不允许单独开 allowInsecure 吧

@Fangliding
Copy link
Member Author

这个选项最大的作用可能就是 设置成类似 96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6 (ISRG ROOT X1) 之类的来防止设备本身证书不可信 别的动作我觉得不太有必要了

@RPRX
Copy link
Member

RPRX commented Jan 10, 2026

VerifyPeerCertInNames 设了的话倒是会自动 allowInsecure,不过它本质上还是会要求证书可信非自签,除非 pin 了自签 CA

@RPRX
Copy link
Member

RPRX commented Jan 10, 2026

pin leaf 和 pin CA 的区别是前者直接通过,后者仍会执行 name 和 time 验证对吧

@Fangliding
Copy link
Member Author

重新验证是 VerifyPeerCertInNames 块里完成 要是只allowinsecure+pin ca那就只会看ca 因为不知道用哪个域名去验证

@RPRX
Copy link
Member

RPRX commented Jan 10, 2026

域名不是 SNI 填了吗

@Fangliding
Copy link
Member Author

rand Carrier访问不到 而且没法处理IP证书

@Fangliding
Copy link
Member Author

不对 应该可以 如果有需要的话可以把servername传进去

@Fangliding
Copy link
Member Author

域名不是 SNI 填了吗

e86e0f9
我把它做成这样了 整个config传进去 自签CA就不用填那个VerifyPeerCertInNames了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants