你的 DNS 记录是对的,替代服务器也是健康的,但一些客户端仍然花几个小时去连旧地址。少数客户端会立刻失败:那个名字能解析,却从不回应。两种结果都来自同一个缺口:主机名改变的是客户端查询什么,而不是它何时查询,也不是它在收到回应时信任什么。

症状:记录正确,隧道陈旧

保存名字的配置文件,并不等于一个会持续解析它的客户端。大多数客户端只解析一次——在应用配置时,或在隧道建立时——然后一直复用那个地址,直到会话结束。在此之上再叠加很长的 TTL,正是切换必须围绕重连来规划、而不是围绕 DNS 修改来规划的原因。

这两种行为都不是缺陷,而这恰恰让症状令人困惑。客户端使用的是它早先得到的答案,服务端这边没有任何东西能显示那到底是哪个答案。把重连纳入维护窗口,并告诉用户他们会看到什么;否则就把窗口花在回答工单上。结果通常是一长串一模一样的报告。

谁控制这个名字,客户端验证什么

对区域的控制权决定迁移能走多快。把记录留在你能登录的注册商那里,并写下还有谁能改动它。

信任并不跟着名字走。基于 TLS 的客户端可能检查证书身份或固定名称,而 WireGuard 认证对端的公钥,完全忽略主机名。这个差别决定了只改 DNS 是否足够,还是每个配置都需要新的指纹。记录变更绝不应该授权一个没人批准过的端点。

把管理访问和恢复访问与公开的客户端名称分开。丢掉一个托管账户,不应该连重定向客户端的那条记录也一起丢掉。把恢复路径存放在不依赖你正在离开的服务商的地方。

每个客户端何时重新读取这个名字

解析时机是每个客户端各自的属性,所以在承诺切换窗口之前,先检查你实际发布的实现。wg-quick 在接口启动时解析端点,并一直保留那个地址,直到隧道重启。而 OpenVPN 客户端在连接时查询名字,重连时是否再看一次取决于它的选项。

ClientWhen it resolvesWhat it verifies
wg-quickAt interface start, cached for the sessionPeer public key, not the name
OpenVPN 2.6On connect, possibly again on reconnectCertificate identity or pinned name
Mobile clientsMay hold the answer across sleep or a network changePlatform trust store, same certificates

移动客户端是常见的意外,因为它们可能在休眠或网络切换期间一直保留已解析的地址。只有替代服务器在两种地址族上都应答时,才同时发布 A 和 AAAA 记录。只在一个地址族上应答的地址,证明不了另一个地址族的情况,而一条失效的 AAAA 记录会给每次尝试都加上超时。为你支持的每个客户端记录解析行为,然后在人们真正使用的设备上测试。

在大多数客户端里,重连是用户的操作,服务器无法强制。把这一步写进维护说明,并附上一句用户会看到什么。

以证据为依据切换,然后退役旧端点

切换之前,在替代服务器上逐层验证:监听器能应答,防火墙放行端口,路由回程正确,名字解析到新地址,已知身份被接受。能接受连接的监听器,并不等于能完成握手的监听器,所以要测握手,而不是测端口。把当前的吊销列表放在配置旁边,因为恢复的备份会把对端列表恢复成原来的样子,从而重新打开你已经关闭的访问。记录你用哪个身份做了测试,因为「它能用」不是任何人都能复现的证据。

getent hosts vpn.example.com
ss -lunp | grep 51820
wg show wg0 latest-handshakes

过渡期间,观察两个端点上同一身份的连接尝试。仍在向旧地址认证的客户端,是一个从未移动过的配置或缓存答案。按有日期的计划退役旧端点,因为两个服务接受同一个身份,等于两扇门都开着。

切换测试是通过新端点的一次应用会话,而不是 ping。一旦该会话可用,并且旧端点在整个重连周期内没有记录到任何已授权尝试,迁移就完成了。

相关文章