Clash DNS 配置字段详解:nameserver、fallback 与 DNS 劫持

逐项讲解 dns 段的 nameserver、fallback、fallback-filter 与 dns-hijack,说明 fake-ip 与 redir-host 的差异以及常见解析异常的排查顺序。

先区分 DNS 解析、请求接管与代理分流

Clash DNS 配置需要回答三个不同的问题:域名由谁解析、应用的 DNS 请求如何进入内核、连接最终走哪个出口。nameserver 选择上游解析器,tun.dns-hijack 接管符合条件的 DNS 流量,rules 则决定业务连接的出口。这三层有关联,但不能互相替代。

本文以当前使用 mihomo 内核的客户端为主要对象。旧版 Clash、不同分支及客户端的配置生成器可能支持不同字段;界面里的“DNS 覆写”也可能替换订阅中的整个 dns 段。排错时应查看客户端最终生成、实际交给内核的配置,而不只检查订阅编辑框。

  • 内核 DNS:只有启用 dns.enable,内核才按该段配置提供解析服务。
  • 系统 DNS:操作系统当前使用的解析入口;仅打开 HTTP 系统代理,不代表所有 DNS 请求都会进入内核。
  • 代理规则:域名或 IP 命中哪条规则,决定直连或代理;使用某个地区的 DNS 不等于选择该地区的代理节点。
  • 应用自带 DNS:浏览器的安全 DNS、应用内置 DoH 可能绕过系统的传统 DNS 设置。

“DNS 劫持”在这里指把指定 DNS 流量重定向到本机内核,不等于运营商篡改解析结果。是否接管成功,需要用查询与连接日志验证。

nameserver 与 default-nameserver:业务解析和引导解析

先建立一个可单独测试的 DNS 监听入口

下面是用于合并到现有 mihomo 配置的 DNS 片段,不是包含节点和规则的完整配置。监听地址限定为本机,端口使用 1053,避免直接与系统的 53 端口竞争。此时系统不会自动使用它,后文会先通过显式查询测试。

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://dns.alidns.com/dns-query
    - https://doh.pub/dns-query

nameserver 是常规域名查询使用的上游列表,可以包含传统 DNS 地址、DoH(DNS over HTTPS)或内核支持的其他协议。列出两个地址并不是声明严格的“主用、备用”顺序,不应依赖列表顺序实现故障切换策略。

default-nameserver 主要用于解析 DNS 上游自身的域名。例如访问 https://dns.alidns.com/dns-query 之前,需要先知道 dns.alidns.com 的 IP。显式提供 IP 形式的引导解析器,可以避免“解析 DNS 服务器域名又依赖该服务器”的循环依赖。

节点域名解析与 DNS 出站要分开检查

mihomo 的 proxy-server-nameserver 可专门用于解析代理节点的服务器域名。若节点地址本身无法解析,业务域名的 DNS 再正常也无法建立代理连接。开启 respect-rules 让 DNS 上游连接遵循路由规则时,更应正确设置节点域名解析路径,避免解析器依赖代理、代理又依赖同一解析器。

不要为了排错一次加入所有高级字段。先确认所选 DoH 在当前网络能够完成连接,再增加按规则出站等设置。DoH 通常使用 TCP 443,但“使用 HTTPS”不自动意味着“经过代理”,实际路径仍由内核配置与路由条件决定。

fallback 与 fallback-filter:结果筛选,不是超时备用

fallback 容易被误解成只有主 DNS 超时才使用的备份列表。实际配置中,内核会结合 nameserver 与 fallback 查询,并依据 fallback-filter 判断采用哪一类结果。它既不是代理节点备用组,也不负责保证某个域名走代理。

以下片段演示显式筛选条件,需与前面的 dns 段合并,不能在文件里再写第二个同名顶层段。示例关闭 GeoIP 筛选,使用文档示例网段和一个指定域名说明判断方式;这些网段并非完整的异常地址清单。

  fallback:
    - https://cloudflare-dns.com/dns-query
  fallback-filter:
    geoip: false
    ipcidr:
      - 0.0.0.0/8
      - 192.0.2.0/24
      - 198.51.100.0/24
      - 203.0.113.0/24
    domain:
      - '+.github.com'
