Clash DNS 配置逐项拆解:nameserver、fallback 分组与 fake-ip 劫持
逐字段解释 dns 段的 nameserver、fallback、fallback-filter 与 enhanced-mode,说明 fake-ip 与 redir-host 的取舍,以及系统 DNS 劫持的生效条件,并附可直接改用的配置片段。
先给结论:DNS 上游、返回地址与流量接管分开检查
Clash DNS 配置最容易混在一起的,其实是三件事:向谁解析域名、向应用返回什么地址,以及应用的 DNS 请求有没有进入内核。nameserver 和 fallback 处理第一件事;enhanced-mode 处理第二件事;系统 DNS、监听端口和 TUN 的 dns-hijack 决定第三件事。只把模式改成 fake-ip,不会自动接管整台设备的 DNS。
下文主配置以 mihomo 为目标。Clash 是客户端生态中的常见称呼,图形界面相似,不代表底层字段完全一致。原版 Clash、不同历史分支和当前 mihomo 对 TUN、DNS 扩展字段的支持存在差别。先从客户端显示的内核信息或启动日志确认实现;命令行部署可运行 mihomo -v 查看当前环境,不要照着界面版本推测内核能力。
- 订阅导入成功:只说明配置可以被读取,不等于 DNS 已被系统使用。
- 节点延迟测试成功:只覆盖测试目标,不等于所有域名都能正确解析。
- 返回 198.18 网段地址:在 fake-ip 模式下可能是预期结果,不应直接判定为解析污染。
nameserver 与 default-nameserver:业务解析和引导解析
dns.nameserver 是常规域名解析使用的上游列表。上游可以是普通 DNS 的 IP 地址,也可以是内核支持的 DoH、DoT 地址。列表不是“第一台永远优先,第二台仅在断网时启用”的固定队列;内核会按自身的查询与响应选择逻辑处理多个上游,不宜依赖书写顺序实现严格主备。
为什么写了 DoH,还会用到普通 DNS?
例如 https://dns.alidns.com/dns-query 是一个 DoH 服务地址,但建立 HTTPS 连接前,需要先知道 dns.alidns.com 的 IP。default-nameserver 提供这类 DNS 服务域名的引导解析。下面使用 223.5.5.5 和 119.29.29.29,目的是让依赖关系明确,不代表这两个地址适合所有网络。
| 字段 | 负责的事情 | 常见误解 |
|---|---|---|
enable | 启用内核 DNS 功能 | 启用后系统就一定会使用它 |
listen | 指定 DNS 服务监听地址和端口 | 1053 与系统默认的 53 会自动互通 |
default-nameserver | 为 DNS 上游域名提供引导解析 | 它就是所有业务域名的首选解析器 |
nameserver | 提供常规上游解析 | 列表顺序等于严格的故障切换顺序 |
enhanced-mode | 选择 fake-ip 或 redir-host 等处理方式 | 模式本身负责接管系统流量 |
DoH 的加密只覆盖客户端到该解析服务的这一段,并不自动意味着请求经过代理节点。上游的可达性、DNS 连接所走的出站路径,以及业务连接的规则匹配,需要分别确认。mihomo 还提供 proxy-server-nameserver 等扩展字段,可单独处理代理服务器域名解析;不要在不了解依赖关系时,让解析节点域名的请求又依赖这个节点本身。
fallback 与 fallback-filter:候选结果筛选,不是规则策略组
fallback 虽然常被称作“备用 DNS”,但它不只是等 nameserver 完全超时才启动的后备名单。配置 fallback 后,内核可同时向常规组和 fallback 组发起查询,再根据过滤条件选择结果。这里的“分组”是 DNS 上游集合,与 proxy-groups 中的节点选择、自动测速策略组不是同一层。
geoip、ipcidr、domain 分别判断什么?
geoip: true配合geoip-code: CN:对常规组返回的地址做地区判断;不符合指定地区的结果会触发使用 fallback 结果的逻辑。它依赖内核可用的地理数据。ipcidr:把某些返回地址段视为需要过滤的结果,例如240.0.0.0/4。它检查解析结果,不是给业务连接添加一条代理规则。domain:让匹配的域名使用 fallback 结果。它是域名层面的指定条件,不必等常规组返回异常 IP 才生效。
这些条件不是必须全部满足才触发的串联检查。不要把“域名在名单中,同时地址不在 CN,同时还命中保留网段”理解成唯一触发方式。还有一个容易忽略的限制:被错误返回的地址如果恰好也被地理数据判为 CN,单靠 geoip 不一定能识别异常。fallback 是结果选择机制,不是解析正确性的保证。
需要明确指定某类域名使用哪台 DNS 时,mihomo 的 nameserver-policy 通常更直观。它决定解析上游,rules 决定业务连接出站,两者不要互相代替。即使某个域名由境外 DNS 解析,业务连接也不会因此自动命中代理策略。
fake-ip 与 redir-host:返回虚拟地址还是真实地址
fake-ip:用映射保留域名上下文
enhanced-mode: fake-ip 会为符合条件的查询返回虚拟地址,并在内核中保留域名与虚拟地址的映射。应用随后访问这个地址时,连接必须进入同一个内核,内核才能根据映射还原目标。示例使用 198.18.0.1/16,它属于用于基准测试的保留地址空间,不是远端网站的真实服务器地址。
这种方式有利于在连接阶段保留域名信息,并可避免部分连接在建立前等待真实目标地址解析。但它不是“所有域名都不再需要真实 DNS”:直连目标、IP 类规则判断以及具体内核的处理路径,仍可能触发真实解析。把 fake-ip 当成完全不需要上游 DNS,会留下难排查的连接失败。
redir-host:返回真实地址,重点检查域名关联
redir-host 返回上游提供的真实 IP,内核再利用 DNS 缓存等信息关联域名。它对需要看到真实地址的程序更容易兼容,但不能消除 DNS 结果异常,也不能保证每条连接都完整保留域名上下文。应用自行解析、缓存过期或连接绕过内核,都可能改变规则匹配结果。
- 桌面 TUN 日常使用:可以先验证 fake-ip,让 DNS 与后续连接由同一内核处理。
- 局域网设备、打印机或内部服务异常:先检查局域网 DNS 和过滤名单,再考虑切换模式。
- 特定程序依赖真实 IP:可把对应域名加入
fake-ip-filter,不必立即给所有应用改成 redir-host。
fake-ip-filter 的含义是“这些域名不返回 fake-ip”,不是“这些域名不走代理”。下面片段排除 localhost、*.lan 和 *.local。但排除本身不会让公共 DNS 学会解析路由器私有域名;内部域名还需要可用的局域网解析器。.local 常涉及 mDNS,也不能只靠修改普通 DNS 上游解决。
可改用的 DNS 片段:先在 127.0.0.1:1053 验证
下面只替换完整配置中的 dns: 段,不包含节点、策略组或业务规则。保留现有订阅的其他部分;如果配置已有 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"
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://dns.alidns.com/dns-query
fallback:
- https://cloudflare-dns.com/dns-query
fallback-filter:
geoip: true
geoip-code: CN
ipcidr:
- 240.0.0.0/4
- 0.0.0.0/8
这里选择回环监听,是为了先限定在本机测试;没有直接监听 0.0.0.0:53,也没有向局域网开放解析服务。ipv6: false 用于收窄本次 DNS 验证范围,不等于关闭操作系统 IPv6,更不能据此认定所有 IPv6 连接都被阻止。
先检查语法,再检查监听
命令行环境可在配置所在目录执行以下检查。图形客户端由自身管理配置路径时,不要直接拿命令替换它的启动参数;使用客户端提供的配置检查功能,并在日志中确认 DNS 服务成功启动。
mihomo -t -f config.yaml
dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com A +tcp
example.com 是用于验证查询链路的公开示例域名。支持 fake-ip 的查询返回 198.18.x.x 可以是正常现象;UDP 和 TCP 都超时,则先查监听、端口冲突和内核日志。Windows 没有安装 dig 时,可以在交互式 nslookup 中指定服务器和端口:
nslookup
server 127.0.0.1
set port=1053
set type=A
example.com
exit
TUN DNS 劫持的生效条件:53 端口请求必须经过内核
操作系统常规 DNS 通常使用 UDP 或 TCP 的 53 端口。前面的 1053 是测试监听端口,系统并不会自动把请求从 53 转发过去。多数系统的 DNS 设置界面也不能填写自定义端口。要接管普通 DNS,可以使用客户端的 TUN DNS 接管能力,或配置明确的本地转发;不要仅把系统 DNS 写成 127.0.0.1 就认为它会访问 1053。
在支持以下字段的 mihomo 环境中,可将这一段合并进现有 tun: 配置。启用前先按客户端或系统要求授予创建虚拟网卡、修改路由的权限。如果客户端已经管理 TUN,优先使用其配置入口,避免界面设置与手写片段互相覆盖。
tun:
enable: true
stack: system
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
any:53 用于匹配 UDP DNS,tcp://any:53 覆盖 TCP DNS。这里的劫持是把进入 TUN 处理路径的 DNS 请求交给内核 DNS 模块,并不是把所有请求简单改写到本地 1053 端口。能否进入这条路径,还取决于系统路由、其他 VPN、接口选择和平台限制。
以下流量不会因为写了 dns-hijack 就全部被接管
- 浏览器自己的 DoH:通常表现为 HTTPS 流量,不能用端口 53 的规则直接识别为普通 DNS。
- 系统或应用的 DoT:常使用 853 端口,不在这两条 53 端口匹配范围内。
- 没有进入 TUN 的流量:例如被其他 VPN 接管、走独立路由或受平台实现限制的请求。
- 已缓存的结果:应用可能不发起新查询,而是继续使用旧地址或已建立的连接。
系统代理与 TUN 也不要混为一谈。浏览器通过 HTTP 代理提交域名时,可能由代理侧处理目标解析;不遵循系统代理的应用则可能直接使用系统 DNS。排查时可暂时关闭浏览器自带的安全 DNS,建立可控基线,确认后再恢复需要的设置。
故障对照:按现象定位,不同时修改多个变量
| 现象 | 优先检查 | 下一步操作 |
|---|---|---|
| 查询本地 1053 超时 | DNS 是否启用、配置是否生效、端口是否占用 | 看启动日志,分别测试 UDP 与 TCP |
| 本地查询正常,应用仍解析失败 | 应用是否使用了内核 DNS | 检查系统 DNS、TUN 路由及应用自带 DoH |
| 返回 198.18 地址但连接超时 | 后续连接是否回到同一内核 | 检查虚拟网段路由、TUN 状态与连接记录 |
| 少数域名明显等待更久 | fallback 是否可达、是否被过滤条件选中 | 查看解析错误,单独验证备用上游 |
| 内网域名失效 | 公共上游是否无法解析私有名称 | 配置局域网上游或域名定向解析策略 |
| 修改后表现没有变化 | 订阅覆写、系统缓存和应用长连接 | 核对生效配置,清缓存后重新建立连接 |
缓存清理要跟着模式切换走
从 fake-ip 切换到 redir-host,或关闭 TUN 后,应用仍可能缓存虚拟地址。Windows 可运行 ipconfig /flushdns;使用 systemd-resolved 的 Linux 可运行 resolvectl flush-caches。这两个命令分别有适用条件,不是跨平台通用命令。浏览器自己的 DNS 缓存和连接池还需要单独处理,必要时完全退出应用后重新打开。
验证时选一个固定域名,先发起查询,再访问对应页面,同时查看连接面板中的目标域名、命中规则和出站策略。不要只通过公共 IP 查询页判断 DNS:出口地址能说明那次网页连接的出口,却不能完整说明解析请求走了哪台服务器。
需要回看订阅导入与基础连接步骤,可打开入门指南的订阅说明;需要对照 DNS 与规则的关系,可查看使用手册的 DNS 章节。核心原则不变:先确认请求有没有进入内核,再讨论上游和过滤条件,最后调整兼容性名单。