配置实践 · Clash 技术博客

OpenClash 与 AdGuard Home DNS 冲突怎么办?

冲突通常不是两个服务不能共存,而是它们都想监听 53 端口,或者互相把对方设成上游。先画出实际查询顺序,再从两种可用接法中选一种。

  • OpenClash
  • AdGuard Home
  • DNS
  • OpenWrt
本文目录

OpenClash 和 AdGuard Home 一起开就断网,先画清 DNS 路径

OpenClash 和 AdGuard Home 都想处理 DNS,但职责不同:AdGuard Home 负责过滤、重写和查询记录,OpenClash 的内核 DNS 负责让域名解析与代理规则配合。两者可以共存,前提是一条查询只沿一个方向前进。

出现“国内能开、部分域名超时”“AdGuard 查询日志为空”“OpenClash 开启后全屋 SERVFAIL”时,不要急着更换上游。

写下终端从 DHCP 得到的 DNS、路由器 53 端口由谁接收、AdGuard 的上游是谁、OpenClash 内核监听在哪个端口。只要查询最终又回到前一个服务,就会形成循环。

先识别几个入口

入口常见作用不要混淆
路由器 TCP/UDP 53LAN 设备默认访问的 DNS 入口同一个地址端口不能同时被 dnsmasq 与 AdGuard 独占
AdGuard Home DNS 监听接收查询、过滤并转给上游3000 等 Web 管理端口不是 DNS 端口
OpenClash 内核 DNS按模式解析并配合规则常见内部监听为 127.0.0.1:7874,但应以运行页和日志为准
浏览器 DoH / Android 私人 DNS终端直接向外部解析它可能绕过路由器上的两套服务

确认实际监听和转发,不要只看 LuCI 开关

通过 SSH 登录 OpenWrt,查看 53、OpenClash 内部 DNS 端口以及你为 AdGuard 设置的端口分别由哪个进程监听。若 53 已被占用,另一个服务可能根本没有启动;若两个页面都显示运行,也可能靠防火墙重定向绕过了你以为的顺序。

只读检查
ss -lntup | grep -E '(:53|:7874|:5335)'
uci show dhcp | grep -E 'server|port|noresolv'
logread | grep -Ei 'dnsmasq|AdGuardHome|OpenClash.*DNS' | tail -n 80

先记下这些结果

  • TCP 53 与 UDP 53 的监听进程
  • AdGuard Home 的实际 DNS 监听地址和端口
  • OpenClash 状态页显示的 DNS 监听端口
  • dnsmasq 当前 server 指向
  • 防火墙里是否存在 DNS redirect / hijack
  • 修改前可恢复的 OpenWrt 与 AdGuard 配置备份

两种接法都能工作,但只能选一个方向

OpenClash 官方 DNS 说明给出的原则很直接:它应成为 dnsmasq 的唯一上游;如果另一个插件也会劫持 53 或转发 DNS,就停掉其中一套劫持,并明确两个服务的先后顺序。

实际使用中,可以把 AdGuard 放在 OpenClash 前面,也可以让 OpenClash 接收查询后再调用 AdGuard。

根据你想保留的能力选路径

路径查询方向优点取舍
AdGuard 在前LAN DNS 入口 → AdGuard → OpenClash DNS → 外部上游AdGuard 更容易记录每台终端并先做过滤必须关闭 OpenClash 对 LAN 53 的抢先劫持
OpenClash 在前LAN / dnsmasq → OpenClash → AdGuard → 外部上游域名先进入 OpenClash,Fake-IP 与规则路径更集中AdGuard 通常只看到来自路由器/内核的查询,客户端统计会变粗

要保留 AdGuard 客户端统计,就让它先收到查询

这条路径可以写成“终端的 53 入口 → AdGuard Home → 127.0.0.1:7874 → OpenClash 外部上游”。在 OpenClash 的 DNS 设置里停用本地 DNS 劫持,避免防火墙把 LAN 的 53 查询提前截走。

在 AdGuard Home 的“设置 → DNS 设置 → 上游 DNS 服务器”里删除会产生分叉的其他上游,只保留当前 OpenClash 内核 DNS 监听地址。

127.0.0.1:7874 是 OpenClash 文档中的常见示例,不是可以盲抄的固定值。应从 OpenClash 状态、配置和 ss 输出确认实际端口。

AdGuard 使用 53、dnsmasq 移到其他端口,还是由 dnsmasq 转发到 AdGuard,取决于原来的 OpenWrt 集成。无论采用哪种方式,LAN 的 53 最终只能进入 AdGuard 一次。

