连接看起来一切正常:隧道已经建立,控制台也显示了专用端点,但每个请求都在名称解析上失败。本能的反应是怪隧道,而隧道通常是清白的。查询被发往一台对私有区域一无所知的服务器。任何路由改动都不会改变那个答案,因为问题在于到底问了谁。

查询到底到达了哪个解析器?

在查看隧道之前,先找出每条链路上挂着的解析器。Linux 通过解析器状态命令显示每条链路的服务器,macOS 则在 DNS 配置转储中显示带作用域的解析器。如果应答仍来自家用路由器,说明隧道链路从未被询问过。

resolvectl status
scutil --dns | head -40
dig +short internal.example.com

这里混在一起的是两个阶段:服务器推送解析器地址,以及客户端把它安装到活动链路上。配置文件里可能有这个选项,日志也可能显示它已经到达,但操作系统仍在继续使用旧服务器。把日志和链路报告的内容对照一下,然后相信链路。

使用云网络真正会应答的地址

云网络通常通过从网段基址偏移两位的保留地址来应答私有名称,所以从 10.0.0.0 开始的网络会在 10.0.0.2 上应答。有些提供商还会公布一个无需知道网段就能工作的链路本地解析器,当网络是别人搭建的时候这很有用。先把候选地址直接问一遍,再把它推给任何人。不是解析器的地址看起来和防火墙丢包一模一样,因为查询根本得不到任何应答。

如果直接查询能从网络内部应答,但穿过隧道时不能,那解析器没问题,两点之间的路径有问题。这个结果会把排查方向转到路由、转发和访问规则,而不是客户端配置。

隧道并不携带命名空间

数据包过得去,名称过不去。每一侧都必须被告知哪个命名空间属于另一侧,而那是持有该区域的人拥有的独立对象。常见的形式是为一个命名空间设置转发,指向可通过隧道到达的解析器。

实践中每个方向都需要自己的规则,因为拥有该区域的一侧必须把查询发出去。两个方向都要求查询来源被路由并放行,而应答方必须通过隧道返回应答,而不是发往互联网。把转发范围收窄,只让私有命名空间依赖这条链路。把所有查询都送过去,一旦隧道断开,小小的依赖就会变成全面中断。

按顺序走一遍边界

先测活动链路上安装的解析器,再直接查询该解析器,然后从远端做同样的查询,最后测试使用同一名称的应用。每一步隔离一个边界,所以失败会告诉你该看哪里,而不是从头再查一遍。应用失败但应答成功,指向的是证书信任或 API 策略,而不是 DNS。那些故障是真实存在的,换解析器修不好。

记下是哪一步失败。这一行正是下一个人需要的,记录它只要十秒钟。

把链条留在下一个人找得到的地方

把推送的解析器、转发规则、允许的查询来源和应答端点记在同一个地方。私有名称再次失败时,记录会显示隧道是否移动过、解析器地址是否变过,或者某条规则是否被收窄。没有它,每次故障都从零开始,最后落在同样的三种猜测上。

记录要短到能保持准确:四行、一个日期,以及每一部分的负责人姓名。过时的记录比没有更糟,因为它看起来权威,实际却是错的。

相关文章