Files
vps/docs/lan-dns-architecture.md
T
windyboy d43fc5aa01 docs(dns): correct gfw/.1 facts (W1N-56)
- hosts/gfw.windy.lan.md: 3 NICs (eth2/VLAN10 ubunt_upg live), mosdns is
  now OpenClash's nameserver (not idle), rewrite VLAN10 Wi-Fi section to
  live-verified state
- docs/lan-dns-architecture.md: mosdns on gfw no longer 闲置; note the
  recommended AGH+.36 companion architecture is still pending review
2026-08-12 21:38:57 +08:00

7.6 KiB

内网 DNS 架构调研与优化建议

状态:2026-08-12 调研,Linear W1N-56。基于网络工程师视角,方案待实施评审。 2026-08-12 现场核查修正:gfw 上 mosdns 已并入 OpenClash DNS 链(作为 clash 的 nameserver,DIRECT 规则真实 IP 解析用),不再闲置;推荐方案(AGH 前端 + .36 伴生 mosdns 后端)仍待评审落地。 相关:docs/lan-overview.mdhosts/dns.windy.lan.mdhosts/gfw.windy.lan.md

1. 现状(实测)

角色 部署 职责 是否在活动路径
AdGuard Home 192.168.66.36(PVE VM 120,Docker host 网络) EdgeRouter DHCP 通告给 LAN55/66 客户端的 DNS;广告/过滤、查询统计、Web 面板
mosdns 192.168.66.1(gfw OpenWrt)监听 127.0.0.1:6052 OpenClash custom DNS 的 nameserver(DIRECT 规则真实 IP 分流:国内→AGH .36,国外→国内公网 DNS 223.5.5.5/119.29.29.29) 网关侧(clash 消费,不面向客户端)
OpenClash / clash(meta) 192.168.66.1(gfw) gateway 自身/被劫持流量的 fake-ip + 代理,DNS 走 dnsmasq→clash #7874 仅网关侧

关键事实: LAN 客户端 DNS 直连 66.36,不经过 gfw(EdgeRouter service dns forwarding cache 512,通告 .36)。所以 gfw/clash 的 fake-ip 分流对"直连 AGH 的客户端"不起作用;gfw 上 mosdns 作为 clash 的 nameserver 供 DIRECT 规则连接的真实 IP 解析用(国内→AGH,国外→国内公网 DNS),不面向 LAN 客户端。

现状缺口:

  1. AGH 上游是固定 DoH(alidns/doh.pub,兜底 adg.chans.xyz),没有"国内/国外分流"能力 → 国外域名解析易受 DNS 污染/时延差,也无法为不同 region 选最优上游。
  2. 国内/国外分流逻辑(geo)与代理分流逻辑(clash fake-ip)混在网关上,职责不清。

2. 两个候选方案评估

方案 A:AGH 单独作为统一入口(现状演进)

  • 优点:单解析点、面板/拦截/日志集中、维护简单。
  • 缺点:AGH 对 geo 分流 + 防污染支持弱(官方定位是"过滤/家长控制",见 adguard README "Encrypted DNS upstream... requires additional software")。固定 DoH 上游无法按域名 region 选路。→ 不足以解决防污染/分流问题。

方案 B:mosdns 作为智能上游分流器

mosdns(v5)用 sequence 编排:geosite/geoip 匹配器 → 国内域名转发国内 DoH、国外域名转发加密 DoH(防污染),可加 cachereject(屏蔽)。

  • 优点:真正解决"国内快 / 国外不被污染"的分流;性能高(百万域名表也不卡)。
  • 缺点:纯转发器,无 Web 面板、无每客户端统计、拦截要靠域名表(不如 AGH 体验)。→ 单独当入口会退回原始体验。

结论:两个方案是互补的,不是二选一。 单用 A 无法分流防污染,单用 B 失去 AGH 的管理体验。

3. 推荐:分层架构(AGH 前端 + mosdns 后端)

局域网客户端(DHCP DNS = 192.168.66.36)
        │
        ▼
AdGuard Home (66.36)      ── 前端:广告/过滤、拦截表、每客户端统计、Web 面板
   │  上游 = mosdns
   ▼
mosdns(66.36 伴生容器)      ── 后端:智能分流 + 防污染
   │  - geosite:cn        → 国内 DoH/UDP(aliDNS / 腾讯 DNSPod)
   │  - 其他              → 加密 DoH(Cloudflare/Google/自建 adg.chans.xyz)
   ▼
   上游 DoH

职责分离,每个工具只做自己最擅长的事:

  • AGH = 策略/拦截/可观测(拦截表、每客户端日志、面板)。AGH 原生干不了"按域名选路",所以不做分流。
  • mosdns = 智能转发(geo 分流 + 加密防污染)。不用它当入口,所以保持 AGH 的 UX。
  • OpenClash(gfw)= 代理选路(fake-ip + 规则决定"哪些流量走代理")。与"DNS 解析选上游"是两个独立决策,分开放在不同工具最干净——DNS 解析在 66.36 做,代理路由在网关做,互不耦合。

