DNS 泄漏的判断边界

Clash 已经显示代理连接,DNS 检测页却出现本地运营商,这是常见的排查起点。但“检测到多个 DNS 地址”并不自动等于泄漏。首先要确定目标:是只让需要代理的域名通过代理解析,还是要求除节点引导解析之外,所有公网域名查询都经指定出口发送?两种目标对应的合格结果并不相同。

本文把 DNS 泄漏定义为:域名查询没有按照预定策略发送,而是绕到系统、本地网络或其他未授权解析器。检测页展示的通常是接收测试域名查询的递归解析器,不是电脑配置的 DNS 地址,也不是代理节点本身。因此,DNS 所在地区与网页出口地区不同,只能作为线索,不能单独下结论。

观察结果可能原因下一步
出现本地运营商解析器系统查询未接管,或规则明确允许直连解析对照策略与 53 端口流量
出现公共 DNS 服务商内核或浏览器使用了该服务核对是否为预期上游及出口
解析器与节点不在同一国家公共 DNS 的任播、递归出口或地理数据库差异结合连接日志判断路由
每次出现多个地址同一服务使用多个递归出口,也可能存在多条解析路径比较运营主体,而非只数 IP

先做一组可复现的 DNS 泄漏测试

记录环境,再改变一个变量

  1. 记录客户端名称、内核名称和版本,以及当前使用系统代理还是 TUN。本文示例面向 mihomo,不适合直接套用到已经停止更新的旧版 Clash 内核。
  2. 退出其他 VPN、加速器与代理工具。先保留一个客户端运行,避免多个虚拟网卡和 DNS 设置互相覆盖。
  3. 在浏览器中手动打开 dnsleaktest.com,执行 Standard test,再执行 Extended test。记录解析器 IP、运营主体、检测时间与网页出口地址,不要只截取国家一栏。
  4. 关闭代理做一次基线测试,然后开启目标配置重测。基线测试会按本地网络方式联网,不适合在有严格网络隔离要求的环境中执行。
  5. 修改配置后重新加载内核,清理系统缓存并完全退出浏览器,再进行第二轮测试。保持同一节点、同一网络和同一检测页面,方便比较。

Windows 可在终端执行 ipconfig /flushdns 清除系统 DNS 缓存。它不会替你清除浏览器自身的解析缓存,也不会清除 mihomo 内核的全部运行状态。若检测结果始终不变,先重启浏览器与内核,再判断配置是否没有生效。

区分浏览器结果与系统结果

浏览器安全 DNS 可能直接通过 HTTPS 查询,绕过系统的 53 端口解析流程。为了定位,先在浏览器设置中搜索“安全 DNS”,暂时关闭该功能做对照;确认内核接管正常后,再决定是否恢复,并为该 DoH 连接安排明确的代理规则。浏览器测试正常,也不能证明命令行工具、游戏或其他应用使用了相同路径。

例如,一次对照记录可以写成“系统代理:检测到运营商与公共 DNS;TUN:仅检测到配置的公共 DNS”。这只是记录格式,不是实测结论。应当保留自己的结果,并用内核连接记录验证变化来源。

启用 fake-ip 与明确的 DNS 上游

编辑前先备份当前可用配置。订阅通常会被定期更新覆盖,应使用客户端提供的覆写或合并功能;如果不确定合并方式,就复制为独立本地配置验证。最终生效配置中只能有一个顶层 dns:,不要在文件末尾重复粘贴同名段落。

