先区分 DNS 解析、流量分流与 DNS 劫持

网页打不开,不一定是节点故障。域名可能没有解析成功,也可能解析到了错误地址,或应用根本没有使用客户端的 DNS。排查前先分清三个环节:谁接收 DNS 请求、哪个上游返回地址、后续连接命中哪条代理规则。

  • DNS 解析:dns 配置决定内核向哪些解析器查询,以及如何处理返回结果。
  • 流量分流:rules 与策略组决定连接使用 DIRECT、代理节点还是其他出站。DNS 返回国外 IP,不等于连接自动走代理。
  • DNS 劫持:本文指 TUN 内核主动接管指定端口的 DNS 流量,交给内置解析器,不是网络运营商篡改应答的同义配置。

修改前导出当前可用配置。若配置来自订阅,优先使用客户端提供的覆写、扩展配置或合并功能;直接修改订阅生成的文件,可能在下次更新时被覆盖。每次只改一个环节,并在重新加载后检查最终生效配置。

nameserver 与 default-nameserver 的分工

nameserver 是常规域名查询使用的上游列表。裸 IP 通常表示普通 DNS,默认端口为 53;https:// 表示 DoH,通常使用 TCP 443;tls:// 表示 DoT,通常使用 TCP 853。协议加密能保护到解析器之间的查询传输,但不能保证解析器始终可达,也不能替代连接分流。

字段主要用途检查重点
enable启用内置 DNS设为 true 后仍需确认请求实际进入内核
listen提供本地 DNS 监听入口地址、端口与系统 DNS 是否对应
default-nameserver为使用域名的 DNS 上游提供引导解析优先使用当前网络可达的 IP 地址
nameserver处理常规域名查询上游可达性、返回结果与延迟
nameserver-policy为指定域名选择解析器规则范围是否过宽、内网域名是否走错上游

上游域名也需要先解析

使用 https://dns.alidns.com/dns-query 时,内核需要先知道 dns.alidns.com 的地址,这就是引导解析的用途。不要把 default-nameserver 当成所有查询失败后的备用列表;它与 fallback 的职责不同。

也不要在这里填入内核自身的监听地址,例如 127.0.0.1:1053。上游查询再次回到同一个解析入口,可能形成循环。指定其他本地解析服务时,同样要检查该服务是否又把请求转回 Clash。

fallback 不是单纯的超时备用

配置 fallback 后,对适用的查询,内核通常会并行发起主解析与备用解析,再依据 fallback-filter 判断采用哪一侧的结果。不能理解为“先等 nameserver 失败 5 秒,再开始请求 fallback”。具体调度还会受到缓存、域名策略和内核实现影响。

fallback-filter 如何筛选结果

  • geoip: true:启用基于 GeoIP 的判断;结合 geoip-code: CN,主解析返回的地址若不属于指定地区,会转而采用 fallback 结果。
  • ipcidr:主解析结果命中列出的地址范围时,改用 fallback。示例中的 240.0.0.0/4 用于识别不应作为普通公网目标的保留地址段。
  • domain:列出的域名直接使用 fallback 一侧的解析策略,适合已经确认主解析不可靠的少量域名。

GeoIP 判断依赖内核可用的地理数据。它判断的是地址归属,不是在验证答案真伪。境外地址可能是正常的 CDN 结果,境内地址也不一定就是正确应答。开启这项筛选前,应确认地理数据库可用,并理解它会让更多查询依赖 fallback 的网络可达性。

可合并的 mihomo DNS 配置

下面只展示顶层 dns 段,不含节点、订阅与代理组。保留现有可用的出站配置,把原来的 DNS 段整体替换或通过覆写合并;同一 YAML 文件不要出现两个顶层 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
  fake-ip-filter:
    - "*.lan"
    - "+.local"

  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29

  nameserver:
    - https://dns.alidns.com/dns-query
    - https://doh.pub/dns-query

  fallback:
    - https://1.1.1.1/dns-query

  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - 240.0.0.0/4

这段配置的适用边界

示例中的公共解析器是具体的配置选择,不代表在所有网络上均可直连。若 1.1.1.1:443 不可达,先不要启用这套 fallback 组合。可暂时移除 fallback 与 fallback-filter,验证主解析正常,再补上已确认可用的备用解析器。

dns.ipv6: false 用于让内置 DNS 不提供正常的 AAAA 解析结果,不等于关闭操作系统 IPv6,也不会阻止所有应用自行建立 IPv6 连接。需要保留双栈访问时,应核实 IPv6 路由、节点与 TUN 支持后再开启。

Fake-IP 模式下,内核可先向应用返回 198.18.0.0/16 范围内的虚拟地址,随后根据映射保留域名信息。看到这类地址通常不是污染;真正的解析与连接流程还取决于出站类型和规则。fake-ip-filter 中的域名不使用虚拟应答,但仍需要合适的真实解析器,过滤本身不会让公共 DNS 突然认识内网主机。