字段判断对象配置含义
geoip常规解析结果的 IP 归属启用 GeoIP 条件,依赖可用的地理数据。
geoip-codeGeoIP 国家或地区代码启用 GeoIP 时,常规结果不符合指定地区条件会触发使用 fallback 结果。
ipcidr常规解析返回的 IP命中列出的网段时,采用 fallback 结果。
domain查询的域名匹配的域名直接使用 fallback 侧的解析结果。

若使用 geoip: true 与 geoip-code: CN,含义并不是“国内网站直连”,而是基于解析 IP 的地理归属判断结果是否可采用。CDN 地址、地理数据更新和网络出口都可能影响判断;代理出口仍由规则决定。需要指定某个域名使用固定解析器时,nameserver-policy 通常比堆叠地理筛选条件更直观。

fallback 上游也必须能够连接。如果所选上游在当前网络超时,强制某些域名使用 fallback 只会扩大故障范围。应先单独验证上游可达性,再启用筛选。

fake-ip 与 redir-host:返回虚拟地址还是真实地址

fake-ip 依靠地址映射保留域名信息

fake-ip 模式下,内核可向应用返回 198.18.0.0/16 范围内的虚拟 IPv4 地址,并保存域名与虚拟地址的映射。应用随后访问该地址时,流量需要再次被送入同一个内核,内核才能恢复域名、匹配规则并建立真实连接。此网段位于保留的网络测试地址空间,不是网站的公网地址。

因此,查询得到 198.18.x.x 不代表 DNS 污染。真正需要排查的是:DNS 已交给内核,连接却从普通路由发出;或者切换客户端、清空映射后,系统仍缓存旧的虚拟地址。只接管 DNS、不接管后续连接,是 fake-ip 无法访问的常见原因。

redir-host 返回真实 IP,但仍需正确接管连接

redir-host 模式通常返回上游解析得到的真实 IP,不要求应用连接虚拟地址。它对部分依赖真实地址的程序更容易兼容,但域名与连接的关联会受缓存、共享 IP 等因素影响。该模式名称也不代表必须启用 Linux 的 REDIRECT 防火墙规则,更不等于自动完成透明代理。

  • 使用 TUN 且希望保留域名规则匹配信息时,可先测试 fake-ip。
  • 局域网发现、特定设备或游戏出现兼容问题时,优先定位具体域名,再评估 fake-ip-filter。
  • 默认 blacklist 过滤模式下,加入 fake-ip-filter 的域名不再获得虚拟地址;其他过滤模式的含义需按当前 mihomo 配置确认。
  • 更换增强模式后,重新启动受影响的应用并清理 DNS 缓存,避免混用两种模式的旧结果。

dns.ipv6: false 控制内核 DNS 对 AAAA 查询的处理,不等于关闭系统所有 IPv6 连接。浏览器若使用自己的 DoH,或者应用缓存了 IPv6 地址,仍可能通过其他路径建立连接。

tun.dns-hijack:接管 53 端口的边界

dns-hijack 写在 tun 段内,不在 dns 段内。以下是 mihomo 的常见 TUN 片段;它会修改路由,远程服务器操作前应准备控制台或其他恢复方式。桌面客户端通常通过服务模式或授权助手管理 TUN 权限,不要在不清楚权限来源时重复启动第二个内核。

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

any:53 用于匹配进入 TUN 的 UDP 53 DNS 流量,tcp://any:53 补充 TCP 53。它们不是扫描或拦截整张网络的开关:流量首先需要经过 TUN,才能由内核处理。路由排除项、操作系统行为以及本地回环解析服务,都可能让部分请求不进入这条路径。

  • DoH:通常走 HTTPS 的 443 端口,不会因为配置 any:53 就变成内核 DNS 查询。
  • DoT:通常走 TLS 的 853 端口,也不属于传统 53 端口接管范围。
  • Ubuntu 本地解析:127.0.0.53 常是 systemd-resolved 的本地存根地址,看到它不能直接判定 DNS 未接管。
  • 局域网设备:本机启用 TUN 不会自动接管路由器或其他设备的 DNS,网关部署需要额外的转发与防火墙设计。

