· 故障排查 · 预计阅读 12 分钟
Clash DNS 泄漏检测与修复:自查步骤与防泄漏配置实操
说明 DNS 泄漏的成因与检测方式,给出 TUN 模式、fake-ip、关闭系统 DNS 回落等防泄漏配置,并附逐步复测清单。
DNS 泄漏的判定边界
DNS 泄漏指域名查询离开了预期的解析路径。例如,要求所有公网域名通过代理侧解析,实际却由本地路由器转发给运营商 DNS。网页出口 IP 已经改变,不代表解析路径也改变:应用可能先调用系统解析器,再把获得的 IP 地址交给代理。
先定义目标,再判断结果。本文区分两个目标:一是让系统查询统一进入 Clash 内核,并使用指定的加密 DNS;二是进一步让上游 DNS 连接也经过代理出口。前者允许加密 DNS 直连,后者不允许。两者不能用同一个“检测通过”结论替代。
- 系统代理:只影响遵循系统代理设置的应用,不能自动接管所有 UDP 查询。
- TUN:通过虚拟网卡接管符合路由条件的 IP 流量,但仍受路由排除、权限和其他 VPN 影响。
- fake-ip:给应用返回映射地址,便于内核保留域名信息;它不是 DNS 加密协议。
- DoH / DoT:加密到解析服务的连接,但连接可以直连,也可以经过代理。
建立基线:同时记录出口与解析器
固定测试条件
- 记录当前客户端、内核版本、操作系统、使用的网络接口,以及是否同时运行其他 VPN。
- 关闭其他代理软件,暂时停用浏览器“安全 DNS”,避免两套解析机制混合。后续再单独恢复并测试。
- 分别记录关闭代理、仅开系统代理、开启 TUN 三种状态下的网页出口 IP 与 DNS 检测结果。
- 每轮先清理系统和浏览器缓存,再发起新测试;测试页面应使用新生成的域名,而不是重复查询同一个缓存域名。
可在浏览器中手动打开 https://www.dnsleaktest.com/ 或 https://browserleaks.com/dns。它们会接触当前访问 IP 和测试查询信息,属于外部测试服务。检测通常反映递归解析器向权威服务器发起查询时的出口,不能单独证明应用到解析器之间用了哪种传输协议。
| 观察结果 | 可能含义 | 下一步 |
|---|---|---|
| 网页出口已变化,DNS 仍是本地运营商 | 系统查询未接管,或配置仍主动使用本地解析器 | 检查 TUN、DNS 劫持与实际生效配置 |
| DNS 显示公共解析服务,与节点国家不同 | 可能是直连 DoH,也可能是服务商的分布式解析出口 | 检查上游连接的出口和策略 |
| 浏览器测试正常,命令行仍走本地 DNS | 浏览器可能使用独立 DoH | 关闭浏览器安全 DNS 后重测系统解析 |
| 仅在开启 IPv6 后出现额外解析器 | IPv6 路由或 DNS 接管可能不完整 | 检查物理接口 IPv6 DNS 与默认路由 |
“出现多个 DNS IP”不是泄漏的充分证据。公共解析服务可能使用多个出口,多个配置上游也可能参与查询。判断重点是这些解析器是否符合预期,以及查询是否绕过了计划中的代理路径。
系统自查:接口 DNS、缓存与 53 端口
Windows:查看每个接口,而不只看 Wi-Fi
在 PowerShell 执行以下命令。第一条查看接口 DNS,第二条清理缓存,第三条发起一次查询。存在以太网、Wi-Fi、虚拟网卡时,要检查所有正在工作的接口。
Get-DnsClientServerAddress
Clear-DnsClientCache
Resolve-DnsName example.com -Type A
Resolve-DnsName 成功只表示得到了答案,不能证明使用了代理。nslookup example.com 显示的默认服务器,也不等于经过透明劫持后的最终上游。需要结合内核日志、路由和物理接口上的流量判断。
macOS 与 Linux:识别本地 DNS stub
# macOS:查看各作用域的 DNS 配置
scutil --dns
# macOS:刷新系统解析缓存
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
# 使用 systemd-resolved 的 Linux
resolvectl status
resolvectl flush-caches
resolvectl query example.com
Linux 的 /etc/resolv.conf 若指向 127.0.0.53,通常表示使用 systemd-resolved 的本地 stub,并不表示上游也在本机。应继续查看 resolvectl status 中每个链路的 DNS Servers 和 DNS Domain。没有 systemd-resolved 的发行版需使用对应网络管理工具。
抓包时选物理接口
Wireshark 可先使用显示过滤器 dns || tcp.port == 853,定位常规 DNS 和常见 DoT 连接。macOS、Linux 也可使用以下命令;将 en0 改为实际联网接口名称。
sudo tcpdump -ni en0 '(udp port 53 or tcp port 53 or tcp port 853)'
物理接口上出现发往路由器或运营商的明文公网域名查询,需要继续追踪来源。DoH 通常使用 443 端口,不能靠上述过滤器排除。TUN 虚拟接口中看到的查询可能只是接管前的流量,不应直接当作已经从物理网络发出的泄漏。
mihomo 配置:TUN、fake-ip 与 DNS 劫持
下面是需要合并到现有配置的片段,不是完整订阅。保留原来的 proxies、proxy-groups 和 rules;已有 tun 或 dns 时修改原段,避免重复 YAML 键。通过客户端的覆写或合并功能持久化,防止下一次订阅更新覆盖修改。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
strict-route: true
dns-hijack:
- any:53
- tcp://any:53
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
nameserver:
- https://1.1.1.1/dns-query
proxy-server-nameserver:
- https://1.1.1.1/dns-query
关键字段的实际作用
auto-route: true:为 TUN 配置自动路由。桌面客户端通常需要管理员权限或服务模式。strict-route: true:收紧路由行为。在 Windows 上有助于限制多宿主 DNS 绕行,但可能影响虚拟机、局域网或其他 VPN。不同系统的行为并不相同。dns-hijack:将进入 TUN、目标为 TCP/UDP 53 端口的 DNS 流量交给内核解析器。不覆盖任意 HTTPS 请求,也不能自动识别所有应用内 DoH。listen: 127.0.0.1:1053:只在本机回环地址监听 1053 端口。系统 DNS 设置通常不能指定非标准端口,不能直接把“127.0.0.1:1053”填进系统 DNS 地址框。ipv6: false:控制内置 DNS 对 AAAA 查询的处理,不是关闭整个系统 IPv6,也不是 IPv6 防泄漏开关。proxy-server-nameserver:用于代理节点域名的解析,防止“连接节点需要先经由该节点解析”的循环依赖。
fake-ip 常见返回地址位于 198.18.0.0/16。看到该地址表示命中了映射机制,不代表远端网站真实地址变成了保留网段。若应用拿到 fake-ip 后绕开内核直连,连接可能失败;这时要修复流量接管,而不是立刻扩大 fake-ip-filter。把域名加入过滤列表只改变返回地址方式,不会自动改变上游 DNS 的出口。
让上游 DNS 也走代理:规则与引导解析
如果目标是让公网域名查询的上游连接也通过节点,需要额外配置 DNS 出站策略。mihomo 可使用 respect-rules: true 让 DNS 上游连接遵循路由规则;使用该项时应配置 proxy-server-nameserver,保证节点域名有独立的引导解析路径。
下面示例假定现有配置确实有名为 PROXY 的策略组,并且该组已选择代理节点,而非 DIRECT。在前一片段的 dns 段加入第一项,把规则插入现有 rules 的较前位置。不要覆盖原有规则列表。
# 合并到已有 dns 段
dns:
respect-rules: true
# 合并到已有 rules 列表,置于可能抢先匹配的规则之前
rules:
- IP-CIDR,1.1.1.1/32,PROXY,no-resolve
这条规则让发往 1.1.1.1 的连接选择 PROXY,也会影响其他发往该 IP 的流量。它只覆盖示例中的 IPv4 上游,换用其他 DNS 地址时应重新规划规则。保存后查看内核连接记录,确认 DNS 上游连接匹配了预期策略,不能只看配置文件中出现了 respect-rules。
节点域名的引导解析仍需单独评估。即便业务域名通过代理解析,启动时解析节点域名也可能使用直连 DNS。若要求启动阶段同样不发生直连解析,应使用服务提供方支持的稳定节点 IP 或受控的引导机制,同时保留所需 TLS 服务器名称配置。不要把临时解析出的 IP 长期写死,否则节点地址变更后可能失联。
关闭系统 DNS 回落与独立解析旁路
不要把 fallback 当成系统回落开关
Clash 的 fallback 是内核中的另一组上游,配合 fallback-filter 决定结果使用方式;它不是操作系统的备用 DNS。删除它不会阻止系统向 DHCP 下发的解析器发包。反过来,随意加入更多 fallback 地址,可能扩大查询接触的解析服务范围。
- 检查所有上游入口:除了
nameserver,还要检查default-nameserver、fallback、nameserver-policy、direct-nameserver及其实际用途。不要只改一个列表。 - 检查 Windows 多接口:在「设置」→「网络和 Internet」中逐个检查当前活动接口的 DNS 分配。受管理设备若有组策略,应由管理员评估“关闭智能多宿主名称解析”等策略,避免擅自修改企业网络设置。
- 检查浏览器:Chrome 的「设置」→「隐私和安全」→「安全」→「使用安全 DNS」可能单独选择解析服务。排查时关闭,恢复后再验证其连接是否经过预期出口。
- 检查 Android:在系统设置中搜索“私人 DNS”。指定的私人 DNS 提供商通常使用加密连接,不能指望 53 端口劫持自动接管;不同厂商的设置入口与 VPN 行为有差异。
- 检查 IPv6 与分流:物理接口的 IPv6 DNS、TUN 排除路由、按应用绕过和其他 VPN 都可能形成旁路。暂时停用某项只能用于定位,长期方案应同时覆盖所需的 IPv4、IPv6 路由。
需要“代理不可用时停止解析”的严格策略时,应在确认解析链路后,再用受控的路由或防火墙规则限制直连出口,并明确放行节点连接和必要的网络服务。仅打开 TUN 不等于建立断网保护。远程机器、企业内网和需要门户认证的网络尤其应先准备恢复路径。
逐步复测与故障定位
- 验证配置加载:重新应用配置,确认没有未知字段、重复键或 YAML 缩进错误,启动日志显示 TUN 成功建立。
- 清理旧答案:刷新系统缓存并完全退出浏览器后重开。每轮使用新的测试域名,避免缓存掩盖实际链路。
- 验证系统解析:先用系统命令查询,再运行浏览器 DNS 检测。两者结果应能用当前配置解释,而不是仅一个页面显示正常。
- 验证上游出口:检查内核连接和日志中的 DNS 目标、命中规则、策略组最终选择。要求经代理时,确认没有选到
DIRECT。 - 检查物理网络:抓取 TCP/UDP 53 和必要的加密 DNS 连接。对未知的 443 连接结合进程信息判断,不把“没看到明文包”当成全部证据。
- 覆盖状态变化:重复测试切换 Wi-Fi、睡眠唤醒、切换节点与订阅更新后的状态。检查覆写是否仍在,以及路由是否重新建立。
- 检查故障行为:在可恢复的本地环境中使所选代理暂时不可用,确认系统是按预期失败,还是悄悄改走其他解析路径。
网页全部无法打开时
先区分 DNS 超时与代理连接失败。若日志显示上游 DoH 连接失败,检查到 1.1.1.1:443 的出站策略和节点可用性;若节点域名本身无法解析,检查引导解析;若能得到 fake-ip 却连接超时,检查 TUN 路由、排除进程以及其他 VPN 冲突。一次只改一处,保留修改前配置,避免多项变化互相遮蔽。