连接排障 · Clash 技术博客

Mihomo OpenVPN tls-auth 握手超时怎么修?

Mihomo 旧版在 OpenVPN 出站同时使用 tls-auth 与非 SHA1 auth 时,可能在 4 次重传后握手超时。本文说明升级 v1.19.31、同配置验证和失败回退。

  • Mihomo
  • OpenVPN
  • tls-auth
  • 握手超时
  • v1.19.31
本文目录

先确认是否匹配这次 OpenVPN 握手故障

Mihomo issue #2992 记录的是一个很窄的组合:OpenVPN 出站使用 tls-auth,同时 auth 配置为 SHA512。

配置可以加载,DNS 解析和 PROCESS-NAME 规则也能命中,但控制通道在 4 次重传后超时,客户端日志出现 make OpenVPN handshake: read hard reset response after 4 retransmits: context deadline exceeded。

报告环境是 Windows 11 与 Mihomo v1.19.29。HTTP 请求可返回 502,HTTPS 在代理接受 CONNECT 后没有继续收到 TLS 数据;同一 Mihomo 环境中,不使用 tls-auth 的另一条 OpenVPN 配置可以工作。

这组对照支持继续检查 tls-auth 与 auth,而不是先把问题归给 DNS、规则或整个代理入口。

PR #3189 确认旧实现把 tls-auth 控制包的 HMAC 固定为 SHA1。服务端若按 SHA256、SHA384 或 SHA512 等其他 auth 摘要校验,就会因标签长度不一致丢弃第一个控制包。

有服务端日志权限时,可能看到 TLS Error: cannot locate HMAC in incoming packet。使用 SHA1 的服务端不受这一特定缺陷影响,普通 TLS、证书、端口或网络错误也不在本文结论内。

适用范围速查

看到的条件是否匹配处理方向
type: openvpn、tls-auth、非 SHA1 auth 同时存在高度匹配继续核对版本和精确日志
日志包含 4 retransmits 与 context deadline exceeded结合字段后匹配备份后升级至 v1.19.31
只使用 tls-crypt 或 tls-crypt-v2不匹配按对应密钥、证书和服务端配置排查
auth 为 SHA1不属于该根因不要把所有握手超时归给本文修复
DNS 未解析、规则未命中或端口不可达证据不足先修复更早发生的连接阶段

脱敏核对 tls-auth、auth 与 key-direction

先复制一份只供排查的配置,不要直接改正在运行的原文件。确认代理项确实是 type: openvpn,并记录 auth、是否存在 tls-auth、key-direction、proto、端口和服务器域名。

官方文档说明 tls-auth 与 tls-crypt、tls-crypt-v2 互斥,使用 tls-auth 时 key-direction 支持 0 或 1;auth 支持 MD5、SHA1、SHA256、SHA384 和 SHA512,默认值是 SHA256。

不要把 tls-auth 静态密钥、username、password、客户端私钥、证书完整内容或真实服务器地址贴到公开工单。公开证据只保留字段名、摘要算法、脱敏地址、错误时间和首条相关日志;原始配置应保存在私有位置。

不要为了测试而删除 tls-auth、猜测 key-direction 或把服务端 auth 降为 SHA1。那会改变认证边界,无法证明升级是否修复了原问题,还可能让客户端配置与服务端不一致。

只读记录版本并检查候选配置
mihomo -v
mihomo -t -f /path/to/config.yaml

字段核对清单

  • 运行内核版本和构建架构已经记录
  • 目标代理明确为 type: openvpn
  • tls-auth 与 auth 同时存在,且 auth 不是 SHA1
  • key-direction 与原始 .ovpn 或服务端配置一致
  • tls-auth 没有与 tls-crypt 或 tls-crypt-v2 同时配置
  • 公开记录已删除静态密钥、账号、私钥、证书正文和真实地址

先排除更早发生的 DNS、规则与端口失败

握手错误只说明 OpenVPN 控制通道没有完成,不能单独证明原因。先确认服务器域名已经解析、目标 UDP 或 TCP 端口可达、请求确实命中这条 OpenVPN 出站,并保留一条已知可用出站作对照。

