2917 字
15 分钟
IPv6 与 DNS 的分手协议

IPv6 与 DNS 的分手协议#

1 序言#

宽带没有公网 IPv4,是很多折腾党绕不开的痛。好在 IPv6 通常不缺:运营商默认下发 /64 前缀,内网设备通过 SLAAC 自动生成公网 IPv6 地址,配合 Lucky DDNS 自动更新 AAAA 记录,照样可以在外网直接访问家里的服务。

但把 IPv6 用起来之后,我踩了一个隐蔽的坑:系统 DNS 查询开始绕过自建的 AdGuard Home(AGH),直接打到公共 IPv6 DNS 上。表现为 nslookup 的解析服务器是 public1.alidns.com (2400:3200::1),而不是 AGH 的内网地址。这样一来,AGH 的过滤规则、条件上游分流全部失效,游戏协调服务器、CDN 解析结果也不可控。

本文记录完整排障过程与最终方案:IPv6 只负责分配地址(用于远程访问与 DDNS),完全不推送任何 IPv6 DNS,让内网所有域名解析强制走 IPv4 侧的 AdGuard Home。

文中 IP 均为示意(内网使用 RFC 1918 示例网段,公网 IPv6 前缀以 2408:xxxx:xxxx:xxxx::/64 代替),请替换为自己的实际地址。

2 问题复现与根因分析#

2.1 现象#

某天 Steam / Dota2 游戏协调服务器异常,重启路由器后恢复,但随后排查发现 DNS 链路并不干净:

C:\Windows\system32>nslookup steamchina.com
服务器: public1.alidns.com
Address: 2400:3200::1

解析服务器是 IPv6 地址的阿里公共 DNS(2400:3200::1),不是自建 AGH。也就是说,电脑发起的 DNS 查询根本没有进内网 DNS 服务器,直接被 IPv6 DNS 旁路了。

2.2 根因:RA 报文携带的 RDNSS#

IPv6 地址与 IPv6 DNS 的下发是两个独立通道,都藏在路由器的 RA(Router Advertisement,路由器通告)报文里:

RA 报文组成作用我们要不要
前缀信息(Prefix)终端 SLAAC 自动生成公网 IPv6 地址要
RDNSS(RFC 6106)附带 IPv6 DNS 服务器地址,终端自动采用不要
O 标志位(Other)为 1 时终端会再跑 DHCPv6 索取附加参数不要

此外 DHCPv6 还有两种模式:

  • 无状态(SLAAC):只广播前缀,终端自己生成 IPv6 地址,不额外下发参数。
  • 无状态 + 有状态:除了 RA 前缀,还会启用 DHCPv6,可能额外下发 DNS 服务器。

如果主路由开了「有状态」或者 RA 里带了 RDNSS,Windows 网卡就会自动拿到一整套 IPv6 DNS(例如阿里 2400:3200::1、240c::6666)。

2.3 为什么 Windows 会绕过首选 DNS#

Windows DNS 客户端会并行查询网卡上的所有 DNS 服务器。只要网卡存在 IPv6 DNS,即使 IPv4 首选 DNS 填的是 AGH,也会出现查询直接打到 IPv6 DNS 的情况,表现为 nslookup 的服务器变成了公共 IPv6 DNS。这也是「明明把 DHCP 首选 DNS 改成了 AGH,却总有个别解析不走 AGH」的经典来源。

2.4 一个关键认知:关 DNS 不等于关 IPv6#

很多人以为「关掉 IPv6 DNS 就是禁用 IPv6」,这是误解:

  • 远程访问:直接用 IPv6 地址访问设备,不需要域名 AAAA 解析,与 DNS 完全无关。
  • Lucky DDNS:Lucky 读取本机网卡上的公网 IPv6 地址,通过 HTTPS 调用域名服务商 API 提交 AAAA 记录更新,不依赖内网 DNS 查询,因此关掉 IPv6 DNS 对 DDNS 毫无影响。

3 方案对比#

方案做法缺点
禁用 IPv6网卡/路由器直接关 IPv6失去公网 IPv6,远程访问与 DDNS 全部废掉,不可接受
网卡手动指定 IPv6 DNS每台设备手动填治标不治本,设备一多就失控,新设备默认仍会拿到 RDNSS
路由器只分配地址、不推送 DNSRA 只带前缀,RDNSS 关闭,DHCPv6 纯无状态配置一次,全网生效,一劳永逸

最终采用第三种:IPv6 只分配地址,DNS 统一收归 IPv4 侧的 AGH。

4 架构设计#

┌─────────────────────────────┐
│ 运营商宽带(拨号) │
└──────────────┬──────────────┘
│
┌──────────▼──────────┐
│ 爱快主路由 192.168.3.1 │
│ RA 下发 IPv6 前缀 │
│ RDNSS 关闭 / 无状态 DHCPv6 │
└──────────┬──────────┘
┌──────────────────┼───────────────────┐
│ │ │
┌─────────▼─────────┐ ┌────▼─────┐ ┌───────▼───────┐
│ ImmortalWrt 旁路由 │ │ AdGuard │ │ 内网终端设备 │
│ 192.168.3.2 │ │ Home │ │ (Windows/手机) │
│ 获取公网 IPv6 │ │ 192.168.3.3│ │ SLAAC 生成 IPv6 │
│ 不广播 RA/DNS │ │ IPv4 DNS │ │ IPv6 DNS 为空 │
│ Lucky DDNS 更新AAAA│ │ 解析核心 │ │ DNS 走 IPv4 AGH │
└───────────────────┘ └───────────┘ └─────────────────┘

