先区分 DNS 泄漏与解析器位置差异

Clash 已经开启代理,DNS 检测页却出现本地运营商,这通常说明仍有解析请求沿本机网络发出。但检测结果出现多个国家、多个解析器,也不一定意味着泄漏。应先明确目标:哪些域名允许本地解析,哪些域名必须经代理解析,再逐条核对。

本文的配置面向 Clash Meta(mihomo)内核。旧版 Clash、部分移动端客户端与其他代理工具的字段支持不同。修改前先在客户端的内核信息或运行日志中确认内核名称,并备份当前配置。不要仅凭客户端名称判断是否支持 respect-rules 或下面的 TUN 参数。

观察结果可能含义下一步
页面出口 IP 属于代理节点网页连接经过代理,DNS 路径仍未确认继续做 DNS 扩展检测
解析器显示本地运营商系统、浏览器或内核上游可能直连解析对照日志与 53 端口抓包
解析器显示公共 DNS 服务商请求到达公共递归解析器核对访问该解析器的出站路径
同时出现预期的国内外解析器可能来自有意设置的分域名解析按策略判断,不只看数量

建立基线:固定节点、浏览器与检测条件

按三组条件记录结果

  1. 关闭代理:记录公网出口、运营商名称和 DNS 检测结果,作为本地网络基线。
  2. 只开系统代理:固定同一个节点,关闭 TUN,重新运行标准检测和扩展检测。系统代理主要覆盖遵循代理设置的应用,并不自动接管系统全部 DNS。
  3. 开启 TUN:保持节点、规则与浏览器不变,启用 DNS 劫持后再测。记录解析器地址、时间和是否出现本地运营商。

可以使用 DNS leak test 或 BrowserLeaks 的 DNS 检测页面。每次重新发起检测,不要把上一次页面保留的结果当成新结果。连续做两轮;若只有一次出现异常,先检查浏览器缓存、节点切换和配置是否已经重载。

暂时排除浏览器独立 DNS

桌面 Chrome 的入口通常是「设置」→「隐私和安全」→「安全」→「使用安全 DNS」;Firefox 通常在「设置」→「隐私与安全」→「基于 HTTPS 的 DNS」。测试阶段先关闭浏览器独立 DoH,入口名称可能随版本调整。修复完成后若要恢复,应单独验证该 DoH 连接的出站。

无痕窗口不会自动关闭安全 DNS。浏览器通过 HTTPS 访问独立解析器时,流量通常使用 443 端口;即使 TUN 接管了这条连接,dns-hijack 的 53 端口规则也不会把它改成内核 DNS 查询。

  • Windows 清理系统 DNS 缓存可使用 ipconfig /flushdns。
  • 运行 systemd-resolved 的 Linux 可使用 resolvectl flush-caches;其他发行版按实际解析服务处理。
  • 同时清理或重启客户端的 DNS 缓存,并关闭测试页面后重新打开。只清系统缓存不能清掉所有应用缓存。

fake-ip 的作用:保留域名映射,而非自动隐藏查询

enhanced-mode: fake-ip 会为符合条件的域名返回合成地址,常见地址池是 198.18.0.1/16。应用连接这个地址时,mihomo 根据映射恢复域名,再执行规则与出站处理。因此,在本机看到 198.18 开头的解析结果,通常是预期现象,不代表远端服务器真的位于该网段。

fake-ip 改变的是客户端向应用返回的答案。后续是否需要真实解析、由哪个解析器处理、解析请求走直连还是代理,仍取决于连接方式、出站协议和 DNS 配置。仅开启 fake-ip,不能保证上游查询都走代理。

过滤列表只处理兼容性例外

局域网设备发现、打印机和部分依赖真实地址的程序可能需要加入 fake-ip-filter。例如 +.lan、+.local 可作为局域网域名的检查起点,但它们仍需要能回答这些名称的本地解析服务;把名称加入过滤列表不会自动启用 mDNS,也不会自动找到路由器。

不要为解决单个应用问题把所有域名都加入过滤列表。先确认故障域名,再增加最小范围的例外,并重测该域名的解析路径。返回真实 IP 与发生 DNS 泄漏是两个不同问题。

配置示例:分域名解析与上游出站

下面是可用于对照的 mihomo dns 与 tun 配置段,不是完整订阅。保留原配置中的节点、策略组和规则;合并已有的同名字段,不要在 YAML 顶层重复添加两个 dns。建议通过客户端的本地覆写或合并配置保存,避免订阅更新覆盖修改。

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - '+.lan'
    - '+.local'
  respect-rules: true
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  proxy-server-nameserver:
    - https://dns.alidns.com/dns-query
  nameserver:
    - https://1.1.1.1/dns-query
  nameserver-policy:
    '+.cn':
      - https://dns.alidns.com/dns-query

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
    - tcp://any:53
字段示例中的职责
default-nameserver引导解析 DNS 服务端域名,不是所有业务域名的默认上游
proxy-server-nameserver单独解析代理节点域名,减少代理建立前的解析依赖循环
nameserver处理未命中解析策略的普通域名查询
nameserver-policy按查询域名选择解析器,不负责指定网页连接的代理节点
respect-rules让 DNS 上游连接遵循路由规则,仍需核对实际命中的出站