下面是 mihomo 的 DNS 配置片段,需要并入已有节点、策略组和规则的完整配置。示例将一般查询发送到 Cloudflare DoH,把 qq.com 及其子域交给国内 DoH;后者是明确的分域策略,不代表“所有查询都走代理”。

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
  proxy-server-nameserver:
    - https://223.5.5.5/dns-query
  nameserver:
    - https://1.1.1.1/dns-query
  nameserver-policy:
    "+.qq.com":
      - https://223.5.5.5/dns-query
  • listen: 127.0.0.1:1053 仅监听本机,不向局域网开放解析服务。系统 DNS 设置通常不能填写 1053 这样的自定义端口,所以还需要后面的 TUN 接管,或由系统支持的本地转发器接入。
  • 198.18.0.1/16 是这里选用的虚拟地址池。应用得到其中的地址是正常现象;若网络里恰好使用该网段,需要先处理冲突。
  • fake-ip-filter 中的域名改用真实地址回答,主要用于兼容局域网发现等场景。它不是分流规则,也不代表这些查询一定直连。
  • proxy-server-nameserver 专门解析代理服务器的域名,避免“连接节点需要 DNS,而 DNS 又等待节点连接”的循环依赖。节点使用 IP 时,这部分查询可能不会发生。
  • default-nameserver 用于解析 DNS 服务器域名等引导需求。若实际触发这里的普通 DNS 查询,本地网络可能观察到引导域名;不要把它误解为所有业务查询都会使用该地址。

用 nameserver-policy 与规则确定解析出口

nameserver-policy 负责“某个域名问哪个解析器”;respect-rules: true 让 DNS 上游连接遵循路由规则。它们解决的问题不同。仅把上游换成国外公共 DNS,并不能保证请求经代理发出。

假设现有配置已经有名为 代理选择 的可用策略组,可以把下面两条加入原有 rules: 列表,放在可能提前匹配它们的规则之前。不要用这两行替换整个规则列表,也不要在策略组不存在时直接保存。

rules:
  - IP-CIDR,1.1.1.1/32,代理选择,no-resolve
  - IP-CIDR,223.5.5.5/32,DIRECT,no-resolve

第一条让示例中 1.1.1.1:443 的 DNS 上游连接使用指定代理组;第二条让国内上游直连。no-resolve 避免为了判断这条 IP 规则额外触发域名解析。规则按顺序匹配,如果上方已有更宽的直连规则,新增规则可能不会得到执行。

全代理解析与国内分流分别验收

  • 国内分流目标:保留示例的 nameserver-policy,接受指定域名向国内解析服务查询。测试页中的随机测试域名通常不匹配该策略,应走一般上游。
  • 更严格的代理解析目标:移除这类国内分域例外,并检查其他 DNS 上游、备用解析、直连解析设置。节点域名引导仍需单独设计,不能靠删除一行就宣称全部封闭。
  • 企业或校园内网目标:内网域名可能必须交给本地 DNS。先询问网络管理员,保留必要的分域解析,不要把内网域名批量发送给公共服务。

验证时在客户端连接列表中搜索 1.1.1.1,查看目标端口是否为 443、命中策略是否为预期代理组。不同客户端展示 DNS 内部连接的能力不同;列表没有显示时,应结合调试日志和网络抓包,而不是把“看不见”当作“没有请求”。

TUN 接管系统 DNS 与 53 端口劫持

系统代理主要影响遵循代理设置的应用,并不自动接管所有系统 DNS 请求。需要覆盖更多应用时,可以在支持 mihomo TUN 的客户端中启用虚拟网卡,并合并以下配置。启用过程可能要求管理员权限或安装虚拟网卡服务。

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
    - tcp://any:53

这里的 any:53 与 tcp://any:53 分别用于接管经过 TUN 的普通 UDP DNS 与 TCP DNS。它们不能把任意应用的 HTTPS 解析自动改写成内核 DNS,也不能接管根本没有经过虚拟网卡的连接。系统、路由表和客户端权限都会影响实际覆盖范围。