推荐部署位置:mosdns 与 AGH 同机(66.36),而非 gf(.1)

位置 评价
66.36 伴生容器(推荐) 单点即 AGH 所在;AGH→mosdns 走本机/近端一跳;不受网关重启/OpenClash churn 影响;可纳入现有 ansible compose 管理;不占用 OpenWrt 资源
gf(.1) 虽近网络边缘,但该网关已有 clash fake-ip + 多种劫持规则,再叠 mosdns 会与 clash 的 DNS 处理互相干扰、耦合;且网关重启即断 DNS(影响整个 LAN)。不推荐

注意:若把 mosdns 放 gfw,必须先理清与 OpenClash dnsmasq→clash #7874 + nft fw4 DNS-hijack 的先后/覆盖关系,否则会出现"部分设备解析走了 clash、部分走了 mosdns"的混乱。放 66.36 则完全避开这个冲突。

4. 更优替代方案(也一并考虑)

  1. 分层(推荐,见上):AGH(66.36)→ mosdns(66.36 伴生)→ 上游。体验最好、职责最清。
  2. 纯 mosdns + 前端面板:不用 AGH,用 mosdns + 其他统计面板。→ 会明显损失拦截/统计管理体验,除非你讨厌 AGH 的 Docker 部署。不推荐用于替换。
  3. AGH 只挂一个带分流的上游(第三方 DoH 聚合):例如接一个已做分流的公共 DoH。→ 失去可控性,且不可信。不推荐做主路径。
  4. 全部交给 OpenClash fake-ip,关闭 AGH:把 LAN 客户端 DNS 指到 gfw。→ 让"代理网关"成为全 LAN DNS 单点,网关重启/代理抖动整个内网断网;且 AGH 的拦截/日志也没了。不推荐。

5. mosdns 配置要点(mosdns v5,预留实施)

核心是 sequence + 上游拆分 + 缓存 + 屏蔽:

plugins:
  - tag: main
    type: sequence
    args:
      - exec: cache 1024            # 缓存加速
      # 国内分流:命中 geosite:cn → 国内 DoH
      - matches: [ qname &geosite:cn ]
        exec: forward https://dns.alidns.com/dns-query
      # 广告域名可选屏蔽(或交给 AGH 前置拦截,二选一)
      # - matches: [ qname &./blocklist.txt ]
      #   exec: reject 3
      # 其余(国外)→ 加密 DoH 防污染
      - exec: forward https://1.1.1.1/dns-query
      # 备选国外上游/兜底
      - matches: [ has_resp ]
        exec: accept
      - exec: forward_addr  https://208.67.222.222:443/dns-query
  - type: udp_server
    args: { entry: main, listen: "127.0.0.1:5353" }
  - type: tcp_server
    args: { entry: main, listen: "127.0.0.1:5353" }

要点:

  • 上游可加 upstreamconcurrent > 1addr 做多/故障切换。
  • geosite:cn / geoip:cn 数据插件自动从 repo 更新;国内用 aliDNS/腾讯,国外用 DoH(Cloudflare/Google/自建 adg.chans.xyz)。
  • 屏蔽交由 AGH 前置(推荐),不要 AGH 和 mosdns 都自己维护一套拦截表(重复)。

6. 迁移 / 实施顺序(待评审)

  1. 在 66.36 起 mosdns 伴生容器(/opt/mosdns + compose,固定 digest,纳入 ansible)。
  2. AGH「上游 DNS 服务器」改为指向 mosdns(http://127.0.0.1:5353/dns-query127.0.0.1:5353)。AGH 的 bootstrap 仍用公网 IP(避免 AGH → mosdns → AGH 死循环)。
  3. 验证:国内域名(如 taobao.com)、国外域名(如 google.com)、被拦截域名、每客户端日志。
  4. 确认后,disable/移除 gfw 上闲置的 mosdns(6052)以免混淆。
  5. 回归:EdgeRouter 通告不变(仍 .36),因此 LAN 客户端无感;重启 AGH/mosdns 单点验证。

7. 风险与备注

  • mosdns 仅监听 127.0.0.1(不对外),由 AGH 消费;避免 LAN 直连 mosdns 造成两套入口。
  • AGH 上游指向本机 mosdns 时,务必配 bootstrap 公网 IP,否则自举死循环。
  • 本方案不改 EdgeRouter DHCP/通告,不改 gfw OpenClash 代理规则,只动 66.36 上的 DNS 链路,风险可控。
  • 与 W1N-40「审查并修正 AdGuard Home」联动:该 issue 侧重 AGH 本身,本 issue 侧重整体 DNS 分层。