这份示例还需要核对什么

  • 上游出站:如果目标是让普通域名经代理解析,应确认访问 1.1.1.1:443 的连接命中了预期代理组,而不是 DIRECT。若命中直连,调整现有规则的顺序与目标;不能只依赖 respect-rules: true 这一行。
  • 国内解析:+.cn 仅匹配相应域名范围,不等同于“全部国内网站”。国内服务也可能使用 .com,境外服务也可能使用 .cn。需要时按实际域名补充精确策略。
  • 引导查询:示例保留本地可达的引导解析器与节点域名解析器。这些查询可能直接发出。若要求包括节点域名在内的全部解析都不经过本地网络,需要另行设计可达的引导链路,不能直接照抄此段。
  • DoH 可达性:HTTPS 加密保护传输内容,但不等于连接经过代理。若当前网络无法直连相应解析器,应先解决路由或更换可达上游。

TUN 劫持 DNS:覆盖 53 端口,不覆盖所有解析协议

示例同时列出 UDP 与 TCP 的 53 端口劫持。前提是相关数据包确实进入 TUN;如果另一套 VPN、静态路由或应用绑定接口绕过了 TUN,这些规则不会生效。auto-route 用于自动配置路由,auto-detect-interface 用于识别出站接口,二者都应结合系统权限和实际路由表检查。

监听端口与劫持目标不要混淆

listen: 127.0.0.1:1053 表示内核提供一个本地 DNS 监听入口;dns-hijack 则把进入 TUN 的指定 DNS 请求交给内核处理。开启 TUN 劫持时,不必因此把系统 DNS 写成“127.0.0.1:1053”,多数系统 DNS 设置界面也不支持这种带端口写法。

只监听回环地址可限制外部设备访问。若准备为局域网设备提供 DNS,需要单独规划监听地址、防火墙与网关,不要为了修复本机泄漏直接改为面向所有接口开放。

  • DNS over TLS:常用 TCP 853,不属于上面两条 53 端口规则的匹配范围。
  • DNS over HTTPS:通常使用 HTTPS 443,需要按普通网络连接检查出站。
  • Android 私人 DNS:排查时可先在系统「私人 DNS」设置中关闭自定义提供商,再测试客户端 DNS。
  • IPv6:dns.ipv6: false 控制内核对 AAAA 查询的处理,不会关闭系统 IPv6,也不会自动接管已有 IPv6 连接。

复测与定位:从本地入口追到上游连接

先检查配置是否真正生效

  1. 保存覆写并重载配置,检查日志是否有未知字段、YAML 缩进或端口绑定错误。
  2. 检查 TUN 适配器和相关服务是否启动。Windows 上通常需要客户端服务或相应权限,仅打开界面开关不代表路由已经建立。
  3. 临时提高日志详细程度,观察测试期间的域名、规则与出站记录。排查完成后恢复常用日志等级。
  4. 清理缓存,使用相同节点重跑检测,把新结果与最初基线对照。

安装了 dig 的设备可以直接查询内核监听口,先确认 DNS 模块能正常响应:

dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com AAAA

A 查询在 fake-ip 模式下可能返回合成地址;按示例关闭 DNS IPv6 时,AAAA 查询可能没有地址答案。这组命令直接访问内核,只验证监听入口,不验证系统请求是否被 TUN 接管。仍需用普通应用发起连接并观察路由。

抓包检查仍然存在的旁路

在实际物理网卡上抓包,而不只看 TUN 虚拟网卡。Wireshark 可使用以下显示过滤器;其中 853 用来辅助发现常见的加密 DNS 连接,并不能覆盖所有加密解析方式。

udp.port == 53 || tcp.port == 53 || tcp.port == 853

若仍看到本机向运营商 DNS 发出普通业务域名查询,检查系统解析服务、浏览器、其他 VPN 与 TUN 排除路由。若只看到引导解析器或节点域名查询,要按前面设定的范围判断是否符合预期。DoH 走 443,不能仅凭这条过滤器的空结果宣布全部修复。

常见问题与验收标准

开了 fake-ip,检测页仍显示运营商怎么办?

先确认测试请求是否进入内核。若进入,再检查上游 DNS 连接的出站以及已有 fallback;若没有进入,优先检查浏览器独立 DNS、系统私人 DNS和 TUN 路由。反复更换 fake-ip 地址池通常不能解决这类路径问题。

nameserver-policy 会让对应网站自动直连吗?

不会。它决定域名交给哪个解析器;网站连接如何出站仍由 rules、模式与策略组选项决定。应分别验证“解析服务连接的出站”和“目标网站连接的出站”,不要把二者混为同一条连接。

换了网络后为什么又出现异常?

Wi-Fi 与有线切换会改变网关、接口和系统 DNS。休眠恢复后也可能留下旧路由。重新检查 TUN 服务、默认接口和本地 DNS 监听,再清缓存复测。若关闭客户端后系统无法解析,先恢复系统 DNS 与路由,确认基础联网正常后再加载配置。

什么结果才算修复完成?

  • 需要代理解析的测试域名,其上游连接命中预期代理出站。
  • 普通应用的 53 端口查询进入内核,物理网卡没有出现不符合策略的明文业务查询。
  • 浏览器 DoH、系统私人 DNS 与 IPv6 路径都已分别检查,而非只关闭其中一个入口。
  • 订阅更新、客户端重启与网络切换后再次检测,覆写和路由仍然有效。

DNS 防护的核心是让解析路径可解释、可复测。fake-ip 提供域名映射,nameserver-policy 选择解析器,TUN 劫持统一入口;最后还要用路由规则决定上游连接从哪里发出。四个环节对齐后,检测结果才有明确含义。