解析 Mihomo DNS 泄露问题

摘要: 在使用 mihomo 或其他 Clash-core 代理工具的 TUN 模式时,很多用户会遇到 DNS 请求泄露至本地运营商 DNS 的问题,这不仅可能导致隐私风险,还可能影响网络访问的稳定性。本文将从一个真实的论坛讨论案例出发,深入剖析问题根源,并通过提供具体的“错误”与“正确”配置对比,一步步教您如何通过 nameserver-policystrict-route 彻底解决 DNS 泄露。

原帖参考: TUN模式配置疑问 - LINUX DO


一、问题的提出:为何 TUN 模式会“背叛”我的 DNS 设置?

在使用 mihomo 这类强大的代理工具时,我们追求的是对网络流量的精细化控制。然而,理论上的完美配置有时却会在实践中暴露出意想不到的问题。

一位用户在论坛中分享了他的困惑:在 Windows 系统上,他为 mihomo 精心配置了 fake-ip 模式。当使用系统代理 (System Proxy) 时,一切正常,DNS 解析纯净无污染。可一旦切换到功能更强大的 TUN 模式,通过抓包分析,他震惊地发现,网络中竟然出现了发往本地运营商 DNS(例如 114.114.111.114)的请求。

这无疑敲响了警钟:DNS 泄露了!这意味着,即使用户的 TCP/UDP 流量都被代理,DNS 查询这一“指路牌”却暴露了用户的真实意图和地理位置。

二、探究根源:fallback 机制的“副作用”

经过一番深入探讨,问题的矛头指向了 Clash 内核中一个常见但容易被误解的配置:fallback 机制。

  • TUN 模式与 fake-ip 的协同工作:当启用 TUN 模式和 fake-ip 时,任何应用程序发起的域名解析请求都会被 mihomo 的内置 DNS 服务器接管。mihomo 会立即返回一个 198.18.0.1/16 网段内的“假 IP”,让应用程序的流量被系统的路由表指向 mihomo 创建的虚拟网卡,从而实现全局代理。
  • fallback 的设计初衷与现实偏差fallback 机制的设计初衷是为了在主 DNS (nameserver) 解析结果不佳(例如解析到污染 IP)时,提供一个备选的、通常是更纯净的 DNS 服务器(如 Google DNS, Cloudflare DNS)来进行二次验证。然而,关键问题在于,默认情况下,mihomo 发往 fallback DNS 服务器的请求,并不会遵循用户设定的路由规则。它会直接通过系统的默认网络接口发出,这也就解释了为什么用户的本地运营商 DNS 会收到请求。

简单来说,fallback 像一个热心的“场外求助”,但这位求助对象却不遵守现场的“代理规则”,直接从“大门”跑了出去。

三、配置实战:从错误到正确的进化

为了更直观地理解问题,我们来看一个典型的错误配置示例。很多网络上流传的配置或自动转换的订阅都可能包含类似结构:

错误的配置示例 (易导致 DNS 泄露)

dns:
  enable: true
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  listen: 0.0.0.0:53
  nameserver:
    - https://dns.alidns.com/dns-query # 国内DNS
    - https://doh.pub/dns-query
  fallback:
    - https://dns.google/dns-query # 境外的纯净DNS
    - https://1.1.1.1/dns-query
  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - 240.0.0.0/4

问题分析:

  • 当访问国外网站时,nameserver 解析出的 IP 若在中国大陆 (geoip-code: CN),fallback-filter 机制被触发。
  • mihomo 会同时向 fallback 中的 dns.google 等服务器发起请求。
  • 这个请求不会经过代理,而是直接通过物理网卡发出,从而泄露给了本地网络。

正确的配置方案:nameserver-policy + strict-route

要从根本上解决问题,我们需要放弃 fallback 这种模糊不清的机制,转向更精准、更可控的 nameserver-policy

核心思路:为不同的域名群体,指定不同的解析策略,并强制所有 DNS 请求都必须遵守路由规则。

dns:
  enable: true
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  listen: 0.0.0.0:53
  use-hosts: true
  # 关键点 1: 强制 DNS 请求遵守路由规则
  # DNS 请求本身会匹配 `rules` 规则,需要为其设定代理
  strict-route: true
  
  # 关键点 2: 使用 nameserver-policy 进行精细化分流
  nameserver:
    - https://dns.alidns.com/dns-query # 作为默认或国内解析
    - 223.5.5.5
  nameserver-policy:
    # 匹配 geosite:cn 列表中的域名,使用国内 DNS 解析
    'geosite:cn':
      - https://dns.alidns.com/dns-query
      - 223.5.5.5
    # 匹配 geosite:gfw 列表中的域名(需要代理访问的),使用国外的 DoH
    # 注意:这里的 DoH 请求会因为 strict-route: true 而走代理
    'geosite:gfw':
      - https://dns.google/dns-query
      - https://1.1.1.1/dns-query
    # 确保微软、苹果等服务的稳定性,可直连解析
    'geosite:microsoft,apple':
      - https://dns.alidns.com/dns-query

  # 关键点 3: 移除 fallback 和 fallback-filter 相关的所有配置
  # fallback: [] # 可以留空或直接删除整个键

配置解析:

  1. strict-route: true: 这是防止泄露的“安全阀”。它强制 mihomo 内部发出的所有 DNS 请求(例如对 nameserver-policyhttps://dns.google/dns-query 的请求)都必须经过路由模块的判断。你需要有相应的规则(如 DOMAIN-SUFFIX,dns.google,PROXY)来确保这类 DNS 请求被正确地送往代理服务器。
  2. nameserver-policy: 这是 DNS 精细化管理的“指挥中心”。我们在这里制定了清晰的策略:
    • 国内域名 (geosite:cn):使用快速、准确的国内 DNS。
    • 被墙域名 (geosite:gfw):使用需要通过代理才能访问的国外 DoH 服务,从源头上保证解析结果的纯净。
    • 特殊服务域名 (微软、苹果):同样使用国内 DNS 保证连接稳定。
  3. 放弃 fallback: 在 nameserver-policy 的精准控制下,fallback 机制显得多余且危险。果断移除是最佳实践。

四、总结与参考

通过上述配置的调整,我们可以构建一个既高效又安全的 DNS 解析环境。在 TUN 模式下,无论是普通应用还是命令行工具,其所有网络流量(包括 DNS 查询)都将处于 mihomo 的掌控之下,彻底杜绝 DNS 泄露的风险。

这套配置的核心在于,从依赖模糊的“备选方案” (fallback),转变为制定明确的“行动纲领” (nameserver-policy),并用“纪律” (strict-route) 来约束所有行为。

官方文档与参考资料:

为了更深入地理解 Clash/Mihomo 的 DNS 配置,强烈建议阅读官方文档: