OpenWrt 配置 IPv6 NAT6

本文配套视频,质量一般,B站就不发了:

为什么要使用NAT6?

通常情况下,IPv6网络为每个联网设备分配了公网IPv6地址。由于公网IPv6地址的数量极其庞大,黑客难以通过传统的枚举方法进行有效的扫描和入侵。然而,随着量子计算技术的进步,这种安全性优势可能会在未来逐渐减弱。

在网络安全管理较为薄弱的家庭环境和小型企业中,IPv6被用来实现外网远程访问。部分老旧设备可能因系统简陋而缺乏复杂的防火墙规则配置,这使得它们更容易遭受黑客的扫描与攻击。当量子计算机技术更加普及后,这类攻击实施起来可能会变得更加简单。

在IPv6全面普及之前,由于许多安全措施尚未完善,它反而可能成为一片攻击者的蓝海。

为了提升网络安全性并顺利过渡到IPv6,我们可以考虑在网络架构中引入NAT(网络地址转换)技术作为临时解决方案之一。

此外,一些地区的宽带拨号后没有下发DHCPv6-PD前缀信息,而是直接下发64位IPv6地址,路由器无法分配IPv6地址(当然可以把IPv6相关选项设置成relay模式,但获取的IPv6地址不是你路由器分配的)。

不过需要注意的是,这样做会导致所有设备共享同一个公共IPv6地址,而不是由路由器独立分配的私有IPv6地址,这可能会影响某些特定应用的功能。

另外,通过这种NAT的方式实现IPv6会阻碍IPv6的发展,因此,我们应当尽可能地使用IPv6的相关机制分配公网IPv6地址。

如何避免使用NAT6?

为了尽到去 NAT 的义务,增加此节。

如果您的上级设备能够为下级设备分配 IPv6 地址(不管你接了多少个设备),那么配置 IPv6 中继是一个不错的选择。

(下方描述中,IPv6前缀相当于IPv4的子网,前缀数字越大实际能分配的地址越少,/64前缀的网络地址数量要比 /60 的少,故此处称 /64 小于 /60)

只要有小于 /64 的IPv6地址前缀,OpenWrt 就会自动将其作为 IPv6-PD 前缀,然后为 LAN 接口分配 /64 前缀。

如果您能将光猫改为桥接模式,然后使用 OpenWrt 拨号,通常可以获取到大于 /64 的 DHCPv6-PD 前缀。

如果您是光猫拨号,可以尝试进入光猫设置,启用 DHCPv6(SLAAC不行,无法下发大于 /64 前缀),将 /64 前缀增加到 /60,这样 OpenWrt 就能获取到DHCPv6-PD前缀,无需改桥接。

如果您只能获取到小于等于 /64 的前缀,只要不是 /128 的前缀,都可以作为前缀手动分配地址,IP没冲突基本都可以使用,不过设置起来有点麻烦,可能需要编写脚本实现。

如果您只能获取到 /128 的前缀,那么此时就只能使用 NAT6 共享一个 IPv6 地址给下级设备使用了。

OpenWrt系统配置NAT6

1、安装并更新软件包

警告:使用 nftables 的 OpenWrt (23.x以上版本)不要执行此步骤,系统基本默认支持配置 NAT6。

以下命令只适用于 iptables,强制执行会引入不必要的依赖。

1
2
3
opkg update
opkg install ip6tables
opkg install kmod-ipt-nat6

这几个包通常是默认安装的。

2、修改ULA前缀

这个在IPv6中近似于IPv4的LAN口内网地址。

默认情况下,OpenWrt 会在第一次启动时会随机生成好ULA前缀,因此我们可以直接跳到第3步

修改/etc/config/network文件中的ula_prefix,如果已有内容,无需修改,直接:q退出。

1
vi /etc/config/network
1
2
config globals 'globals'
option ula_prefix 'fd38:eb73:c847::/48'

如果此时重启网络或OpenWrt系统,下联的设备会获取到ULA前缀开头的64位和128位IPv6地址。

3、配置网关地址下发

此步十分重要。

建议您将 PC 连接到 OpenWrt LAN 底下,如果获取不到 IPv6 网关,那么必须要执行这一步。

修改/etc/config/dhcp文件中lan口的DHCPv6配置,如果已有多余的内容,建议从option dhcpv6开始删除替换。

1
vi /etc/config/dhcp
1
2
3
4
5
6
7
8
9
10
config dhcp 'lan'
option interface 'lan'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv4 'server'
option dhcpv6 'server'
option ra 'server'
option ra_management '1'
option ra_default '1'

建议使用替换的方法修改配置,从第六行就开始覆盖替换。直接在浏览器LuCI里面修改可能会导致配置错误。

4、打开IPv6 NAT

新版 OpenWrt 直接在“网络->防火墙->常规设置”地下的区域那里,在到 “WAN -> Reject” 处,我们点击编辑,在弹出的区域设置内,切换到高级设置选项卡,勾选“IPv6 Masquerading”(IPv6 伪装)即可。

以下信息仅供 23.x 以下老版本和使用 Iptables 的版本,Nftables 的你连自定义防火墙的选项都找不到。

部分固件在“网络->防火墙->NAT 规则”里面配置好一条名为“nat6”的规则,默认没有启用,我们勾选“启用”,然后点击页面下方的“保存并应用”即可完成配置。

其它系统需要修改/etc/firewall.user脚本,自定义防火墙规则。