如果日志在解析、拨号、证书读取或配置校验阶段已经出现更早错误,就先处理那一条。只有 DNS 和规则都成功,连接进入 OpenVPN 握手,再出现 4 次 hard reset 重传超时,才符合 issue #2992 的诊断顺序。

同一个服务器、同一份脱敏配置和同一个 HTTPS 目标应贯穿升级前后。若测试期间同时更换节点、协议、端口、证书和 auth,即使连接恢复也无法把结果归因到 v1.19.31。

配置测试失败或字段不受支持

先修复 YAML 和当前版本支持范围,不进入握手结论。

服务器域名解析失败

先检查 DNS、proxy-server-nameserver 和系统网络。

规则没有命中 OpenVPN 出站

固定测试策略并确认 Connections 或日志中的实际出口。

端口立即被拒绝或一直不可达

检查服务端、端口、防火墙和 proto,不把它写成 HMAC 摘要问题。

进入握手后出现 4 retransmits,字段组合也匹配

保存基线,继续做 v1.19.31 版本对照。

升级前备份配置与旧内核

v1.19.31 是包含 PR #3189 修复的稳定版。升级前先记录当前二进制的完整版本输出、操作系统、CPU 架构、由哪个客户端或服务管理器托管,以及当前核心文件的实际位置。

完整备份配置、证书引用文件和旧核心二进制,但让备份保持私有。使用图形客户端时,还要记录它的核心更新入口与自动更新策略;应用版本和正在运行的 Mihomo 版本并不总是同一个值。

远程设备、路由器或无人值守主机必须先确认有不经过该 OpenVPN 出站的管理路径。没有备用入口时,不应在唯一连接窗口直接替换核心。

建立可回退基线

  1. 记录运行版本

    保存 mihomo -v 或客户端内核信息,并记录系统、架构和托管方式。

  2. 复制完整配置

    备份 YAML 与引用文件,原始 tls-auth key、账号和私钥只保存在私有副本。

  3. 保留旧核心

    复制当前可执行文件并标明版本,不用新文件覆盖唯一的回退副本。

  4. 固定验证目标

    记录策略组、OpenVPN 出站、同一 HTTPS 地址和升级前的精确错误。

  5. 确认备用管理入口

    远程环境先确保控制台、直连或另一条已验证出站仍可使用。

从官方 Release 升级到 v1.19.31

Mihomo v1.19.31 于 2026 年 9 月 14 日发布,Release 明确包含提交 6d179a1c:让 OpenVPN tls-auth 的 HMAC 摘要跟随 auth,而不是固定使用 SHA1。

最低目标是实际运行 v1.19.31;若使用后续稳定版,应确认其包含 6d179a1c 修复。只更新图形客户端界面或订阅不能替代核心升级。

直接运行 Mihomo 时,从 MetaCubeX/mihomo 官方 v1.19.31 Release 选择与操作系统、CPU 架构和构建变体一致的资产,并核对该资产在 Release 页面列出的 SHA256。

由 Clash Verge Rev、OpenClash 或其他前端管理核心时,使用该项目已有的官方核心更新入口,更新后再次读取实际运行版本。

停止旧核心后再替换文件,保留原权限、启动参数和服务配置。不要混用不同版本的单个库文件,也不要从搜索广告、网盘或不明镜像取得同名核心。

完成一次可验证的升级

  1. 选择正确资产

    系统、架构和构建变体必须与当前环境一致,并保存官方文件名和 SHA256。

  2. 停止旧实例

    通过当前托管工具正常停止核心,避免新旧进程同时读写配置或争用端口。

  3. 替换或应用更新

    按现有安装方式更新完整核心,不改变原 OpenVPN Profile 的认证字段。

  4. 先做配置测试

    确认 v1.19.31 能加载原配置,再启动服务并检查首条日志。

  5. 读取实际运行版本

    从命令行、API 或客户端内核信息再次确认当前进程是 v1.19.31,或是已确认包含该修复的后续稳定版。

用同一 OpenVPN Profile 验证修复

升级后的关键不是界面显示成功,而是同一服务器、同一 Profile、同一 auth 和同一 tls-auth 能完成控制通道握手。先固定策略组选择,让一条请求明确命中该 OpenVPN 出站,再访问升级前使用的同一 HTTPS 目标。

检查日志不再出现 read hard reset response after 4 retransmits,并确认请求得到真实 HTTPS 响应。还应验证一条普通出站,确保核心升级没有破坏其他路径;需要 UDP 时再单独做一次真实 UDP 业务验证,不能用延迟数字代替。

不要把关闭 tls-auth、改为 SHA1 或换到另一台服务器后的成功算作修复验证。那些变化只能证明另一条配置可用,不能证明 v1.19.31 已修复原组合。

把端口换成当前 HTTP 或 mixed-port,并确保策略已选中目标 OpenVPN 出站
curl -I -x http://127.0.0.1:7890 https://example.com

v1.19.31 修复验收清单

  • 实际运行版本为 v1.19.31,或为已确认包含该修复的后续稳定版
  • 配置、服务器、auth、tls-auth 与 key-direction 没有因测试被改动
  • 测试请求确实命中目标 OpenVPN 出站
  • 日志不再出现 4 retransmits 的 hard reset 握手超时
  • 同一 HTTPS 目标返回有效响应,而不是只有本地代理端口可连接
  • 普通出站与基础网络仍正常,需要 UDP 时已另做真实 UDP 验证
  • 旧核心、私有配置备份和回退步骤仍然可用

v1.19.31 仍失败就停止套用这次根因

如果实际运行版本已经是 v1.19.31 或确认包含该修复的后续稳定版,却仍出现握手失败,不要继续把所有错误归给旧版固定 SHA1。先比较错误是否还是同一条、请求是否仍命中同一出站,以及服务端是否同时记录 HMAC、证书、密钥方向或认证失败。

重新核对 ca、cert、key、tls-auth、key-direction、auth、proto、端口和系统时间;确认 tls-auth 没有和 tls-crypt 或 tls-crypt-v2 混用。若服务端配置或密钥近期变化,应以服务端当前配置为准,不从旧客户端文件猜测。

只有原错误消失、换成另一条明确错误时,才按新的首条错误继续排查。反复修改摘要、密钥方向和证书会破坏版本对照,也可能触发服务端的失败保护。

版本仍显示 v1.19.30 或更早

修复核心更新路径;当前进程尚未使用包含修复的版本。

规则改走 DIRECT 或另一条代理

恢复明确的测试策略,不用错误出口判断 OpenVPN 结果。

服务端报告 incoming packet authentication failed

核对 tls-auth key 和 key-direction,不重新生成或公开密钥。

出现证书、私钥或 CA 错误

转入证书链和客户端身份排查,不再使用本文 HMAC 根因。

仍是相同 4 retransmits 且字段、版本均吻合

保存最小脱敏配置、两端首条日志和版本,向 Mihomo 项目提交可复现证据。

升级异常时回退,但不要降低认证

如果 v1.19.31 在当前设备上引入其他启动或兼容问题,可以停止新核心,恢复升级前保存的完整旧二进制和原配置,再通过同一托管入口启动。回退后先确认版本和配置加载,再验证普通出站与设备管理入口。

旧核心会重新带回本文描述的 tls-auth 非 SHA1 握手问题,所以它不是这条 OpenVPN Profile 的长期修复。业务需要立即恢复时,应切换到已经验证可用的其他节点或协议,或暂时停用该 Profile;不要删除 tls-auth、猜测 key-direction,或为了兼容旧客户端降低服务端 auth。

后续重新升级时,继续使用同一脱敏基线、官方资产和真实请求。向上游反馈应包含系统、架构、完整版本输出、字段组合、升级前后首条相关日志和最小复现步骤,但绝不能包含静态密钥、账号、私钥或真实服务地址。

安全回退完成标准

  • 旧核心与原配置作为完整的一组恢复,没有混用新旧组件
  • 普通出站、基础联网和设备管理入口已经恢复
  • 受影响的 OpenVPN Profile 已停用或明确标记为仍未修复
  • 没有删除 tls-auth、改变 key-direction 或降低服务端 auth
  • v1.19.31 的资产、日志和失败现象已保留用于后续复测
  • 公开反馈只使用脱敏副本,不包含任何认证材料

参考资料