VPN 搬迁了:为什么你的 OpenVPN 客户端仍在拨旧 IP
新的 DNS 记录只是一步。在期待重新连接之前,先比较解析器的回答、客户端实际拨出的地址和重启选项。
提供方更改了你的公网地址,你更新了动态 DNS 记录,客户端却仍然连不上。从外面看,像是记录没有生效。多数时候记录没有问题,客户端拨的是搬迁前解析出的地址,因为运行中的隧道和保存的配置文件对服务器身在何处各有各的判断。三层必须一致,而它们的更新节奏并不相同。
看配置文件拨向哪里,而不是 DNS 说什么
打开你实际使用的连接,读一读 remote 那一行。那里的数字地址永远不会跟随主机名更新,无论记录变得多正确。
然后检查 你编辑的配置文件是否就是客户端加载的那一个。导入的配置文件很常见:管理员可能几个月前复制了一份并保留了自己的版本,于是下载目录里的文件和应用里的条目可能不一致。在调试 DNS 之前,先比较客户端自身连接详情里的端点。
两个文件、一个端点——这里是常见的发现。
grep -nE '^remote|^resolv-retry|^persist-remote-ip|^float' client.ovpn
printf 'resolver says: '; dig +short vpn.example.net读取客户端下一次连接尝试
用详细日志重启连接,读取它写明将要联系的地址的那一行。重要的是那个值,而不是浏览器解析出的结果。
解析器的缓存仍可能保留上一个答案,有些网络保留的时间比记录的 TTL 要求更长。要问客户端实际使用的解析器,而不是你在别处测试过的公共解析器。
如果日志显示的是新地址、连接仍然失败,那问题已经转移:数据包发往某处,却没有人应答。这是监听器、防火墙或端口转发的问题,它在服务器一侧,而不在客户端的解析路径上。把这两种失败分开,因为把不可达的监听器当成 DNS 问题,会让你在同一个循环里绕两遍。
知道自己做的是哪种重启
并非所有重启都保留同样的状态,所以地址变更的表现会因进程如何被回收而不同。由信号触发的软重启会保留更多上一个会话的上下文,而完全停止再启动会从配置重新开始。如果你要测试客户端是否重新解析,你要的是从配置出发的那条路径。
持久化设置也很重要,因为它们的设计目的是保住已通过认证的东西,而不是追逐新地址。
最干净的测试是从目标配置文件全新启动,再看一眼写明端点的日志行。从部分保留的会话里学到的任何东西,都只是关于那个会话的陈述。
四个选项及其各自的分工
带主机名的 remote 才是让重新解析成为可能的设置;那一行写成字面地址就排除了它。resolv-retry 控制查找失败时的行为,而 2.6 已把它默认设为无限。所以加上它什么也不会改变,它也从不安排定期检查是否出现不同的答案。说它会轮询新地址的人,把恢复与新鲜混为一谈。
persist-remote-ip 讲的是连续性而不是新鲜:它在所支持的软重启范围内复用最后一次通过认证的端点。在测试搬迁时,这恰恰与你要的相反。如果你的构建启用了它,测试时先关掉,等新端点被证实后再恢复。若一直开着,一次成功的重连可能什么也不能告诉你关于 DNS 的事。
float 接受在会话中途地址发生变化的已认证对端,而且只在支持它的部署中生效。它不会刷新 DNS,也不会自行跟随提供方的变更。把它看作面向漫游对端的韧性功能,而不是服务器的动态地址机制。
在责怪客户端之前,先确认新端点
从你的网络之外,确认新地址在配置的端口上有监听器,并且提供方的转发指向它。一台没有开放端口的机器配上正确的 A 记录,产生的正是人们归咎于缓存的那个症状。
然后重连并确认两件事:客户端用预期的服务器证书完成了认证,且会话到达了你想要的资源。地址变更不会降低身份要求,而连到错误端点的成功连接比失败的连接更糟。OpenVPN 2.6 手册列出了全部四个选项及其各自的作用范围,这就是应该放在配置文件旁边的检查清单。
在重启承载你管理访问的隧道之前,先留一条带外进入服务器的通道。这一项预防就能避免此场景衍生的大多数事故。