方法一:http://路由器的IP地址/cgi-bin/luci/admin/network/firewall/custom

方法二:vi /etc/firewall.user

1
2
3
WAN6=这里填写IPv6 WAN6口的网卡名称,如eth0
LAN=这里填写LAN口的网卡名称,一般就填br-lan
ip6tables -t nat -A POSTROUTING -o $WAN6 -j MASQUERADE

安全起见,下面两条不建议添加,基本不影响使用:

1
2
ip6tables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A FORWARD -i $LAN -j ACCEPT

5、正确配置网关

正常情况下,此时客户端应该可以正确获取 IPv6 ULA地址 + 网关。

此时客户端如果可以正常使用 IPv6 上网,恭喜你,你很幸运。

然而现实情况下,即使客户端的路由是正确的,但是客户端无法正常访问IPv6网络,那到底是怎么回事呢?

这是本文的重点。

在路由器上看一下自己的默认网关。

1
ip -6 route show default
1
2
default from 2409:xxxx:xxxx:xxxx::xxx via fe80::xxx:xxxx:xxxx:xxxx dev eth0 proto static metric 512 pref medium
default from 2409:xxxx:xxxx:xxxx::/64 via fe80::xxx:xxxx:xxxx:xxxx dev eth0 proto static metric 512 pref medium

如果您获得的是这样 fe80::xxx:xxxx:xxxx:xxxx 的网关,OpenWrt 不会将其添加到默认路由表中,即使此时 OpenWrt 已经可以通过 IPv6 的方式访问 IPv6 网络,客户端就是不行。

为了解决这个问题,需要创建一个钩子脚本 /etc/hotplug.d/iface/99-ipv6 ,把上面返回的 fe80::xxx:xxxx:xxxx:xxxx 默认路由添加到路由表中。

1
vi /etc/hotplug.d/iface/99-ipv6

网上的教程中,基本上都只获取到一个IPv6地址,如SLAAC,然而我这边有两个IPv6地址,如DHCPv6+SLAAC,需要手动修改脚本。

下面的脚本我已经修改过,只会使用获取到的第一个IPv6地址的网关地址及信息,均测试有效

第一种:

1
2
3
#!/bin/sh
[ "$ACTION" = ifup ] || exit 0
ip -6 route add `ip -6 route show default|sed -e 's/from [^ ]* //'|sed -n '1p'`

第二种:

1
2
3
#!/bin/sh
[ "$ACTION" = ifup ] || exit 0
route -A inet6 add default gw `(ip -6 route | grep default | awk '{print $5,$6,$7}' | sed -n '1p')`

设置权限:

1
chmod +x /etc/hotplug.d/iface/99-ipv6

6、重启路由器使配置生效

1
reboot

7、开启IPv6 DNS解析

默认情况下,新版系统已经默认开启IPv6 DNS解析。

其它系统需要浏览器访问http://路由器的IP地址/cgi-bin/luci/admin/network/dhcp ,点击高级设置,取消“禁止解析 IPv6 DNS 记录”,然后点击页面下方的“保存并应用”。

8、测试

浏览器验证

浏览器访问以下网站,查看当前用于上网 IPv6 的地址:

http://ipw.cn/

http://ch.test-ipv6.com/

http://ipv6-test.ch/

如果您需要验证上级设备的连通性,可以访问:

http://[上一层的IPv6网络设备地址]

如果ipv6-test已出IPv4地址,5秒内未出IPv6地址,那么基本上失败,不用继续等待。

如果第5步网关配置错误,会表现为上一层的IPv6网络设备正常访问,上上层的网络设备(公网)无法访问,ipv6-test失败。

这种情况可以尝试更改/etc/hotplug.d/iface/99-ipv6文件sed -n '1p'中的1

正常情况下,ipv6-test应该可以正常(10/10)通过,显示的 IPv6 地址为上级路由的 IPv6 地址。

最佳测试方法

如果您刚修改了设置,建议重启网卡。

如果您无法打开浏览器,可以在终端上输入:

1
curl 6.ipw.cn

您可以通过上述命令验证 OpenWrt 与 IPv6 的连通性。

如果需要深度排查,可以先验证解析域名是否正确:

1
ping www.baidu.com -6

上述命令如果连 IPv6 地址都没有返回,请检查 DNS 配置,正常情况下 IPv4 的 DNS 服务器都能返回 IPv6 地址,如果没有返回 IPv6 说明肯定有限制。

如果能够返回 IPv6 地址,但无法 Ping 通,那么可能是地址的问题,可以查看是否获取到了地址和网关。

1
ipconfig /all

如果能够获取到地址(非fe80)和网关,可以测试一下路由:

1
tracert www.baidu.com -6

如果无法路由,可以查看路由表:

1
route print -6

如果确定是网关的问题,那就检查网关上的配置。

后记

目前这个IPv6的NAT还有一些问题,而且相关问题和应用开发的积极性不高,毕竟这与IPv6要消除NAT的初衷相悖。不过NAT6对于多线聚合等应用还是有一定意义。相信以后随着IPv6的普及和大佬的进一步研究,以及在企业等大型公共网络中的部署,肯定会出现更完善甚至更独特的解决方案。

参考:

https://openwrt.org/docs/guide-user/network/ipv6/ipv6.nat6

https://tang.su/2017/03/openwrt-ipv6-nat/

https://www.jianshu.com/p/2a5e0ba31835