Windows 上 VPN 阻断本地 LAN:路由问题还是客户端策略?
Windows 上的本地 LAN 访问会因两种不同原因中断:缺少路由,或者网关策略丢弃该子网。三项检查可以判断是哪一种。
工作 VPN 一连上,你自己桌上的打印机、NAS 或开发机就停止响应。有时一条路由命令几秒钟就能修好;有时同一条路由明明正确,数据包却仍然消失,这说明你面对的是症状相似的另一类问题。判断归结为三个问题,而顺序弄反正是人们花一整晚反复删除、重加路由的原因。
动手前先问三个问题
第一:本地前缀有没有表项,它是否指向物理网卡?第二:连接时客户端是否从网关收到本地网络的许可或拒绝?第三:你只需要访问 LAN 的出站流量,还是互联网上的某些东西也必须能到达你机器上运行的服务?
第一个问题把路由故障与过滤故障分开。第二个问题告诉你路由修复是否被允许生效。第三个问题改变修复方式:路由修复的是出站流量,而无法到达的入站服务通常是监听绑定与返回路径的问题,加路由只会更糟。
| What you see | What it points at |
|---|---|
| No local prefix in the table | Missing route |
| Correct prefix, no reply | Client filter or gateway policy |
| Works by IP, fails by name | Resolver changed by the tunnel |
| Inbound service dies, outbound fine | Return path or listener binding |
问题一:路由、过滤还是名称
先读表,再往里加东西。接口索引很重要,下面每条路由命令都锚定在它上面:
route print -4
Get-NetRoute -DestinationPrefix 192.168.1.0/24 | Format-Table InterfaceIndex,NextHop,RouteMetric
直连子网通常在隧道启用时仍保留在链路由,因此表项可能存在而流量仍然失败。这种组合正是路由之后执行的过滤器留下的特征,也是第二条更具体的路由完全不起作用的情形。
分别按地址和按名称测试。如果 ping 192.168.1.50 有回应而 net view 192.168.1.50 没有,那路由表从来不是问题:隧道改变了解析器,本地名称不再解析。为这个加路由是白费功夫。
问题二:网关允许访问本地 LAN 吗?
商业客户端安装的不只是路由。它在连接时获得一份策略,这份策略可以包含明确的本地网络许可。在 Cisco IPsec 部署中,组策略带有 split-tunneling 设置和一个单独的本地 LAN 访问标志;客户端里的复选框只是一个请求,网关可以拒绝。在 AnyConnect 中,配置文件控制 split 的包含与排除列表以及同样的许可。在 Windows RRAS 上,对应物是配置文件中的默认网关选项加上服务器分配的静态路由。
标志关闭时,有文档记录的行为是:即使存在有效且更具体的路由,客户端仍会阻断发往直连子网的流量。这也是客户端并不拥有的路由会在你添加后几秒内消失的原因:客户端在重建它被告知要构建的状态,而不是在跟你较劲。
客户端日志会记录连接时的决定,读它比在机器上做任何实验都快。如果日志说本地访问被阻断,就停下:任何命令行修复都过不了这一关,剩下的路只有改策略、经隧道访问资源,或把客户端关进虚拟机、让宿主机留在本地网络。
问题三:你需要哪个方向?
发往附近设备的出站流量是路由问题。把 LAN 前缀指向本地网关,度量值要低到能压过隧道的默认路由:
route add 192.168.1.0 mask 255.255.255.0 192.168.1.1 metric 1 if 12
route add 192.168.1.50 mask 255.255.255.255 192.168.1.1 -p
第二种形式固定单台设备,当一个地址就是全部需求时,这正是你要的。netsh 的对应写法按接口名而不是索引记录同样的决定:
netsh interface ipv4 add route prefix=192.168.1.0/24 interface=12 nexthop=192.168.1.1 store=persistent
当地址与掩码不匹配时,路由命令会以 参数错误 失败,例如一个 /24 掩码的主机地址。子网路由用网络地址,单台主机用主机掩码。
入站方向不同。同一台机器上的 VNC 或 SSH 服务器会变得不可达,因为入站连接的应答从 VPN 网关出去后再也不回来。动路由之前,先看服务监听在什么地址上:
netstat -ano | findstr :5900
只绑定某一个地址的监听器不会在另一个接口上应答。把它绑到所有接口是一个有意的决定,要配合一条限定在你所信任网络上的防火墙规则。只有做完这些,路由修复才能恢复返回路径。
采用与问题匹配的最小改动
另一个常见动作是取消 IPv4 高级属性里的 “在远程网络上使用默认网关”。这会让互联网流量留在本地,但同时做两件事:VPN 不再是默认路径,客户端也不再收到远程网络的路由,包括 multicast。取消之后,除非服务器推送每个客户端都需要的具体远程前缀,否则远程 LAN 就消失了。
这种不对称决定了做事顺序。如果远端必须保持完全可达,就从服务器推送远程子网,别动本地默认路由。如果改不了服务器,就通过隧道分配的地址为远程前缀加一条永久路由,并用 route print 确认前缀指向 VPN 接口,而默认路由仍指向物理网关。
然后确认修复能挺过重连,因为非永久路由会随网卡消失,每次连接后运行的脚本才是它们该待的地方。在同一次会话里测试一台本地设备和一项远程资源,断开、重连,再测一次。如果路由看起来正确而本地设备仍然失败,回到问题二:客户端在过滤,答案是改策略,而不是加第二条互相竞争的路由。