这篇按 2026-05-24 比对到的 OpenWrt、dnsmasq、Mihomo 和 sing-box 官方文档写,默认你用的是 OpenWrt 22.03 之后的 firewall4/nftables 思路。老 fw3 设备也能照着排查,但命令输出会不一样。

先不要同时改 DNS hijack、防火墙、客户端 TUN 和订阅配置。这个故障最容易误判,因为网页打不开、DNS 检测异常、Mihomo 日志没请求、sing-box FakeIP 不命中,都可能来自同一个入口冲突。

##把哪条链路定下来?

排查阶段只保留一条链路:

终端 -> OpenWrt LAN IP:53(dnsmasq) -> 127.0.0.1:7874(Mihomo 或 sing-box DNS) -> 上游 resolver

如果是旁路由,把「OpenWrt LAN IP」换成旁路由地址。关键不是谁当主角,而是同一台终端只能拿到一个预期 DNS 入口。

用终端先看真实下发值:

nslookup openwrt.lan
nslookup example.com

Windows 看:

ipconfig /all

macOS 看:

scutil --dns | grep nameserver

Linux 看:

resolvectl dns

你希望看到的是 OpenWrt 或旁路由 LAN 地址。这里如果已经出现主路由、公共 DNS、IPv6 地址或桌面客户端的虚拟 DNS,后面的 hijack 规则再漂亮也不算入口干净。

IPv6 为什么会偏离 IPv4 hijack?

OpenWrt 默认用 dnsmasq 处理 DNS/DHCP,用 odhcpd 处理 DHCPv6 和 RA。IPv4 DHCP 下发的 DNS 只解决一半问题,IPv6 侧还可能通过 RA/RDNSS 告诉客户端另一组 DNS。

典型现场是:你在 firewall 里接管了 TCP/UDP 53,IPv4 查询都进了 dnsmasq,但手机或 Windows 仍用 RDNSS 里的 IPv6 DNS 查 AAAA 记录。结果看起来像 DNS hijack 偶发失效。

排查时可以临时关闭 LAN 侧 IPv6 DNS 广播:

uci set dhcp.lan.dns_service="0"
uci set dhcp.lan.ra_dns="0"
uci commit dhcp
service odhcpd restart

这不是让所有人长期关闭 IPv6。它的作用是把变量减到一个:先证明问题是不是 RA/RDNSS 造成的。确认后,如果你需要 IPv6,就把 IPv6 DNS 也转回同一条 dnsmasq -> Mihomo/sing-box 链路。

旁路由和桌面客户端哪里会互相抢?

旁路由的常见错法是主路由仍在发 DHCP,桌面客户端又开了 TUN 或系统代理。结果同一台电脑同时收到三类指令:网关走主路由,DNS 走旁路由,应用连接又被本机客户端改路由。

用这张表定位冲突位置:

现象更可能的冲突点第一项检查
手机正常,电脑不正常电脑本机客户端接管 DNS 或 DoH关闭桌面客户端 TUN/系统 DNS
IPv4 域名正常,IPv6 域名异常RA/RDNSS 下发了另一组 DNSuci show dhcp.lan
Mihomo 没有 DNS 日志请求没有到 Mihomo DNS listen终端实际 DNS 与 dnsmasq 上游
sing-box FakeIP 不命中DNS 没走 sing-box 或反向映射缺失dns.serversdns.rulesfakeip
开启 hijack 后整网变慢dnsmasq 到本机 DNS 被再次接管排除本机 DNS 服务地址
只重启后复发DHCP 租约或客户端缓存没刷新释放租约并断开 Wi-Fi 重连

如果表里同时命中两项,处理更靠近终端的那一项。终端拿错 DNS 时,路由器内核再正确也接不到请求。

最小修复步骤

按下面顺序改,每一步只改一个变量:

  1. 选一台测试设备,关闭桌面 Mihomo、sing-box、Clash 系客户端的 TUN、系统 DNS 和 DoH。
  2. 在主路由 DHCP 页面确认网关和 DNS 下发值。旁路由方案里,DNS 只指向旁路由;主路由方案里,DNS 只指向主路由。
  3. 在 OpenWrt 上确认 dnsmasq 监听 53,Mihomo 或 sing-box 不直接抢 53。
  4. 让 dnsmasq 上游只指向一个本机端口,例如 127.0.0.1#7874
  5. 临时关闭 RA/RDNSS DNS 下发,排除 IPv6 分支。
  6. 释放测试设备 DHCP 租约,断开 Wi-Fi 后重新连接。
  7. nslookup、内核日志和浏览器各测一次同一域名。

