ping 一个字面地址,它有回应。按域名打开网站却毫无动静,而网络图标仍坚称连接正常。在一台刚连上 VPN 的 Mac 上,这种组合几乎总意味着查询指向了一台已经不可达的服务器,而不是网络断了。这些地址在早前某个时刻被写死到了 Wi-Fi 服务上,此后没人移除过。用排除法诊断,然后删掉那些写死的条目。

修法是删除而不是刷新,这个区别很重要,因为大多数人最先尝试的命令做的是完全另一件事。

“已连接”只是在说链路

macOS 为每个网络服务保存一份解析器配置。来自 DHCP 的值是一个来源,手动输入的是另一个,配置文件推送或客户端写入的是第三个。写死的条目优先级高于网络提供的值,而协议栈里没有任何东西会重新校验它们。因此已经消失的服务器会一直留在列表里,直到有人删掉它或服务被从头重建。

这就是为什么隧道完成握手,对一条早已走错方向的查询毫无帮助。VPN 只是加了一个解析器,并没有审查那个正在失败的老配置。

把域名和报文分开

先用字面地址访问一台主机。能打开,说明报文正常,问题在解析器。打不开,就停在这里,把问题当成路由问题处理,因为改 DNS 只会给本就混乱的图景再加一个变量。

域名失败而对应地址成功,就是指纹。也要看范围:全都失败指向一条坏掉的全局配置,只有隧道内的主机失败则指向另一个责任方和更窄的修法。

删掉写死的服务器

在“网络”设置里打开 Wi-Fi 服务的详细信息,切到 DNS 标签页。逐行移除服务器,确认改动,再看看搜索域里有没有你从未添加过的值。让列表保持为空,重新连接该服务,并确认 DHCP 下发的地址会自己回来。空列表正是证明问题出在写死值上的那个临时状态。

较旧的版本把同一个面板藏深一层,放在“高级”按钮后面,行为与结果都一样。

读状态,而不是读面板

scutil --dns | head -40 会按范围分组打印 macOS 实际在用的解析器,而对一个已知内部域名做一次 nslookup,就能看出到底有没有应答。把两份输出对照一下:面板很干净、却仍列着过期服务器,说明这项设置归另一个写入方所有。那是另一个缺陷,需要另一种修法。

两者都干净而域名仍然失败时,故障已经挪到别处,你也不再是在调 DNS 配置了。

是谁把条目放回去

删除后又回来的服务器必有来源。去“设备管理”里找配置描述文件,因为描述文件可以携带 DNS,并按自己的节奏重新生效。去客户端的偏好设置里找“连接时设置 DNS”之类的选项,并判断它在这台机器上是否还值得保留。如果 VPN 确实需要私有解析器,就把范围限定在它自己的域名上,而不是写进那张会被未来每个网络继承的全局列表。

记下预期的解析器和它应当应答的域名。下次客户端更新后,各验证一个公网域名和一个内网域名,这比再走一遍设置流程更快,也能在机器还在你手里时抓住回归。

其余都是维护表演:看似果断的命令,改不了任何可测的东西,只把同样的坏查询留给下一个人。

相关文章