应用声称隧道是健康的,可你需要的目的地有一半始终没有回应。第一反应是加一条路由或降低度量值,而这个反应正是最该先被杀掉的迷思。当客户端自己的 LAN 和隧道地址池声称同一个前缀时,路由表持有两件互相矛盾的事实,无论是默认路由还是度量值都无法解决。修复是一次编址决策,任何路由编辑都替代不了它。

为什么额外的一条路由无法拆分同一个前缀

一条路由无法把同一个前缀上的两个声明分开,所以明智的做法是停止寻找那条正确的路由。协议栈不会把相同前缀放在已连接路由之前,更具体的条目确实能抓到该地址,但会让拥有它的本地主机变得不可达。看起来像路由问题的,其实是编址冲突;两种修复改的都是地址,而不是路由。 在接受之前,先在自己的机器上验证这个说法。

ip route get 192.168.1.50
route -n get 192.168.1.50
Find-NetRoute -RemoteIPAddress 192.168.1.50

向系统查询单个地址,并留意它点名的是哪个接口。Linux、macOS 和 Windows 都会用一次只读查询来回答,报告选中的接口和下一跳,而不发送任何数据。当隧道处于连通状态而查询结果却指向物理网卡时,内核把它当作链路内地址,而不是隧道能够承载的地址。

把服务商分配的前缀和家庭路由器所服务的前缀并排放在一起,按字符串比较。完全一致是最清楚的情况;范围更大、包含家庭子网的服务商地址池同样会失败,只是更容易被忽略。只是看起来相似的两个前缀并不是冲突,所以改动之前先把两者都写下来。

读取客户端真正拿到的地址池

读客户端收到了什么,而不是服务商的宣传页面。提高 OpenVPN 客户端日志的详细程度,服务器下推的路由会出现在日志里,从而暴露隧道前缀;在别处,地址池会出现在连接详情或网卡本身上。向服务商索取其所用全部私有网段的完整清单,因为今天的单个 /24 明天可能变成两个。避开常见的 RFC 1918 网段,并不等于避开你实际被分配到的地址。

地址池也可能缩小或在区域之间迁移,所以清单需要有日期和负责人。任何早于你上次方案变更的服务商答复,都只能当作猜测而不是事实。在确定网段之前再问一次,并把答复和网络笔记放在一起,好让下一位接手证据。

你能做的修复是重新编号

如果 VPN 服务器不是你所能更改的, 迁移家庭 LAN 是唯一可用的修复,而这正是商业服务商下的常见情形。选一个在服务商地址池之外、也在你日后可能需要之外的网段,并对着每一个经由隧道到达的站点做核查。要预期短暂中断,以及一串更长的被遗忘设备:仍然持有旧地址的设备看起来能用,直到它需要网关为止。

  1. 先做清点:路由器自身的地址、DHCP 范围、保留地址、端口转发,以及任何手工填写过地址的设备。
  2. 然后在维护窗口内把路由器的 LAN 前缀和 DHCP 范围一起改掉,并先续租有线设备,再续租无线设备。
  3. 接着修正静态地址:打印机、网络存储,以及任何写死了网关的设备。
  4. 最后,重新连接 VPN 客户端,确认隧道地址不再与 LAN 冲突。

按这个顺序处理这些地址,而不是一次全部动手;把旧网段保留一段时间的记录,让过期设备是可辨认的,而不是神秘的。从不续租的设备会以连不上网关的方式自我暴露,这比打一通支持电话有用得多。如果路由器的租期超过一天,就在窗口期间把它们缩短。

别名能做什么、不能做什么

当服务器归你所有时,在客户端做地址转换可以把远端前缀暴露在空闲的本地网段里,于是同一台主机在第二个地址上应答。社区版 OpenVPN 用 client-nat来做到这一点,而该指令是该客户端独有的,人们常拿来比较的商业与移动客户端都没有它。这套安排需要一条与转换相符的路由、一个给别名用的空闲网段,以及一台愿意应答客户端未转换地址的服务器。当客户端属于你无法配置的托管服务商时,这些都没用。

改动生效后,先按地址、再按名称分别到达一台本地主机和一台远端主机,并记下系统每次选择的路由。名称仍可能解析到旧网段,所以地址和名称值得各查一遍。如果其中有设备在改动期间一直没重启,就把一台客户端和一台服务器侧设备重启,因为缓存的邻居表项比这次编辑活得更久。

把你最终定下的前缀写进人们真的会看的地方:网络笔记、路由器自己的备注字段、入门页面。总会有人再次选中 192.168.1.0/24,冲突也会随他一起回来。

相关文章