先分清 DNS 解析、规则分流与流量接管
Clash 能连上节点,却有部分网站打不开,原因未必是节点失效。一次访问至少涉及三件事:把域名解析成地址、根据规则选择出口、把应用连接送进代理内核。DNS 配置主要解决第一件事;TUN 和系统代理决定第三件事。只修改 DNS 地址,不能自动接管所有应用。
本文以 mihomo,也就是常说的 Clash Meta 内核为主要配置对象。原版 Clash、不同分支及客户端界面支持的字段并不完全相同。先在客户端的内核信息或启动日志里确认实际内核,再使用对应配置;应用版本与内核版本不是同一个编号。
- 应用发起解析:可能使用操作系统 DNS,也可能使用浏览器自己的安全 DNS。
- 内核处理查询:收到查询后,按 DNS 配置返回真实地址或 fake-ip。
- 连接匹配规则:域名、目标 IP、进程等信息参与匹配,随后选择直连或代理策略。
nameserver、default-nameserver 与 fallback 分别负责什么
nameserver 是常规域名解析所用的上游集合;default-nameserver 主要负责解析 DNS 上游自身的域名。例如,上游写成 https://dns.alidns.com/dns-query,内核需要先知道 dns.alidns.com 的地址,才能建立加密连接。这一步常称为引导解析。
| 字段 | 用途 | 容易误解的地方 |
|---|---|---|
enable | 启用内核 DNS 功能。 | 启用后仍需让系统查询进入内核。 |
listen | 指定 DNS 监听地址及端口。 | 不是 HTTP 或 SOCKS 代理端口。 |
default-nameserver | 为带域名的 DNS 上游提供引导解析。 | 不是所有普通查询的默认首选列表。 |
nameserver | 处理常规 DNS 查询。 | 不应理解成严格逐项主备切换。 |
fallback | 提供另一组解析结果,配合过滤条件选择答案。 | 不是只有主 DNS 超时才使用的备用列表。 |
fallback-filter | 决定哪些查询或主解析结果需要采用 fallback。 | 不是广告过滤器,也不决定网页流量走哪个节点。 |
常见上游格式包括普通 DNS 的 223.5.5.5、DoT 的 tls://1.1.1.1:853,以及 DoH 的 https://dns.google/dns-query。普通 DNS 通常使用 53 端口,DoT 通常使用 853,DoH 通常使用 HTTPS 的 443。端口能访问并不等于服务能完成查询,仍要观察解析结果和日志。
加密 DNS 保护的是客户端到解析服务这一段传输。它不自动保证上游可信、不自动隐藏所有域名信息,也不代表 DNS 请求已经经过代理节点。先确认上游在当前网络下可达,再讨论是否需要按规则代理其连接。
fake-ip 与 redir-host:按兼容性选择
fake-ip 会向应用返回一个由内核管理的虚拟地址,并保存域名与该地址的映射。应用随后连接这个地址时,内核就能还原目标域名,再执行规则匹配。常用地址池是 198.18.0.1/16,属于基准测试用途地址范围,不是网站的真实服务器地址。
redir-host 则向应用返回解析出的真实 IP,并尽可能利用已记录的解析关系参与域名判断。如果应用自行使用加密 DNS,或连接信息里只有 IP,内核未必能取得可靠的原始域名。域名嗅探可补充部分信息,但不能保证覆盖所有协议。
- 优先尝试 fake-ip:适合希望稳定保留域名分流信息、并已正确接管流量的桌面环境。
- 为个别域名加例外:局域网设备发现、依赖真实 IP 的程序或连通性检测出现异常时,先调整
fake-ip-filter。 - 再考虑 redir-host:如果业务程序持续不兼容虚拟地址,可切换模式做对照测试,不必同时改动所有 DNS 上游。
排错时还要注意:对 fake-ip 执行 ping,不能据此判断远端网站是否正常。虚拟地址的意义是映射与接管;真正有用的检查是应用能否建立连接,以及客户端连接详情中识别出的域名和最终策略是否正确。
一份便于理解的 DNS 配置片段
下面的片段启用本地 DNS,并展示 fake-ip 与两组解析上游的搭配。它监听 127.0.0.1:1053,只允许本机访问,避免把设备意外暴露为局域网 DNS 服务。这里的 1053 不是系统默认 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:
- localhost
- "*.lan"
- "*.local"
- "+.msftconnecttest.com"
- "+.msftncsi.com"
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://dns.alidns.com/dns-query
fallback:
- https://dns.google/dns-query
- https://cloudflare-dns.com/dns-query
fallback-filter:
geoip: true
geoip-code: CN
ipcidr:
- 0.0.0.0/32
- 240.0.0.0/4
应用配置前检查三项
- 合并到已有 dns 段:不要在同一份 YAML 里重复写两个顶层
dns:。同名键可能被覆盖,也可能直接导致解析错误。缩进使用空格,不用 Tab。 - 确认上游可以连通:如果当前网络无法连接 Google 或 Cloudflare 的 DoH,不能指望这份 fallback 自动修复网络。先换成实际可达、可信的上游,或进一步配置 DNS 上游的代理路径。
- 理解 IPv6 的范围:这里的
dns.ipv6: false用于停止该 DNS 服务返回 AAAA 记录,并不等于关闭操作系统 IPv6,也不能单独阻止应用的 IPv6 流量绕行。
对 *.local 加过滤也不意味着接管了设备发现。常见 mDNS 使用 UDP 5353 和组播地址,与普通单播 DNS 不同。如果打印机、投屏设备或 NAS 发现失败,还要检查 TUN 的局域网路由、系统防火墙和组播处理。
fallback-filter 怎么判断解析结果
在上述配置中,geoip: true 与 geoip-code: CN 表示:当常规解析结果不符合指定地区的判断时,采用 fallback 结果。ipcidr 则补充需要排除的地址范围,例如 0.0.0.0/32。这种判断依赖 IP 地理数据库,不能保证每个 CDN 地址都被准确归类。
需要强调:非 CN 地址并不等于被污染。合法网站本来就可能部署在其他地区。这里是根据网络环境设计的结果选择策略,不是对答案真伪的绝对证明。若网站返回合法地址却连接缓慢,应继续检查出口规则与 CDN 调度,而不是不断扩大过滤网段。
指定域名使用另一组上游
mihomo 还支持 nameserver-policy。当目标是让某一类域名固定使用指定 DNS 时,直接写策略通常比不断扩充 fallback 条件更清楚。例如下面的局部片段,让 example.com 及其子域名使用指定 DoH,其余查询仍使用常规配置。
dns:
nameserver-policy:
"+.example.com":
- https://dns.alidns.com/dns-query
这段只演示策略语法,需合并到原有 dns 段。若使用公司内网域名,应填写公司提供的 DNS 地址,并确认 VPN 或专线下的可达性。把公共 DNS 换来换去,无法解析只存在于企业内网的私有记录。
DNS 上游走代理时避免循环依赖
mihomo 的 respect-rules 可以让 DNS 上游连接遵循路由规则,但启用时需要同时妥善配置 proxy-server-nameserver,为代理节点服务器的域名提供可用解析。否则可能出现“DNS 要经过节点,节点域名又等 DNS 解析”的依赖循环。基础配置正常之前,不建议把这些开关一并打开。
TUN DNS 劫持:让系统查询真正进入内核
只开启系统代理时,通常是支持代理设置的应用把 HTTP 或 SOCKS 连接交给内核,操作系统 DNS 仍可能向路由器或运营商服务器查询。TUN 则通过虚拟网卡接管更多 IP 流量,并可将捕获到的 DNS 请求交给内核 DNS 服务。
在确认客户端服务模式或所需权限已准备好后,可参考以下 mihomo 局部配置。桌面客户端经常自行管理 TUN 字段;如果界面已经生成相同设置,应检查最终生效配置,避免界面开关与手写覆写互相覆盖。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
any:53用于匹配相应的 UDP DNS 请求,tcp://any:53补充 TCP DNS。两者针对的是进入接管路径的流量。auto-route负责自动设置相关路由;它可能影响其他 VPN、虚拟机网络或企业安全软件,应逐项测试。auto-detect-interface尝试识别出口网卡;多网卡、热点共享和复杂 VPN 环境仍可能需要显式指定出口。
如果不用 TUN,而要让系统直接使用本机 DNS,一般需要有服务监听本机 53 端口,并将系统 DNS 指向该地址。这里涉及端口占用、管理员权限与系统解析服务冲突,不能把示例中的 1053 原样填入只支持 IP 地址的系统 DNS 输入框。
按顺序检查:解析失败、fake-ip 不生效与 DNS 泄漏
第一步:直接查询内核的监听端口
在装有 dig 的 Linux 或 macOS 环境中,先执行以下命令。Windows 可以在具备该工具的终端环境中做同样测试;不要把普通 nslookup 的默认 53 端口测试误认为已验证 1053。
dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com A +tcp
在 fake-ip 模式下,未命中过滤列表的域名通常应得到 198.18.0.0/16 范围内的映射地址。若请求超时,先看 DNS 功能是否启用、端口是否被占用、配置是否加载成功。注意,拿到 fake-ip 只能证明本地映射查询正常,不能单独证明远端真实解析与网站访问都正常。
第二步:验证系统与应用是否走同一条路径
- 重新加载配置,确认日志没有未知字段、YAML 缩进或端口绑定错误。
- 开启 TUN 后,用浏览器访问测试域名,并在客户端连接详情查看域名、命中规则和出口策略。
- 临时关闭浏览器安全 DNS,对比现象。若关闭后恢复,应检查浏览器 DoH 路径,而非只改
fallback。 - 逐一排除其他 VPN、手动 DNS 和应用自带代理,避免同时存在多条接管链路。
第三步:清理缓存,再复测
Windows 可运行 ipconfig /flushdns;使用 systemd-resolved 的 Linux 可运行 sudo resolvectl flush-caches。macOS 常用命令如下。系统缓存、浏览器缓存与内核 fake-ip 映射不是同一层,必要时还需重启测试应用或使用客户端提供的 DNS 缓存清理功能。
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
从 fake-ip 切换到 redir-host 后,尤其要避免应用继续持有旧的虚拟地址。若清空了内核映射,但浏览器还缓存原 fake-ip,连接可能暂时失败;重启浏览器再试,比继续改规则更有针对性。
第四步:把“泄漏测试”当线索,而不是结论
DNS 测试页面看到的通常是递归解析服务的出口,不一定是本机或代理节点 IP。解析服务地区与节点地区不同,也不能直接证明请求绕过了代理。先明确目标是阻止运营商明文查询、统一应用解析路径,还是让特定上游经过代理,再结合日志、连接记录和必要的抓包判断。
配置收束:先跑通,再逐项增加策略
稳定的起点是一组可达的 DNS 上游、明确的解析模式,以及确实生效的流量接管。先用本地端口查询验证 DNS 服务,再用应用访问验证规则和出口。只有观察到具体异常时,再增加 fake-ip-filter、nameserver-policy 或 DNS 上游代理策略。
- 局域网域名失败:先检查内网 DNS、mDNS 与路由,不急着替换公共上游。
- 只有某个应用失败:先检查应用自带 DoH、代理设置与 fake-ip 兼容性。
- 所有域名都超时:先看服务监听、上游可达性及是否存在解析循环。
- 解析正常但网站打不开:转查节点连接、规则命中和目标端口,别把所有问题都归给 DNS。
每次只修改一项,保存修改前后的配置与错误日志。这样既能找出真正有效的调整,也能在订阅更新、内核升级或网络切换后快速恢复。