各设备职责:

设备职责关键配置
爱快主路由内网唯一 RA 通告源、IPv4 网关DHCPv6 无状态,RA 不携带 RDNSS
ImmortalWrt 旁路由获取公网 IPv6,运行 Lucky DDNS仅作 IPv6 客户端,lan 口 DHCP/RA 全关
AdGuard Home内网 DNS 解析核心(IPv4)条件上游分流,Steam/完美等域名走阿里 DoH
Windows 终端业务客户端IPv4 首选 DNS 指向 AGH,IPv6 DNS 清空

⚠️ 旁路由场景铁律:旁路由禁止开启 RA server。一旦开启,内网会出现两套 RA 报文(主路由 + 旁路由),IPv6 DNS 与地址分配互相打架,前功尽弃。

5 实施步骤#

5.1 爱快主路由:LAN 口配置#

进入「网络设置 → IPv6 设置 → 选中 LAN 口」,按如下修改:

  • DHCPv6:开启,模式选 无状态(不要选「无状态 + 有状态」,有状态会通过 DHCPv6 下发 DNS)。
  • IPv6 DNS:取消勾选(核心开关,取消后 RA 不再携带 RDNSS)。
  • RA 通告绑定:不勾选,保证内网所有设备正常获取 IPv6。
  • 保存并应用。

避坑:爱快部分固件即使你不手动填 IPv6 DNS,RA 的 RDNSS 也会自动填入公共 IPv6 DNS(如 2400:3200::1、240c::6666),所以必须找到「IPv6 DNS」开关并显式关闭,而不是只看有没有手动填。

5.2 ImmortalWrt 旁路由:只拿 IPv6,不外发#

5.2.1 lan 接口关闭 DHCP / RA 服务#

SSH 登录旁路由,执行:

Terminal window
uci set dhcp.lan.dhcpv4='disabled'
uci set dhcp.lan.dhcpv6='disabled'
uci set dhcp.lan.ra='disabled'
uci set dhcp.lan.ra_dns='0'
uci set dhcp.lan.dns_service='0'
uci set dhcp.lan.ignore='1'
uci commit dhcp
/etc/init.d/dnsmasq restart

配置含义:

配置项值作用
dhcpv4 / dhcpv6disabled不提供 DHCP 地址分发
radisabled不发送 RA 通告,不与主路由抢 RA
ra_dns0兜底:即使发 RA 也不带 RDNSS
dns_service0兜底:DHCPv6 不下发 DNS
ignore1lan 接口整体忽略 DHCP 服务

避坑:ImmortalWrt 部分固件没有独立的 odhcpd 服务,执行 service odhcpd restart 会报 Command failed: Not found。这是正常现象,配置已经写入生效,改用 /etc/init.d/dnsmasq restart 或 /etc/init.d/network restart 重载即可。

5.2.2 lan6 接口:仅作为 IPv6 客户端#

在 Web 界面进入「接口 → lan6 → 高级设置」:

  • 协议保持 DHCPv6 客户端,用于获取运营商公网 IPv6(Lucky DDNS 依赖它)。
  • 取消勾选「自动获取 DNS 服务器」:防止 OpenWrt 本机采用上游推送的 IPv6 DNS。
  • 取消勾选「委派 IPv6 前缀」:旁路由不需要再向下游分发前缀,内网前缀分配全权交给爱快。
  • 保存并应用。

5.2.3 本机 DNS 强制走 AGH#

编辑 /etc/config/dhcp 中的 dnsmasq 段,确认或配置:

option noresolv '1'
list server '127.0.0.1#7874'

noresolv '1' 表示 dnsmasq 不读取系统 resolv.conf,不会自动加载 lan6 接口拿到的上游 IPv6 DNS;list server 指向本地端口转发,上游最终落到 AGH。这样旁路由本机的域名解析也统一走 IPv4 侧的 AGH。

5.3 Windows 客户端:清空 IPv6 DNS#

  • IPv4 属性:首选 DNS 填 AGH 内网地址,备用 DNS 留空。
  • IPv6 属性:DNS 服务器全部清空,不要手动填任何 IPv6 DNS。

这样即使 RA 意外携带 RDNSS,本机也不会采用。属于最后一道防线,正常情况下应保持路由器层面已关闭 RDNSS。

5.4(可选强化)AdGuard Home 禁用 AAAA 记录#

上面三步解决了「系统不拿 IPv6 DNS」,但 AGH 本身仍然会正常返回域名的 AAAA 记录(IPv6 解析结果)。如果你想让 DNS 层也彻底和 IPv6 分手——即域名解析只走 IPv4,AGH 不再返回任何 AAAA 记录——可以在 AGH 里加一条全局规则:

