先理解:一次访问可能用到不止一个 DNS
系统解析器、浏览器安全 DNS、代理内核 DNS 和节点服务器自己的解析器,可能分别参与同一次访问。把系统 DNS 改成某个公共地址,并不保证浏览器和内核跟着变化。先看失败发生在哪一层,再决定改哪里。
| 现象或日志 | 先查什么 |
|---|---|
| 节点域名 lookup failed | 代理服务器地址怎样解析、引导解析是否可达 |
| 节点能连接,特定网站解析超时 | 该目标命中的 DNS 策略与上游路径 |
| 浏览器正常,命令行解析失败 | 浏览器安全 DNS 与系统 DNS 的差异 |
| DNS 返回 198.18.x.x | 是否启用了 fake-ip,以及后续流量有无被内核接管 |
第一步:用一个失败域名做对照
记录实际失败的域名,而不是整段带路径的网址。下面用 example.com 演示;真实排障时换成你的目标。先在客户端断开且系统代理关闭时记录结果,再连接客户端复测。保留报错类别和时间,不要一口气换三组 DNS。
nslookup -type=A example.com
nslookup -type=AAAA example.comdig example.com A
dig example.com AAAA
scutil --dnsnslookup 和 dig 有自己的查询行为,不一定复现浏览器、应用或 macOS 的全部分域解析路径。因此“dig 成功”只是线索,最终仍要用原先失败的应用验证。AAAA 返回空也不自动代表故障:目标可能没有 IPv6,或内核被配置为不返回 AAAA。
第二步:fake-ip 不是目标服务器的真实地址
fake-ip 模式会先给应用一个合成地址,再由内核把后续连接映射回域名。Mihomo 的示例地址段是 198.18.0.1/16,因此查到 198.18 开头的地址可能完全正常。它不能作为网站真实 IP、机房位置或泄露判断依据,也不适合拿去做普通的地理定位。
真正的问题是:应用拿到了 fake-ip,但连接没有回到负责这个映射的内核。例如停止 TUN 后应用仍缓存旧地址,或者解析在一个客户端完成而路由被另一客户端接管。先让 DNS 与流量接管回到同一套配置,再重启受影响的应用;必要时通过客户端支持的入口清理 fake-ip 缓存。
打印机、局域网主机名或某些需要真实 IP 的应用,可能需要精确的 fake-ip-filter。只给确认受影响的域名添加例外,并先读当前 filter-mode:blacklist 与 whitelist 的含义相反。不要为了一个本地域名把所有域名都放入过滤列表。
第三步:避免节点解析与 DNS 代理相互等待
如果 DNS 上游被要求经过代理,而建立代理又必须先解析节点域名,就可能形成启动循环。Mihomo 的 proxy-server-nameserver 用于节点域名解析,default-nameserver 用于解析 DNS 服务器本身的域名;两者并不是同一个用途。按服务方提供的可用模板配置,不要把整套 DNS 都指向尚未建立的代理。
使用 respect-rules 等“DNS 遵守路由规则”选项时,必须同时考虑节点引导解析与路由。先检查客户端日志里是节点域名失败,还是目标域名失败。若只把所有请求改成海外 DoH,可能把原本可启动的连接改成循环失败。
第四步:分别检查浏览器安全 DNS 和系统私人 DNS
- 在浏览器设置中查找“使用安全 DNS”,记下当前提供商或自动模式。做一次跟随系统的对照,再恢复你需要的设置。
- Android 用户在系统设置搜索“私人 DNS”。指定的私人 DNS 可能使用不同路径;普通 53 端口的 DNS 劫持并不能覆盖所有加密 DNS。
- 在客户端内核日志中确认目标 DNS 请求是否实际出现。如果没有出现,不要仅凭 TUN 已开启就认定它已经接管。
- 公司分域 DNS 和内网域名应遵循组织配置,不能用公共解析器替代后再期待内网名字能解析。
怎样验证修好了,哪些“修复”应避免
先在原应用里验证实际目标,再查客户端的连接记录,确认出口符合预期。断开后直连网站也应正常,重启客户端后故障不应复现。DNS 结果在不同地域、时间和 CDN 下可能不同,不能把与别人截图不一样当作污染证据。
不要为修 DNS 关闭 TLS 证书验证,也不要把整份 hosts 文件从陌生网站复制覆盖。清缓存只能处理残留记录,不能修复错误的上游路径或过期订阅。仍失败时,提供域名、解析层、错误类型和前后对照,隐藏订阅凭据后再求助。