值得注意的是,除非你的路由器实在是被下发了/128子网,即一个IPv6地址的极端情况,否则请不要使用NAT6这个方案。NAT6会造成性能损耗以及端对端特性的缺失。
ULA + NAT6之“曲线救国”
NAT6 (IPv6 Masquerade),很好理解同NAT4一样是为了解决地址数不足问题所涉及的补救方案。
这虽然违背了 IPv6 端到端通信的初衷,甚至造成了性能的衰减,但在这种特殊的校园网环境下,能用上才是王道。
配置 ULA + NAT6 的方案,核心思路是:内网设备使用 ULA (唯一本地地址),OpenWrt 作为网关,在 WAN 口将所有出站的 ULA 流量的源地址替换成路由器 WAN 口自身的公网 IPv6 地址。
1.LAN 端改造:ULA 的正确启用
首先,将 OpenWrt 的 LAN 口 IRA和 dhcpv6从“中继模式 (Relay mode)”改为“服务器模式 (Server mode)”,NDP 代理设置为已禁用。
IPv6 RA下 默认路由器 设置为强制的。
启用并正确配置 ULA (唯一本地地址) 前缀。
全局网络设置下IPv6 ULA 前缀 设置留空或一个有效的 /48 ULA 前缀 (例如 fd00:1234:5678::/48)。
遇到的坑1:一开始 br-lan 接口没有正确获取到 ULA 地址(通过 ip -6 addr show dev br-lan 检查,只有 fe80:: 的链路本地地址),导致客户端依然没有默认网关。通过上述修改,确保 br-lan 拥有了类似 fdxx:xxxx:xxxx::1/64 的 ULA 地址。
客户端电脑随后也成功获取了 ULA 地址,并且 IPv6 默认网关正确指向了 OpenWrt br-lan 接口的链路本地地址(fe80::...)。
2. WAN 端防火墙配置:开启 IPv6 Masquerade
在 /etc/config/firewall 中,为 config zone 'wan' 添加 option masq6 '1'。
重启防火墙 /etc/init.d/firewall restart。
关键的路由问题:源特定路由的“从中作梗”
- 即使这样配置了,一开始还是不通!电脑提示“无法访问目标网”。再次在 br-lan 抓包,发现是 OpenWrt 自己向客户端发送了 ICMPv6 "Destination Unreachable, Unreachable Route" 错误。
- 深入排查 ip -6 route show:终于发现了症结所在!OpenWrt 上有一条源地址特定的默认 IPv6 路由:default from 240c:... via ...。这条路由意味着只有当数据包的源 IP 地址属于校园网分配给 WAN 口的那个 240c:... 公网前缀时,才使用这条默认路由。而我 LAN 客户端的源 IP 是 ULA 地址,根本不匹配这个条件!所以 OpenWrt 认为无法将 ULA 的包路由出去。
- “元凶”锁定:这条源地址特定的路由,很可能是我之前在 wan6 接口上(有意或无意)开启了一个名为 “IPv6 源路由 (IPv6 Source Routing)”(或类似描述“使用基于源的策略路由自动处理多个上行链路接口”)的选项导致的。
因此,请关闭 wan6 接口上的“IPv6 源路由”选项。
(可选优化,但推荐)为了让 wan6 接口获取一个更纯净、不带源限制的默认路由,并配合 NAT6(此时 WAN 口自身有公网 IP 即可),将 wan6 的 option reqprefix 设置为 'no' (不再请求前缀委派),并确保 option defaultroute '1' (请求设置默认路由)。
LAN 侧的 ULA 配置保持不变。
防火墙 masq6 '1' 保持开启,并确认 nft list ruleset 的 chain srcnat_wan 中出现了针对 meta nfproto ipv6 的 masquerade 规则 (或我之前看到的 fullcone 规则,只要它能实现源地址伪装)。
重启路由器后,再次检查:
ip -6 route show 显示默认路由不再带有 from 240c:... 的限制,变成了一条通用的默认路由!
客户端获取 ULA 地址和指向 OpenWrt 的网关。
访问 test-ipv6.com 测试也顺利通过了大部分项目(除了因为 NAT 可能导致的一些端到端特性识别问题)。