改完后按查询顺序逐项确认

  1. AdGuard 能启动

    日志没有 bind: address already in use,TCP 与 UDP 监听都符合预期。

  2. OpenClash DNS 在内部端口监听

    本机能看到 7874 或实际端口由 Mihomo/OpenClash 占用。

  3. 关闭 OpenClash LAN DNS 劫持

    重启后检查防火墙和启动日志,确认没有规则抢在 AdGuard 前面。

  4. AdGuard 只转给 OpenClash

    查询日志出现客户端地址,新的允许域名能得到响应。

更重视 Fake-IP 与规则一致性,就让 OpenClash 先接收查询

这条路径保留 OpenClash 的本地 DNS 劫持,并关闭 AdGuard Home 自己对 LAN 53 的重定向或劫持。让 AdGuard 只在一个不冲突的本机端口监听,例如 127.0.0.1:5335,再在 OpenClash“覆写设置 → DNS 设置”的自定义上游中填写这个实际地址。

AdGuard 的上游必须继续指向真正的外部 DNS,而不是 127.0.0.1:7874、路由器 LAN:53 或任何会重新进入 OpenClash 的地址。

此时 OpenClash 接收终端查询,再向 AdGuard 请求真实上游结果。AdGuard 日志里的客户端往往只剩路由器本机,这是这种接法的正常代价。

方向示意,不是可直接粘贴的端口模板
LAN client
  -> dnsmasq / OpenClash DNS hijack
  -> OpenClash DNS
  -> AdGuard Home 127.0.0.1:5335
  -> external upstream DNS

三个常见问题看起来都像“DNS 很慢”,处理方法却不同

日志反复出现同一域名,随后 SERVFAIL

常见原因:OpenClash 与 AdGuard 互相作为上游,形成查询循环

处理方法:沿上游地址逐个画箭头,删掉返回前一层的那一项。

AdGuard 查询日志为空,但网页能打开

常见原因:OpenClash 或防火墙在 AdGuard 前劫持了 53

处理方法:若选择 AdGuard 在前,关闭冲突劫持并检查 NAT/nftables 规则顺序。

AdGuard 启动失败,提示 address already in use

常见原因:dnsmasq 或另一实例已占用相同地址与端口

处理方法:确定唯一的 53 监听者,再为内部转发选择不同本机端口。

电脑正常,手机偶尔绕过过滤

常见原因:IPv6 DNS、Android 私人 DNS 或浏览器 DoH 直接向外查询

处理方法:测试时统一关闭独立加密 DNS,并检查 DHCPv6/RDNSS 下发。

OpenClash 停止后全屋 DNS 失效

常见原因:唯一上游已指向停止监听的内核端口

处理方法:准备一键回退到可达的外部 DNS,或让停用脚本同步恢复 dnsmasq 上游。

缓存会遮住问题。调整服务顺序后重启相关服务,让测试终端清理 DNS 缓存或重新连接 Wi-Fi,再查询一个从未访问过的域名。反复打开已缓存的网站,只能证明旧答案还在。

最后同时验证过滤、分流和停机回退

从一台测试电脑完成验收

  1. 确认终端 DNS

    nslookup 输出的 Server 应是计划中的路由器或 AdGuard 地址,不是意外的公网 DNS。

  2. 查询允许域名

    使用一个未缓存域名,响应时间正常且 AdGuard/OpenClash 日志按选定顺序出现。

  3. 查询过滤规则

    在 AdGuard 临时添加一条测试规则,确认返回符合过滤设置,再删除该规则。

  4. 观察代理规则

    访问需要代理的域名,OpenClash 连接记录应保留域名并命中预期策略。

  5. 分别重启服务

    按实际启动顺序重启 AdGuard、dnsmasq 与 OpenClash,监听和上游方向不应变化。

  6. 执行回退

    停用 OpenClash 时,按预案把 DNS 恢复到可达上游,LAN 设备仍能解析普通域名。

从 LAN 终端做最基本的路径检查
nslookup example.com 192.168.1.1
nslookup www.iana.org 192.168.1.1

验收通过的结果应很具体:53 只有一个预期入口,AdGuard 能按选定拓扑看到查询,OpenClash 能拿到域名并执行规则,新域名没有循环超时,关闭任一组件时也有明确回退。做到这些,比把两个页面都调成“运行中”更重要。

参考资料