为什么 Windows VPN 路由表里会出现 0.0.0.0/1 和 128.0.0.0/1
默认网关选项添加的是两条半默认路由,而不是一条。在客户端上添加或删除路由之前,请先看清前缀、度量和接口。
连接到 Windows VPN 并打开路由表,有两个条目很显眼:0.0.0.0/1 和 128.0.0.0/1。它们不是笔误,也不替代默认路由。它们是否出现取决于一个配置文件选项,而这个组合是构建完整隧道的方式,并非拆分隧道的功能。改任何一行之前,请把选项、前缀和接口放在一起读。
默认网关选项安装了什么
把所有流量送进隧道的那个配置文件选项,是通过添加这两个前缀来实现的。取消该选项,它们就消失,只留下一条仅覆盖分配给隧道适配器的子网的路由。复选框控制的是这对路由,而不是重写唯一的那条默认路由。这就是为什么取消勾选后,路由表看起来像部分改写,而不是删除。
0.0.0.0/1 覆盖 IPv4 空间的下半部分,128.0.0.0/1 覆盖上半部分,合起来覆盖所有单播地址。两者都比默认的 0.0.0.0/0 更具体,因此最长前缀匹配会把普通流量送进隧道,而物理默认路由留在原处。保留那条默认路由不是装饰:包裹加密负载的数据包目标地址是服务器的公网地址,必须从物理适配器出去。若把默认路由替换掉而不是劈成两半,隧道自身的传输就会试图进入隧道,那是环路而不是连接。
因此,出现一条字面意义上的 0.0.0.0/0 指向 VPN 适配器时,值得停下来看一眼。原生客户端通常不会写这种路由,所以要么是手工添加的路由,要么是别的客户端改动了路由表。在往下排查任何问题之前,先把它找出来。
拆除比保留网关更省事
拆除是选择两条而不是一条的实用理由。连接期间客户端正好拥有两条路由,断开时把它们删掉,物理适配器当时持有什么就保持什么。而替换掉唯一默认路由的客户端必须记住原来的网关,DHCP 租约变化之后还可能恢复一个已不存在的网关。两条自有路由不携带这种状态。
其他客户端也采用了同样的设计。带 redirect-gateway def1 的 OpenVPN 配置文件安装的就是这两个前缀,而不是删除默认路由;Windows 客户端出于同样的路由原因沿用这一模式。
这也是为什么在你期待拆分时,路由表却可能看起来像完整隧道。这个组合是构建完整隧道的方式,不是拆分隧道出错的证据。如果配置文件设置为使用远端网关,那么所有流量都会被路由,无论某个本地应用还能不能访问到什么。
最长前缀在任何度量之前就已胜出
前缀长度先于其他任何字段决定查找结果。度量只在前缀完全相同的路由之间打破平局,所以 /1 条目会胜过 /0 默认路由,即使它的度量更差。接口绑定决定的是:当两条路由共享同一前缀、Windows 必须选择由哪个适配器发包时,剩下的是什么。
route print -4
Get-NetRoute -AddressFamily IPv4 | Sort-Object DestinationPrefix
Find-NetRoute -RemoteIPAddress 10.50.5.20
拆分隧道的路由表里有物理默认路由、两条半默认路由、隧道子网的路由,以及你添加的任何办公网前缀。物理默认路由的度量可能更低也可能更高,取决于客户端和配置文件;只要 /1 这对路由还在,那个差异什么也不改变。一旦这对路由被移除,一切都会变,正是那时过期网关或错误接口浮现出来。要读整张表,而不是你预期会变的那一行。
为办公网前缀选择一个所有者
对于拆分隧道,只点出必须走 VPN 的那个前缀,并选定一种拥有它的方式。把路由指向分配到的隧道地址,在该地址变化之前一直有效;而绑定到接口虽然能扛住地址变化,但配置文件重建后索引被重新分配时就会断掉。绑定到配置文件的 cmdlet 避开了这两个问题,代价是需要那份配置文件。
route -p add 10.50.0.0 mask 255.255.0.0 172.16.8.1
route -p add 10.50.0.0 mask 255.255.0.0 0.0.0.0 IF 31
Add-VpnConnectionRoute -ConnectionName Office -DestinationPrefix 10.50.0.0/16
cmdlet 把前缀绑定到具名配置文件,于是路由随连接出现、随连接消失,这正是受管笔记本电脑想要的。持久路由能熬过重启,也能熬过促成它的那份配置文件,于是退役的 VPN 会在机器上留下多年不去的条目。每个前缀只选一种方法,并把选择记录下来,因为同一前缀的持久路由加配置文件路由会产生重复条目,拆除时很难理清。无论选哪种,所有权都应该体现在工单里,而不只是留在机器上。
所有权才是本节回答的问题,语法不是。 一个前缀有两个所有者,才是值得避免的故障模式。
用目标来验证,而不是用网站
测试必须穿过隧道的目标,而不是报告出口地址的网站。 Find-NetRoute 会返回选中的路由和源地址,于是你能看到是办公网前缀还是物理默认路由胜出,然后再去打开共享本身。
Find-NetRoute -RemoteIPAddress 10.50.5.20
Get-VpnConnection -Name Office
出口地址网站是很弱的检查,因为 DNS、IPv6 和浏览器代理都可能把那个请求送向不同路径。IPv4 和 IPv6 在同一个对话框里还有各自独立的设置,清掉一个勾选框不会动另一族,所以双栈机器可能让 IPv6 走隧道、而 IPv4 走拆分路由。在下结论说这是拆分之前,两族都要检查。如果路由正确而服务仍然失败,剩下的那层是过滤,而不是路由。
客户端管理的防火墙可以在路由表完美的情况下封掉办公子网。那条策略属于推送配置文件的人,而不属于编辑路由的人。