你检查宿主机的公网 IP,看到 VPN,就断定虚拟机已被覆盖。这个结论并不能由这次测试支持。 客户机有自己的路由表、自己的解析器和自己的网络接口,而宿主机的出口地址对它们一无所知。

测试必须在客户机内部运行,并且必须说明它测了什么。

从客户机内部开始,而不是在宿主机浏览器里

先记录 hypervisor 的网络模式:NAT、桥接、仅主机或 macvtap。在 NAT 模式下,宿主机为客户机的流量做路由,所以宿主机的隧道是否生效,取决于客户端如何安装路由。在桥接模式下,客户机是物理 LAN 上的对等节点,宿主机的隧道与它无关。这两种模式在同样的宿主机配置下会给出相反的答案。

在改动任何东西之前先把模式写下来,因为正是它决定了结果能意味着什么。

发出一个你知道目的地址的请求

向一个会报告它所见源地址的服务发一个无害请求。然后检查客户机自己对该目的地址的路由决策:ip route get 203.0.113.5会打印客户机将使用的接口和网关。

如果接口是客户机的普通网卡,流量就没有走客户机内部的隧道。

第二块网卡、代理设置或客户机侧的 VPN 客户端,可能改变某个应用的答案,却不改变另一个应用。要测试你真正关心的应用,而不是 shell 里随手发出的通用请求。

单独检查解析器

出口地址变了,并不能告诉你哪个解析器处理了这个主机名。用与平台匹配的工具显式查询该名称,并记下是哪个服务器应答的。Split DNS 意味着解析器问题和路由问题有不同答案。

这两者可能朝任一方向分叉,而这种分叉往往就是真正的 bug。

在 systemd 主机上,resolvectl query会指出应答背后的接口和 DNS 服务器。较旧的配置会在 dig 的输出里显示服务器。无论哪种方式,重点都是看清哪个服务器作了应答,而不只是有没有收到应答。

测试失败策略,而不只是成功路径

如果要求是任何流量都不得离开隧道,那么一次成功的请求什么也证明不了。使用客户端支持的可控失败测试:按受支持的方式停掉隧道,看客户机的新请求是否被阻断。不要假设宿主机客户端的 kill switch 覆盖了每一种虚拟转发安排。它文档化的作用范围才是你唯一能依赖的东西。

隧道断开时回落到物理网卡的客户机,做的正是 NAT 模式所允许的事。

记录模式与范围

写下 hypervisor 模式、客户机的接口与路由、解析器,以及你测试的应用。再加上日期,因为快照恢复或 hypervisor 更新都可能改变这四项。

如果 IPv4 走了隧道,就照实说。不要把结论扩展到 IPv6、别的命名空间,或另一张网络上的另一台虚拟机。

相关文章