更换 VPN 服务商:规划主机名,而不只是 IP
新的 DNS 记录不会迁移现有会话。请规划由谁控制这个名字、每个客户端何时解析它,以及你将如何退役旧端点。
你的 DNS 记录是对的,替代服务器也是健康的,但一些客户端仍然花几个小时去连旧地址。少数客户端会立刻失败:那个名字能解析,却从不回应。两种结果都来自同一个缺口:主机名改变的是客户端查询什么,而不是它何时查询,也不是它在收到回应时信任什么。
症状:记录正确,隧道陈旧
保存名字的配置文件,并不等于一个会持续解析它的客户端。大多数客户端只解析一次——在应用配置时,或在隧道建立时——然后一直复用那个地址,直到会话结束。在此之上再叠加很长的 TTL,正是切换必须围绕重连来规划、而不是围绕 DNS 修改来规划的原因。
这两种行为都不是缺陷,而这恰恰让症状令人困惑。客户端使用的是它早先得到的答案,服务端这边没有任何东西能显示那到底是哪个答案。把重连纳入维护窗口,并告诉用户他们会看到什么;否则就把窗口花在回答工单上。结果通常是一长串一模一样的报告。
谁控制这个名字,客户端验证什么
对区域的控制权决定迁移能走多快。把记录留在你能登录的注册商那里,并写下还有谁能改动它。
信任并不跟着名字走。基于 TLS 的客户端可能检查证书身份或固定名称,而 WireGuard 认证对端的公钥,完全忽略主机名。这个差别决定了只改 DNS 是否足够,还是每个配置都需要新的指纹。记录变更绝不应该授权一个没人批准过的端点。
把管理访问和恢复访问与公开的客户端名称分开。丢掉一个托管账户,不应该连重定向客户端的那条记录也一起丢掉。把恢复路径存放在不依赖你正在离开的服务商的地方。
每个客户端何时重新读取这个名字
解析时机是每个客户端各自的属性,所以在承诺切换窗口之前,先检查你实际发布的实现。wg-quick 在接口启动时解析端点,并一直保留那个地址,直到隧道重启。而 OpenVPN 客户端在连接时查询名字,重连时是否再看一次取决于它的选项。
| Client | When it resolves | What it verifies |
|---|---|---|
| wg-quick | At interface start, cached for the session | Peer public key, not the name |
| OpenVPN 2.6 | On connect, possibly again on reconnect | Certificate identity or pinned name |
| Mobile clients | May hold the answer across sleep or a network change | Platform trust store, same certificates |
移动客户端是常见的意外,因为它们可能在休眠或网络切换期间一直保留已解析的地址。只有替代服务器在两种地址族上都应答时,才同时发布 A 和 AAAA 记录。只在一个地址族上应答的地址,证明不了另一个地址族的情况,而一条失效的 AAAA 记录会给每次尝试都加上超时。为你支持的每个客户端记录解析行为,然后在人们真正使用的设备上测试。
在大多数客户端里,重连是用户的操作,服务器无法强制。把这一步写进维护说明,并附上一句用户会看到什么。
以证据为依据切换,然后退役旧端点
切换之前,在替代服务器上逐层验证:监听器能应答,防火墙放行端口,路由回程正确,名字解析到新地址,已知身份被接受。能接受连接的监听器,并不等于能完成握手的监听器,所以要测握手,而不是测端口。把当前的吊销列表放在配置旁边,因为恢复的备份会把对端列表恢复成原来的样子,从而重新打开你已经关闭的访问。记录你用哪个身份做了测试,因为「它能用」不是任何人都能复现的证据。
getent hosts vpn.example.com
ss -lunp | grep 51820
wg show wg0 latest-handshakes
过渡期间,观察两个端点上同一身份的连接尝试。仍在向旧地址认证的客户端,是一个从未移动过的配置或缓存答案。按有日期的计划退役旧端点,因为两个服务接受同一个身份,等于两扇门都开着。
切换测试是通过新端点的一次应用会话,而不是 ping。一旦该会话可用,并且旧端点在整个重连周期内没有记录到任何已授权尝试,迁移就完成了。