不要为解决本机 DNS 问题直接把监听地址改成 0.0.0.0:53 并开放公网访问。确实需要服务局域网时,应限定允许访问的网段,并分别检查 UDP、TCP 防火墙规则。

Ubuntu 排查顺序:监听、查询、接管、出口

第一步:确认实际配置与监听进程

纯命令行部署可对实际配置目录执行测试。以下路径按 /etc/mihomo/config.yaml 举例;使用桌面客户端时,应检查客户端提供的运行配置,不要以这份路径替代它的真实目录。

mihomo -t -d /etc/mihomo -f /etc/mihomo/config.yaml
sudo ss -lntup 'sport = :1053'
resolvectl status

配置测试主要发现语法与配置问题,不代表上游网络一定可达。ss 用于核对 1053 是否被正确进程监听;如果出现地址占用,先定位另一个 DNS 服务,不要盲目停止系统解析服务。

第二步:绕过系统解析器,直接测试内核

Ubuntu 的 dig 来自 dnsutils 软件包。先使用显式地址查询,区分“内核 DNS 本身失败”和“系统请求没有进入内核”。

dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com A +tcp
dig @127.0.0.1 -p 1053 example.com AAAA

观察响应状态、回答记录和是否超时。fake-ip 模式下,A 查询可能只证明内核能够分配虚拟地址,并不充分证明真实上游解析成功;还需结合一次实际访问与日志确认。设置 dns.ipv6: false 时,AAAA 没有地址回答也未必是故障。

第三步:验证系统入口与业务连接

resolvectl query example.com
curl -I --connect-timeout 10 https://example.com
curl -I --connect-timeout 10 --proxy http://127.0.0.1:7890 https://example.com

最后一条假设现有配置的 mixed-port 是 7890,并通过显式 HTTP 代理建立 HTTPS 隧道;它不能单独证明系统 DNS 已被接管。第二条也可能受环境变量代理影响,比较结果前应检查终端环境。若显式代理能访问、普通应用却失败,重点检查系统代理覆盖范围、TUN 路由与应用自带 DNS。

第四步:清理缓存并逐项回退

sudo resolvectl flush-caches

清理 systemd-resolved 缓存后,退出并重新打开浏览器;浏览器自身的 DNS 缓存和现有连接池未必随系统一起清空。短时提高内核日志级别,观察 DNS 超时、节点域名解析失败及规则命中,然后恢复原来的日志级别。日志可能包含访问域名,分享前应删去订阅地址、认证信息与个人访问记录。

常见现象与最小修改原则

现象优先检查下一步操作
显式查询 1053 超时监听地址、端口占用、内核是否启动先查 ss 和运行日志,再检查上游连接。
得到 198.18 开头地址但打不开fake-ip 后续流量与映射核对 TUN 路由,清缓存后重新连接。
只有指定域名失败fallback-filter、nameserver-policy、域名规则临时撤销单个域名的特殊策略,比较日志。
节点列表存在但全部连接失败节点域名解析与节点自身可达性检查 proxy-server-nameserver 及节点连接错误。
只有浏览器表现不同安全 DNS、扩展代理与浏览器缓存临时统一解析路径,重启浏览器后复测。
订阅更新后故障复现客户端覆写与生成配置将修改放入客户端支持的持久覆写机制。

可靠的调整顺序是:先让一个 DNS 监听入口可查询,再验证一个上游可达,然后确认系统请求和业务连接进入内核,最后增加 fallback、按域名解析策略及 TUN 接管规则。每轮只修改一个变量,并记录修改前后的查询结果。这样才能判断问题来自解析、路由还是节点,而不是把所有异常都归为“DNS 污染”。

需要了解端口、代理组与规则的整体关系,可继续阅读入门指南;核对配置字段时,可参照协议参考。本文中的 DNS 和 TUN 片段都应合并到已有配置,保留原有节点与规则,不要整份覆盖订阅。

下载Clash