同时运行两个 VPN 客户端是一场路由之争,而不是隐私设置。哪个隧道拥有更具体的路由,流量就归谁,另一个虽然保持连接,却闲置不用。 企业网关于是看到一条从个人出口进来的连接,而本机上的企业客户端仍然看得见每一个适配器。判断这两件事哪一件才重要,就是全部功课。

路由表只选出一个赢家

在企业客户端启动前后各抓一次路由表,读接口那一列,而不只是看目的地址。外层隧道的普通默认路由很容易被顶掉,因为 /1 路由对比 /0 更具体。字面上的 0.0.0.0/1 和 128.0.0.0/1 这一对,把整个 IPv4 空间分成两半覆盖,胜过任何单条默认路由。装好之后,外层隧道仍显示已连接,却不承载任何流量。

ip route show default
ip route show | grep -E '^(0.0.0.0/1|128.0.0.0/1)'

策略路由可以完全绕开主表,所以规则和路由都要读。把带标记的流量送往另一张表的规则,会在查询主表之前先胜出。正因如此,才能让一个应用留在物理链路上,而其余一切走隧道。

ip rule show

Windows 用度量值来裁决

在 Windows 上,赢家是到目的地址度量值最低的那条路由,两个客户端都可以装上度量值不同的默认路由。要把路由表和接口配置放在一起读,因为度量值更低的适配器并不总是你以为的那一个。还会设置接口度量值的客户端,不必新增任何一条路由就能挪动默认路由。输掉的那个适配器仍然保持启用,只是什么都收不到。

route print -4
Get-NetIPConfiguration | Select-Object InterfaceAlias, IPv4DefaultGateway

比较两份输出,指出拥有 0.0.0.0/0 的接口。如果两个客户端都声称拥有它,就由度量值决定,这也是为什么连接顺序测试在不同机器上会显得不一致。如果两份输出都没有显示默认网关,说明客户端没有跑全隧道,链路论证也就无从谈起。

两个观察者,两种不同的视角

远端网关看到一条从外层出口进来的连接,再加上客户端转发进自己隧道的一切。本地客户端则看得到适配器、路由以及另一条隧道的存在,因为它以创建这些对象的权限运行。把两种视角分开才是要点;声称客户端察觉不到,并不是。

假设客户端想枚举什么就能枚举什么,转而按网关的视角来规划。依赖客户端一直看不见的设计,离崩溃只差一次更新。

DNS 和 IPv6 才是链路漏的地方

DNS 跟着胜出的那份解析器设置走,而那未必是数据包实际走的路径。经由企业隧道到达的企业解析器与设计一致;从隧道之外到达的本地解析器则不一致,它会暴露隧道本该隐藏的名字。IPv6 是第二处泄漏:双栈主机会继续用 IPv6 去往那些隧道只通过 IPv4 承载的目的地。要分别检查这两个协议族,因为只走 IPv4 的隧道对 IPv6 路由或解析器一无所知。

ip -6 route show default
resolvectl status | grep -A2 'DNS Servers'

要有意识地去修解析器和 IPv6 路由,而不是在上面再叠一条隧道。双重封装还会消耗 MTU,所以链路建起来后页面卡住时,先试更小的内层 MTU。解析器答得快,并不能证明它就是对的。

相关文章