本机验证顺序

  1. 确认客户端显示 TUN 已启动,日志没有权限不足、网卡创建失败或路由添加失败。
  2. 运行 nslookup example.com 127.0.0.1 前,先确认本机 53 端口确有监听;本文监听的是 1053,不能把该命令失败直接判为 DNS 故障。
  3. 若系统安装了 dig,运行下方命令直接测试内核的 1053 端口。命中 fake-ip 时,通常会看到 198.18.0.0/16 范围内的回答。
  4. 再运行 nslookup example.com 8.8.8.8 检查普通系统查询是否被接管。应结合日志确认;命令显示的服务器名称本身不是接管成功的证据。
  5. 最后重新运行浏览器扩展检测,并尝试常用应用的实际联网。
dig @127.0.0.1 -p 1053 example.com A
nslookup example.com 8.8.8.8

在 Windows 11 中,可到「设置」→「网络和 Internet」→「代理」检查是否仍留有其他工具写入的手动代理。TUN 与系统代理可以按客户端设计配合使用,但排查阶段应先使用一种明确的接管路径,再逐项恢复其他功能。

IPv6、浏览器 DoH 与缓存的剩余风险

DNS 的 IPv6 开关不等于系统 IPv6 开关

示例中的 dns.ipv6: false 控制内核对 AAAA 查询的处理,并不关闭操作系统 IPv6,也不自动阻止应用通过自己的解析结果建立 IPv6 连接。已有缓存、应用内置 DoH 或静态地址仍可能走另一条路径。应分别验证 IPv4 与 IPv6 的出口;若当前客户端无法完整接管 IPv6,可临时关闭测试网卡的 IPv6 做对照,确认原因后再决定长期方案。

53 端口以外的解析需要单独处理

DoT 常用 TCP 853,DoH 通常使用 HTTPS 443,也可能通过 HTTP/3 使用 UDP 443。dns-hijack 中的 53 端口规则不会把这些加密连接转换成普通 DNS。对于浏览器或应用自带的安全 DNS,要么让它使用系统解析,要么为其解析服务的连接配置符合目标的代理规则。

抓包确认是否仍有未预期的明文查询

有抓包工具时,可在物理网卡上使用显示过滤表达式 udp.port == 53 || tcp.port == 53 观察测试期间的流量,并按查询域名、目标地址和时间与日志对照。TUN 网卡上的 DNS 包可能只是接管前的内部过程;判断是否外溢,应重点看物理网卡是否向未预期的外部 DNS 发送了查询。

抓不到 53 端口数据并不意味着没有解析流量,因为 DoH 和 DoT 已经加密。反过来,节点引导、局域网设备或其他进程的查询也不能直接归咎于正在测试的网页。需要按进程、域名和时间区分来源。

配置验收与故障回退

一次可靠验收至少包含三部分:解析器符合预期,DNS 上游连接命中正确出口,业务应用能正常访问。只看检测页“没有本地地址”,无法覆盖内网域名失效、节点循环解析或其他应用绕行的问题。

  • 配置无法加载:检查 YAML 缩进、重复顶层字段和未知选项;确认运行内核是 mihomo,而不是把客户端外观当作内核版本依据。
  • 所有域名都超时:先检查节点是否能连接、代理服务器域名是否能通过专用上游解析,再检查 1.1.1.1:443 的代理路径。不要在故障时同时更换节点、DNS 和规则。
  • 检测正常但内网打不开:检查内网域名是否需要本地解析,并评估 fake-ip-filter 与分域策略;不要只扩大过滤列表而不检查真实上游。
  • 订阅更新后问题重现:比较更新前后的实际生效配置,确认 DNS、TUN 和规则覆写仍然存在,而不是只检查编辑器中保存的文本。
  • 关闭客户端后无法联网:检查系统 DNS、手动代理与路由是否恢复;先关闭 TUN、退出客户端,再按备份恢复网络设置。

fake-ip 负责域名映射,nameserver-policy 负责解析器选择,路由规则负责上游连接出口,TUN 负责扩大系统接管范围。把这四层分别验证,比反复切换“防泄漏”开关更容易找到原因。需要了解基础分流与订阅操作,可继续阅读Clash 配置教程;字段含义可查阅完整文档。