进入「过滤器 → 自定义过滤规则」,添加:

||*^$dnstype=AAAA

作用与辨析:

  • dnstype=AAAA 修饰符表示只拦截 AAAA 类型(IPv6 地址记录)的查询,A 记录解析完全不受影响,正常返回。
  • 配合「系统无 IPv6 DNS」+「IPv4 首选 DNS = AGH」,整条链路变为:所有域名查询走 IPv4 的 AGH → AGH 只返回 A 记录 → IPv6 仅保留地址与直连访问,域名解析彻底与 IPv6 脱钩。
  • 外网访问不受影响:外部访客的解析请求走公网 DNS(如阿里云),不经过你的 AGH,Lucky DDNS 更新到域名服务商的 AAAA 记录照常生效。

两个注意点:

  • 该规则会拦截所有域名在内网解析时的 AAAA 记录。如果某台内网设备确实需要解析某个域名的 IPv6 地址,用白名单例外放行:
@@||example.com^$dnstype=AAAA
  • 依赖纯 IPv6 站点的场景(只能通过 AAAA 访问的网站)会无法解析,需要自行权衡是否启用。

验证:

C:\Windows\system32>nslookup -type=AAAA steamchina.com

预期:不再返回 AAAA 记录(空应答或只返回 A 记录);普通解析依旧指向 AGH。

6 验证与测试#

6.1 旁路由 IPv6 地址#

Terminal window
ip -6 addr

预期输出(前缀已脱敏):

3: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 2408:xxxx:xxxx:xxxx:1234:5678:9abc:def0/64 scope global dynamic noprefixroute

关键点:地址是 2408: 开头的公网 IPv6,且带 noprefixroute,代表旁路由只持有地址、不分发前缀,不会抢主路由的 RA 通告。

6.2 Windows 网卡信息#

C:\Windows\system32>ipconfig /all

预期结果:

  • 网卡存在公网 IPv6 地址。
  • IPv6 DNS 服务器一栏为空。
  • IPv4 DNS 只有 AGH 内网地址。

6.3 域名解析路径#

C:\Windows\system32>nslookup steamchina.com
服务器: adguardhome
Address: 192.168.3.3

解析服务器变成了 AGH(192.168.3.3),IPv6 DNS 旁路问题彻底消失。

6.4 路由路径#

C:\Windows\system32>tracert steamchina.com
1 <1 毫秒 <1 毫秒 <1 毫秒 192.168.3.2 ← 旁路由
2 <1 毫秒 <1 毫秒 <1 毫秒 192.168.3.1 ← 主路由
3 3 ms 2 ms 2 ms x.x.x.x ← 运营商出口
...
18 68 ms 68 ms 69 ms 218.92.141.107 ← 目标服务器

中间若干跳显示 请求超时 属于正常现象:运营商骨干设备普遍关闭 ICMP 超时应答,只要最终能到达目标 IP,链路就是通的。

7 踩坑记录#

  • 重启路由器后问题复现:游戏协调服务器异常,重启路由器即恢复,根因是路由器连接会话表 / DNS 转发缓存卡死,重启清空即可;但 DNS 走 IPv6 的问题与它无关,是 RDNSS 未关闭导致。
  • service odhcpd restart 报 Not found:ImmortalWrt 无独立 odhcpd 服务,改用 /etc/init.d/dnsmasq restart 重载,配置本身已通过 uci commit 落盘。
  • 爱快自动填充公共 IPv6 DNS:部分固件即使不手动填,RA 的 RDNSS 也会带上阿里等公共 IPv6 DNS,必须显式关闭「IPv6 DNS」开关。
  • 内网其他设备旧配置残留:手机、平板等设备需要重连一次 WiFi / 网线,清除旧 RA 缓存,才能拿到不带 RDNSS 的新 RA 报文。
  • 不要给旁路由开 RA server:双 RA 冲突会让内网 IPv6 DNS 与地址分配彻底混乱,旁路由只做客户端。

8 总结#

最终整套环境达到的目标:

  • 内网设备正常获取公网 IPv6 地址,IPv6 上网、远程直连不受影响。
  • 所有域名解析强制走 IPv4 侧的 AdGuard Home,过滤规则与条件上游分流全部生效,不再被公共 IPv6 DNS 旁路;可选叠加 AAAA 过滤规则,让 DNS 层与 IPv6 彻底脱钩。
  • ImmortalWrt 旁路由持有公网 IPv6,Lucky DDNS 正常更新 AAAA 记录,远程访问链路完整。
  • 爱快主路由独占 RA 通告,旁路由不做 IPv6 服务器,无双重 RA 冲突。

核心就一句话:RA 报文里「前缀」和「DNS」是两回事,前缀照发、DNS 关掉,IPv6 远程访问与 DNS 统一管理就能兼得。

Created with ❤️ by 张萌萌

IPv6 与 DNS 的分手协议
https://zmm.nw177.cn/posts/10-技术专栏/20-network/16ipv6与dns的分手协议/
作者
张萌萌
发布于
2026-10-02
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取

评论

正在加载评论...