为什么适配器顺序不决定实验室的 VPN 路由
虚拟机管理程序里的「适配器 1」并不能说明来宾会选哪条路由。每次改动硬件后,对比前缀、度量和策略规则。
虚拟机管理程序列表里「适配器 1」排在最前,只是显示顺序,来宾的路由表并不读它。真正决定路径的是前缀、度量,以及在两者之前生效的任何策略规则。因此给实验室虚拟机加一块桥接适配器,可能凭空多出第二条默认路径,而旧的 NAT 网卡仍然显示为存在、并被编为第二块。结果就是一台时通时不通的虚拟机,而且找不到任何配置改动可以解释它。
三个条件决定路径
这三个条件分别是:哪个前缀更具体、前缀打平时度量起什么作用、以及硬件改动后来宾实际应用了哪些规则。每一条都能用一条命令回答,没有一条取决于管理程序的编号。
最后一点才是判断标准:如果你说不出 VPN 端点自身地址会命中哪个前缀,你手里就没有路由策略,只有一套今天碰巧能跑的拓扑。
条件一:哪个前缀胜出
指向 10.8.0.0/24 的路由会压过默认路由,只要目标地址落在其中,这与度量无关,也与适配器顺序无关。这正是装了具体路由的 VPN 客户端能在第二块适配器出现、度量更低时继续工作的原因:具体性先于代价。用 ip route show 核对你以为在用的那张表,用 ip route get 203.0.113.9 看内核对某个具体目的地址真正会给出的答案。
端点自己的地址才是最要紧的检验。如果 VPN 服务器的地址是被新加的桥接适配器解析出去的,隧道可能根本建不起来,也可能建起来之后再丢掉自己的传输路径。要专门查这个地址,而不是假定隧道网卡就是答案。
条件二:度量做什么、不做什么
它的作用比多数人以为的窄。度量只在前缀相同的多条路由之间决胜,不能让更宽的路由压过更具体的路由。打平时数小者优先,而不同操作系统的计数方向相反,这也正是 Linux 与 Windows 之间互相照搬的建议经常自相矛盾的原因。
在来宾里,ip route show 会在每条路由旁打印度量,Windows 上的 Get-NetRoute 打印 InterfaceMetric 再加路由度量。两个都要读,因为实际偏好可能是相加,而不止一个字段。如果存在两条默认路由,那才是要报的发现:来宾有两条出路,谁胜出取决于一串硬件改动就能改掉的数字。
条件三:来宾实际应用了什么
配置不等于已生效状态。并非每个平台上网卡名都能跨硬件改动保持稳定,一条按名字匹配的配置现在可能谁都没被它配上。
要看的是已应用的状态,而不是打算实施的状态。ip -br link 列出当下存在的网卡,在装了 NetworkManager 的主机上 nmcli connection show 会显示哪个配置文件绑在哪块设备上。绑定失败的配置文件会让网卡挂着却没有地址,看起来像路由问题,其实是命名问题。恢复的快照会让情况更糟,因为来宾保存的状态里可能还引用新硬件已经不再提供的适配器身份。
让实验室拓扑可复现
把预期中的虚拟网络挂接和来宾配置一起存下来,让「角色到适配器」的映射是写下来的,而不是从列表位置推出来的。
通常给出四个角色就够了:私有链路、管理、对外传输和隧道。每一个都应当在文件里对应到具体的适配器和具体的来宾网卡。
然后在硬件改动、重启或恢复快照之后测真正的应用,并把到 VPN 端点的路由也纳入这次测试。如果网关虚拟机要充当唯一出口,就要确认被测虚拟机没有意外的第二条默认路径,因为桥接适配器加上的恰恰是第二条默认路径。要从来宾里测,而不是从管理程序控制台测,因为两者对哪块网卡是哪块可能并不一致。
VirtualBox 网络文档描述了各适配器模式以及每种模式连接到什么,加第二块适配器之前值得读的正是这一部分。标清每块适配器承担哪个角色的实验室,让路由变化可以被解释;依赖管理程序编号的实验室,则把每次改动都变成一次试验。