Mihomo 监听示例:

dns:
  enable: true
  listen: 127.0.0.1:7874
  enhanced-mode: fake-ip
  ipv6: false
  fake-ip-filter:
    - "*.lan"
    - "openwrt.lan"

sing-box 则不要只看 inbound。DNS 自己有 serversrulesfinalstrategyfakeip 字段;需要按域名路由时,再看 reverse_mapping 是否符合你的路由写法。

{
  "dns": {
    "servers": [],
    "rules": [],
    "final": "local",
    "strategy": "prefer_ipv4",
    "fakeip": {}
  }
}

如果你的服务来源同时给 Mihomo、sing-box、V2Ray 多种导出,排障时可以用一份兼容 Clash / Singbox / V2Ray 的订阅做格式基线:路由器只导入路由器那份,桌面端只导入桌面端那份,不要把 JSON、YAML 和 URI 链接混着粘。

Mihomo 和 sing-box 的 DNS 要放在哪?

在 OpenWrt 上,推荐让 dnsmasq 继续站在最前面。原因很简单:它知道 DHCP 租约、本地域名、openwrt.lan、NAS、打印机和内网静态记录。

Mihomo 或 sing-box 更适合做后面的规则解析。它们负责 Fake-IP、规则匹配、上游 resolver、节点域名解析。让它们直接面对全 LAN 也能跑,但本地域名和 IPv6 例外会更难收拾。

推荐分工:

组件保留职责不建议承担
dnsmasq53 入口、本地域名、DHCP 主机名、缓存复杂代理规则
odhcpdDHCPv6、RA、RDNSS 下发控制代替客户端 DNS 排错
Mihomo DNSFake-IP、nameserver-policy、节点域名解析直接抢 OpenWrt 53 端口
sing-box DNSDNS rules、final、strategy、fakeip和 Mihomo 同时接管同一入口
桌面客户端单机调试、日志对照排查阶段继续改系统 DNS

如果你坚持让客户端直接问 Mihomo 或 sing-box DNS,至少要给 .lan、路由器管理域、NAS 和打印机写例外。否则内网服务会被送进外部 resolver 或 Fake-IP 池,表现为「网页能开,NAS 名字打不开」。

什么时候保留 DNS hijack?

DNS hijack 适合处理硬编码 53 端口的设备,例如电视盒子、IoT 设备、游戏主机或不方便改 DNS 的手机。它不是第一步,而是入口稳定后的补丁。

OpenWrt 官方示例用 firewall redirect 接管 LAN 到 53 的 TCP/UDP 请求,并建议用 nft list rulesetuci show firewall 查运行态与持久配置。你要额外注意本机 DNS 服务的排除规则,避免 dnsmasq 发给 Mihomo/sing-box 的请求又被抓回 53。

排除逻辑可以按源地址或源 MAC 做。比如本机 DNS 服务在 192.168.2.2,就不要把它发出的 53 请求再次重定向。IPv6 也要单独看地址,不能只写 IPv4 规则。

怎么验收没有冲突?

验收不要换域名。用同一组样本看三层日志:

样本终端结果OpenWrt 侧内核侧
openwrt.lan返回路由器 LAN 地址dnsmasq 本地命中Mihomo/sing-box 不处理
nas.lan返回 NAS 内网地址DHCP/hosts 命中不进入 Fake-IP
普通公网域名DNS 服务器是 OpenWrt/旁路由dnsmasq 转发到本机端口Mihomo/sing-box 有 DNS 日志
AAAA 查询结果符合 IPv6 策略RA/RDNSS 不再给第二入口ipv6strategy 行为可解释
硬编码 DNS 设备仍被带回路由器 53firewall redirect 命中没有循环日志

OpenWrt 上可以临时打开 dnsmasq 查询日志:

uci set dhcp.@dnsmasq[0].logqueries="1"
uci commit dhcp
service dnsmasq restart
logread -f | grep dnsmasq

看完记得关掉。DNS 查询日志量很大,长期打开会让路由器闪存和日志阅读都变得难受。

本文不覆盖什么

不处理 DoH/DoT 全量阻断,不讨论特定插件页面的按钮名。OpenClash、PassWall、homeproxy、ShellCrash 都包装了 Mihomo 或 sing-box,但底层冲突仍然回到 53 端口、DHCP、RA/RDNSS、Fake-IP 和桌面客户端接管。

不要用测速失败代替 DNS 链路排查。测速受策略组、目标站、UDP、TLS 和节点状态多重影响;DNS 排查只看请求怎么进、被谁解析、返回值对不对。

相关阅读