TLS 握手失败是一类信息量很大的报错。它意味着数据包已经到达了对端、TCP 连接已经建好,双方开始协商加密参数——然后谈崩了。所以看到这类报错时,先别急着换节点或者重装客户端,那两件事基本不会改变握手的结果。
握手卡在了链路的哪一段
一次完整的连接大致分成三步:域名解析拿到 IP、TCP 建立连接、TLS 协商加密参数。握手失败发生在第三步,前两步都已经成功。
这个定位很重要,因为它直接排除了一大类猜测:线路不通、节点掉线、防火墙丢包这些问题会让你卡在第二步,报出来的是超时而不是握手失败。如果你的现象是全部节点同时不可用且都是超时,那应该走所有节点同时超时的排查路径,和本文不是一回事。
从报错关键词反推方向
把客户端日志翻到失败那一行,对照下表定位:
| 日志中的关键词 | 含义 | 优先处理方向 |
|---|---|---|
| certificate has expired / is not yet valid | 证书被判定为不在有效期内 | 先查本机系统时间,再查证书本身 |
| certificate signed by unknown authority | 证书签发方不被信任 | 证书链不完整或使用了自签名证书 |
| bad certificate / certificate name mismatch | 证书上的域名与请求的域名对不上 | 检查 SNI 与服务器地址配置 |
| handshake failure / no cipher suite | 双方支持的加密套件或协议版本没有交集 | 客户端或内核版本过旧 |
| unexpected EOF / connection reset | 握手中途被切断,没有正常关闭 | 服务端拒绝,或中间设备干扰 |
| timeout during handshake | 握手包发出后长时间无响应 | 链路质量差或握手被限速 |
日志里如果同时出现多行,以最早的那一行为准,后面的往往是连锁反应。
系统时间:排在最前面的检查项
证书校验依赖当前时间。系统时间只要偏出证书有效期范围,校验就会失败,而报错文本长得像是证书本身有问题,极容易误导方向。
几种典型场景:虚拟机长时间挂起后恢复、双系统之间切换导致时区处理不一致、路由器重启后设备没有及时重新同步、手动改过时间用于其他用途后忘记改回。
处理方式是把时间设为自动同步,确认时区正确,然后完全退出客户端再重启。只改时间不重启客户端,已缓存的状态可能仍在生效。
SNI 与域名配置
TLS 握手时客户端会在明文里告诉服务端自己要访问哪个域名,服务端据此挑选对应的证书。这个字段和证书上的域名对不上,握手就会被拒。
需要检查的地方:
- 节点配置里的服务器地址和 SNI 是否被分别填写过,两者不一致时以 SNI 为准;
- 手工改过 SNI 用于测试后忘了改回;
- 机场更换了证书域名而你用的还是旧配置,这种情况重新更新一次订阅通常就能解决;
- 使用 Trojan 这类以标准 TLS 为外壳的协议时,SNI 配置错误的影响尤其直接。
如果只有部分节点出现这个问题,更可能是机场那边个别节点的配置或证书出了状况,这种参差表现的判断思路可以参考部分节点失效的排查。
证书链与信任问题
报「签发方未知」时,分两种情况。
一种是服务端只发了自己的证书,没有附上中间证书,导致客户端无法把信任链拼到根证书。这属于服务端配置问题,本机改不了,只能反馈。
另一种是服务端用了自签名证书。这种配置下客户端必须显式信任对应证书,或者由机场在配置里预置指纹。如果你是从别人那里拿到的配置片段,很可能缺了这一部分。
顺带说明一点:临时打开跳过证书验证,只是用来确认「问题确实出在证书校验环节」的诊断手段。确认之后要把它关掉,长期开着等于主动放弃了对端身份校验。
协议版本与加密套件
握手失败但完全不涉及证书时,考虑双方支持的参数没有交集。老版本客户端可能不支持较新的 TLS 版本或加密套件,而服务端已经把旧版本关掉了;反过来,某些内核默认只启用较新的参数集,遇到配置保守的服务端也可能协商不成。
处理方式很直接:把客户端和内核都升级到较新版本再测。这一步在使用 VLESS 搭配各类传输层组合时尤其值得先做,不同版本之间对参数的默认取值差别不小,各协议在传输层上的取舍可以看几种主流协议的差别。
中间设备的干扰
如果配置没动过、时间也正确、换了客户端仍然失败,而且失败呈现出明显的时间规律(比如某些时段成片失败、隔一会儿又恢复),那多半不是你这边的问题。
有几个特征可以用来佐证:同一节点换一个网络环境(切到手机热点)就正常;同一网络下换一个使用不同端口或不同传输方式的节点就正常;失败集中出现在握手阶段而不是传输阶段。
这类情况本机能做的调整有限,可行的方向是换用端口更常规、特征更接近普通 HTTPS 的节点,或者向机场反馈具体的节点与时间段。
怎么确认已经修好
握手成功的判断标准不是「没报错」,而是要看到完整链路能跑通:
- 客户端日志里出现握手完成的记录,并且后续有正常的数据传输;
- 用该节点访问一个需要代理的网页,页面完整加载而不是停在连接中;
- 保持连接十分钟以上,期间不再出现新的握手错误——如果握手能成功但连接反复重建,那是另一类问题,见 WebSocket 长连接频繁中断。
三条都满足,才说明加密协商这一环真的稳定了。
仍未解决时收集这些信息
反馈给机场或者自己继续深挖时,下面这些材料决定了能不能定位到根因:
- 完整的日志片段,包含失败前后各若干行,而不是只截取报错那一句;
- 出问题的节点名称、协议类型、端口,以及配置里的 SNI 值;
- 本机系统时间与时区的截图;
- 同一网络下其他节点的测试结果,用来说明是个别现象还是普遍现象;
- 换网络环境后的对照结果;
- 客户端与内核的具体版本号。
有了这几项,对方基本能判断问题在服务端还是在链路上,而不必来回猜。