TL;DR:VLESS Reality 握手失败,第一步先看时间。服务器、手机、电脑、虚拟机只要有明显时间漂移,就可能在握手早期失败。时间正常后,再核对 SNI、publicKey、shortId、uTLS fingerprint 和 flow。

Reality 的排障麻烦在于失败点很早。客户端有时只给一个 timeout 或 handshake failed,日志不一定告诉你是时间、密钥还是 SNI。不要凭感觉改字段。把客户端和服务端参数放到一张表里,一个个对。

先处理时间同步

先看两端当前时间。服务端常见问题是 VPS 没开 NTP、容器或虚拟机暂停后时间漂移;客户端常见问题是手机手动改时区,或者系统时间被旧快照带偏。

Linux 服务端可查:

timedatectl status

重点看:

  • System clock synchronized 是否为 yes。
  • NTP service 是否启用。
  • 时区是否符合你的管理习惯。时区不影响绝对时间,但会影响你读日志。

Windows 客户端看系统「日期和时间」里是否启用自动设置时间。macOS 看「日期与时间」是否自动同步。手机端也一样,先开自动时间。

Reality 字段对照表

项目服务端客户端常见错误
时间系统 NTP系统时间VPS 或手机时间漂移
SNIserverNamesserverName / sni客户端填了列表外的名称
publicKey由服务端 privateKey 生成publicKey / pbk复制漏字符或用错一组密钥
shortIdshortIdsshortId / sid长度不对、大小写混乱、被截断
fingerprint通常无服务端字段fingerprint / utls客户端不支持或随机值不一致
flowuser flow客户端 flow旧 core 不支持 Vision
destdest通常不填目标不可达或和 SNI 逻辑不一致

SNI 不要写成 URL。填 example.com,不要填 https://example.com/。这个错误很常见,而且日志不一定直说。

publicKey 和 shortId 不要靠肉眼扫一眼

Reality 的密钥字段对复制错误很敏感。二维码、聊天软件换行、订阅转换器截断,都可能让 publicKey 或 shortId 少一段。

排查时建议这样做:

  1. 从服务端重新导出 publicKey。
  2. 把客户端字段复制到纯文本编辑器。
  3. 对比长度和字符,不要只看开头结尾。
  4. shortId 对照服务端 shortIds 列表,必须命中其中一个。

如果服务端允许空 shortId,客户端也要按文档处理空值。不要自己补一个看起来顺眼的值。

uTLS fingerprint 排障时先固定

多客户端导入时,fingerprint 字段最容易被改名或丢失。v2rayN、NekoBox、sing-box、Clash Meta 的 UI 字段不同,但最终含义都是让客户端模拟某类 TLS ClientHello。

排障时先选明确支持的值,例如 chrome。不要一边查问题一边用 random。随机值让每次连接表现都可能不同,很难判断是哪一项改动生效。

如果配置来自配套订阅线路,仍建议保存一份原始 Reality 参数表。订阅导入失败时,直接拿表和客户端实际字段对照。

flow 和 core 版本也要看

xtls-rprx-vision 这类 flow 需要客户端 core 支持。旧版 Xray、旧版 Mihomo 或某些 GUI 打包的 core 版本偏旧时,可能不是 Reality 参数错,而是 core 不认识该能力。

判断方法:

  • 查客户端 core 版本。
  • 查 release 说明或官方文档确认是否支持 Reality 和对应 flow。
  • 临时换一个已知支持的客户端测试同一组参数。

不要为了兼容旧客户端随手改服务端 flow,除非你知道服务端用户配置也同步改了。

最后检查表

  • 服务端 NTP 正常,系统时间没有明显漂移。
  • 客户端设备启用自动时间。
  • SNI 命中服务端 serverNames
  • publicKey 与服务端 privateKey 是同一组。
  • shortId 命中服务端 shortIds
  • fingerprint 固定为客户端支持的值。
  • flow 与客户端 core 版本匹配。
  • dest 指向真实可达的 HTTPS 目标。

相关阅读