DNS 泄漏的判断边界
Clash 已经显示代理连接,DNS 检测页却出现本地运营商,这是常见的排查起点。但“检测到多个 DNS 地址”并不自动等于泄漏。首先要确定目标:是只让需要代理的域名通过代理解析,还是要求除节点引导解析之外,所有公网域名查询都经指定出口发送?两种目标对应的合格结果并不相同。
本文把 DNS 泄漏定义为:域名查询没有按照预定策略发送,而是绕到系统、本地网络或其他未授权解析器。检测页展示的通常是接收测试域名查询的递归解析器,不是电脑配置的 DNS 地址,也不是代理节点本身。因此,DNS 所在地区与网页出口地区不同,只能作为线索,不能单独下结论。
| 观察结果 | 可能原因 | 下一步 |
|---|---|---|
| 出现本地运营商解析器 | 系统查询未接管,或规则明确允许直连解析 | 对照策略与 53 端口流量 |
| 出现公共 DNS 服务商 | 内核或浏览器使用了该服务 | 核对是否为预期上游及出口 |
| 解析器与节点不在同一国家 | 公共 DNS 的任播、递归出口或地理数据库差异 | 结合连接日志判断路由 |
| 每次出现多个地址 | 同一服务使用多个递归出口,也可能存在多条解析路径 | 比较运营主体,而非只数 IP |
先做一组可复现的 DNS 泄漏测试
记录环境,再改变一个变量
- 记录客户端名称、内核名称和版本,以及当前使用系统代理还是 TUN。本文示例面向 mihomo,不适合直接套用到已经停止更新的旧版 Clash 内核。
- 退出其他 VPN、加速器与代理工具。先保留一个客户端运行,避免多个虚拟网卡和 DNS 设置互相覆盖。
- 在浏览器中手动打开
dnsleaktest.com,执行 Standard test,再执行 Extended test。记录解析器 IP、运营主体、检测时间与网页出口地址,不要只截取国家一栏。 - 关闭代理做一次基线测试,然后开启目标配置重测。基线测试会按本地网络方式联网,不适合在有严格网络隔离要求的环境中执行。
- 修改配置后重新加载内核,清理系统缓存并完全退出浏览器,再进行第二轮测试。保持同一节点、同一网络和同一检测页面,方便比较。
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,也不能接管根本没有经过虚拟网卡的连接。系统、路由表和客户端权限都会影响实际覆盖范围。
本机验证顺序
- 确认客户端显示 TUN 已启动,日志没有权限不足、网卡创建失败或路由添加失败。
- 运行
nslookup example.com 127.0.0.1前,先确认本机 53 端口确有监听;本文监听的是 1053,不能把该命令失败直接判为 DNS 故障。 - 若系统安装了
dig,运行下方命令直接测试内核的 1053 端口。命中 fake-ip 时,通常会看到198.18.0.0/16范围内的回答。 - 再运行
nslookup example.com 8.8.8.8检查普通系统查询是否被接管。应结合日志确认;命令显示的服务器名称本身不是接管成功的证据。 - 最后重新运行浏览器扩展检测,并尝试常用应用的实际联网。
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 配置教程;字段含义可查阅完整文档。