看起来像是两个 VPN 客户端在抢同一个套接字,而显而易见的修法似乎是卸载其中一个。实际上它们很少碰到同一个套接字。每次连接都会重写操作系统的路由表,而全隧道配置会占用默认路由。通常最后连上的那个赢,所以症状看起来像是从一个客户端转移到另一个。

冲突藏在路由表里

虚拟网卡加上一条默认路由,就是全隧道接管流量的方式。当第二个客户端装上自己的默认路由,旧的那条会被替换,或按度量值被压低,于是所有目标都改走较新的隧道。第一个客户端仍然保持连接,还显示绿色图标,也就是接口还在,路径却没了。正是连接状态与路由状态之间的这种分离,让现象显得混乱。

两个客户端是同一张共享表的编辑者。知道哪次修改发生在最后,几乎能解释所有症状。

读出当前路径归哪条隧道

与其相信自称已连接的客户端,不如检查真实的决定。问系统某个具体目标会由哪个接口承载。

ip route get 10.20.0.5
route print -4

第一条命令会给出某个目标的接口与源地址,这正是你真正关心的问题。路由转储在 Windows 上显示互相竞争的默认条目及其度量值,于是能看出当前哪条占优。要在每个远端网络里各查一个主机,因为一个目标可能正常,另一个网络却不可达。如果答案指向错误的隧道,重连不会有用;必须改路由策略。

阻止第二个客户端占用一切

一个客户端应独占默认路由,另一个只承载自己的前缀。OpenVPN 客户端可以拒绝服务器推送的配置。

pull-filter ignore "redirect-gateway"
ip route get 10.30.4.10

route-nopull 会忽略所有被推送的路由,而 pull-filter ignore "redirect-gateway" 只丢弃默认路由指令,保留被推送的 DNS 和其他选项。按你还想保留多少服务器配置在两者之间取舍,然后补上第二个网络需要的具体前缀。别忘了 DNS,因为不承载查询的隧道推送来的解析器什么也返回不了。在每个网络里各测一个已知主机,并确认远端看到的源地址。

重叠的子网绕不过去

当两个网络公布同一前缀,内核只能为两个不同位置保留一条记录,必须做出选择。主机路由无法凭空补上缺失的区分,调度量值也不行。给一侧重新编址,或者让它的管理员转换远端网段,使前缀不同。先核对真实子网再怪客户端,因为家用路由器默认的 192.168.1.0/24 撞上办公网段的次数,比任何人预想的都多。把两个网段都写进工单,免得下一次变更又把重叠造回来。

也要区分两个目标:同时到达两个网络是路由问题,而为隐私串联隧道是另一种设计,路径上多了一个运营方。不要用其中一个去解决另一个。

相关文章