dns-hijack 放在 TUN 段,不放在 dns 段

仅设置 listen: 127.0.0.1:1053,不会让系统自动把所有 DNS 发到这个端口。系统 DNS 设置通常只接受 IP,不支持填写自定义的 1053 端口。测试可以指定端口,日常使用则需要 TUN 接管、系统转发服务或其他明确的 DNS 接入方式。

以下片段是独立的顶层 tun 段,应与 dns 同级。若客户端已经生成 TUN 配置,只合并需要的字段,不要重复创建同名段落。

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
    - tcp://any:53
  • any:53 用于接管进入 TUN 的普通 UDP DNS 请求;第二项补充 TCP 53。
  • auto-route 用于自动配置路由,但实际接管范围仍受系统权限、接口与平台实现限制。
  • Windows 通常需要客户端服务或管理员权限;macOS 需要允许相应网络组件;Android 通常通过系统 VPN 授权建立接管通道。
  • 客户端若有 TUN 开关,应同时核对界面状态与运行日志,避免 YAML 与界面覆写互相覆盖。

解析上游走代理:先处理节点域名的引导

使用 DoH 不意味着请求必然经过代理。在 mihomo 中,respect-rules 可让 DNS 上游连接遵循路由规则;启用后,还应配置 proxy-server-nameserver,用于解析代理节点自身的域名。否则容易出现“需要代理才能连接 DNS,又需要 DNS 才能连接代理”的依赖循环。

dns:
  respect-rules: true
  proxy-server-nameserver:
    - https://dns.alidns.com/dns-query

这只是需要合并到现有 DNS 段中的增量字段,不是替换上一节的完整配置。节点域名解析器也必须在代理尚未建立时可用。开启后检查 rules:如果 DoH 目标仍命中 DIRECT,它仍会直连;如果目标命中代理组,则还需要组内节点可用。

内网域名单独指定解析器

公司域名、NAS 和路由器管理域名通常应交给内网 DNS。可用 nameserver-policy 指向真实的内网解析器,但地址必须来自当前网络,不能照抄其他环境的网关。与此同时,检查 TUN 的 53 端口接管是否会把该上游请求再次送回内核,避免形成回环。

如果只是少量固定设备,也可以使用明确的 hosts 映射。不要为了一个内网域名,把所有公共域名都切到局域网路由器解析;反过来也不要期望公共 DoH 能解析企业专有区域。

按四步验证,区分超时、污染与接管失败

第一步:检查配置是否真正加载

重新加载后查看日志,先处理 YAML 缩进、字段类型、端口占用和未知配置项。YAML 使用空格缩进,不使用 Tab。若启动日志提示监听失败,先确认 1053 端口是否被其他进程占用;若界面显示修改成功,但日志行为没变,检查客户端是否用订阅覆写替换了手工配置。

第二步:直接查询内置 DNS

macOS 或 Linux 安装了 dig 时,可指定监听地址与端口。第一条检查 A 记录,第二条核对 AAAA 行为。Fake-IP 模式下,第一条返回虚拟地址只能证明本地入口有应答,不能单独证明 fallback 已正常工作。

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

Windows 可进入 nslookup 的交互模式指定端口。下面的命令逐行输入;结束时输入 exit。

nslookup
server 127.0.0.1
set port=1053
set type=A
example.com

第三步:验证系统请求是否进入内核

开启 TUN 后,再执行不指定服务器的系统查询,并观察内核日志。若直接查询 1053 正常、系统查询却异常,优先检查路由、TUN 授权与应用自己的 DNS 设置,而不是继续更换 nameserver。浏览器可以打开网页也不是充分证据:它可能在使用独立 DoH 或已有缓存。

第四步:分别观察解析与连接

选择一个此前异常的域名,查看 DNS 错误、命中的规则和最终出站。需要短时调试时可临时提高日志级别,完成后恢复,分享日志前移除订阅地址、令牌和节点凭据。修改上游后清理相关缓存或重启内核,再比较同一个域名的首次请求与重复请求,避免把缓存命中当成解析器速度提升。

现象优先检查下一步动作
本地 1053 查询超时DNS 开关、监听地址、端口冲突先修复入口,再检查外部解析器
内核有查询,但上游超时443 或 853 可达性、引导解析、出站规则一次只保留一个已确认可达的上游
仅部分域名启用 fallback 后变慢GeoIP 筛选与备用上游可达性核实筛选条件,再测试备用解析器
返回 Fake-IP,但连接失败映射、TUN 路由、规则与节点状态沿连接日志排查,不把虚拟地址当错误
公共网站正常,内网域名失败内网 DNS 与域名策略为内网区域指定可达的内部解析器

稳定的调整顺序是:先让单个 nameserver 可用,再确认系统 DNS 接入,随后增加 fallback 筛选,最后处理 DNS 上游的代理路由。每一步都能独立验证,才能判断问题到底发生在解析入口、上游传输,还是后续连接。