查询离开本机并到达家用路由器,而每个数据包都在走隧道。自然而然会认为缺少路由,但路由通常没有问题。Windows 可以按接口指标决定询问哪个接口的解析器,而隧道适配器往往在这场比较中输给无线接口。

一次泄漏的两种解释

路由解释认为有一部分流量逃出了隧道,所以默认路由或拆分隧道列表一定有错。这个解释用一条命令就能验证,只要默认路由指向隧道内部,这条线索就可以排除。先查它是因为成本低,等结果干净就把它放到一边。

排序解释认为流量完全在隧道内,查询却仍被发往另一个解析器。Windows 把解析器的选择当作带顺序的逐接口属性,因此指标更好的物理适配器可以为某个名称提供 DNS,即使发往已解析地址的数据包走的是隧道。两种解释在泄漏测试页面上给出相同的症状,所以测试本身并不是诊断。只有其中一种能通过修改路由来解决。

把指标和解析器放在一起比较

在隧道开启时记录接口、它们的指标以及配置的服务器。要把它们当作一张表来看,而不是两个独立的列表,因为问题在于哪个解析器排在前面,而不是存在哪些解析器。

Get-NetIPInterface -AddressFamily IPv4 | Sort-Object InterfaceMetric | Select-Object InterfaceIndex, InterfaceAlias, InterfaceMetric
Get-DnsClientServerAddress -AddressFamily IPv4 | Select-Object InterfaceAlias, ServerAddresses

如果隧道适配器的数字高于物理适配器,它的解析器就不会被优先使用,内部名称会交给物理侧提供的解析器。那台路由器可能从缓存回答、向下转发或直接拒绝,而这些结果没有一个是原本想要的设计。排序只是一种偏好,所以它会悄悄失败,而不是报错。

另一种同样常见的变体是隧道适配器上根本没有配置解析器。客户端拉起接口时没有推送 DNS,于是排序的问题根本不会出现。

抬高隧道并重新检查

在提权的终端里把最低的指标给隧道接口,或者提高物理适配器的值。两者都是逐接口设置,而且都可以还原,当你在改动一台你可能并不坐在它前面的机器时,这一点很重要。

Set-NetIPInterface -InterfaceIndex 27 -InterfaceMetric 1
Get-NetIPInterface -AddressFamily IPv4 | Sort-Object InterfaceMetric

改动立即生效,而 DNS 客户端和其他消费者会缓存已经做出的选择。在根据查询结果下结论之前,先重连隧道或重启。跑得太早的测试会复现旧的行为,看起来就像修复失败。

然后查询一个内部名称和一个公网名称,看看是哪台服务器作出了应答。Microsoft 的 关于自动指标的参考资料 解释了为什么最低值会被优先选择,以及自动分配是如何推导出来的。

让设置在重连后依然生效

在每次连接都会重建的适配器上手工设置指标,是一种会消失的设置。如果客户端重建了接口,这个覆盖就需要连接后脚本、策略,或者一份在连接期间掌控 DNS 的客户端配置。

物理适配器上静态配置的服务器则有反过来的同一类持久性问题。它们会一直为该接口应答,直到被移除,而 DHCP 会在下一次租约时重新填回,所以移除它们是一次测量,而不是设计。持久的设计是 面向内部命名空间的名称解析策略,或者一个在连接期间接管 DNS 的客户端。无论哪种做法,都要记录重连前后的解析器列表,测试结束后恢复原来的指标,并确认先前的行为已经恢复。

相关文章