Blog

在 OpenWRT 19.07 上实现 NPTv6 (NAT66)

发布时间: ,大约 200 字 ,阅读时间:1 分钟,

NPTv6 是什么

用一个最简单的例子介绍,网络架构如下图所示:

假设内部网络的 IP 段是 fd01::/64,外部网络的 IP 段是 2001:0db8:1145:1419::/64,那么就有如下的映射关系:

内网 IP 公网 IP
fd01::1 2001:0db8:1145:1419::1
fd01::2 2001:0db8:1145:1419::2
fd01::3 2001:0db8:1145:1419::3
fd01::4 2001:0db8:1145:1419::4

以此类推。

这样做的话,与 2001:0db8:1145:1419:1145:1419:1981:0893 通信即相当于与 fd01::1145:1419:1981:0893 通信。 虽然机器上没有真正的公网 IP 地址,但是 NAT 穿透什么的都是不需要的。 而且这样做可以用无状态协议的方式实现。

但这也有限制。因为每个内部 IP 都有一个独立的公网 IP 映射,所以公网 IP 段的前缀长度必须等于内网 IP 段的前缀长度。

Disco Cisco 的网站上有英文的介绍。

既然都 IPv6 了,为什么还要 NAT?

(对于家庭宽带)网络不稳定

IPv6 有大量地址,运营商分配的最小前缀也是 /64,对于一个家庭来说,内网设备肯定足够分配了。但国内运营商联网一般使用 PPPoE 认证,分配 IP 地址一般采用动态分配。这样就会有如下图的情况:

what-is-my-real-ip.png

图片上获取到的 IPv6 地址都是由 IPv6-RA 分配的。因为各种各样的原因,即使路由器换了地址,NAS 也不会马上去把以前那些没用的 IP 地址删掉,运气好的话 NAS 换了新的地址会马上去用新的,但大部分情况并不会(每次 ssh 上去 NAS 的 IPv6 都是不通的)。而且国内运营商都喜欢 PPPoE 每隔几天掐断一次,断一次 PPPoE 就会换一次 IP,所以这就导致了 IPv6 显得非常不稳定,需要经常重启或者重新断开重连才能恢复。

(对于多 ISP 接入)路由不稳定

disco-385014.webp

对于上图的网络结构,如果在单台路由器上直接给终端设备分配两个不同的 IPv6 地址,终端设备并不知道哪条路是最优解,这就导致可能对端是中国奠信的 IP 但是却使用了中国移动的线路访问。这样不仅没有办法控制终端走向最优出口 ISP,还可能让一大堆用户挤在同一个 ISP 的线路上,另外的 ISP 的线路基本空载。当然,买一段 IP 和一个 ASN 来直接 BGP 能解决,但大多数公司不会这样做。

在 OpenWRT 上实现 NPTv6

通过搜索,可以找到 ip6tables -j NETMAP 可以实现这个功能,但是 OpenWRT 目前并没有直接提供开启的选项,所以这里需要写一个脚本来实现。

1. 修改 IPv6 ULA 为其它的保留地址

这个直接在 Luci 里面操作就可以了,做这一步主要是为了让客户端以为自己有公网 IPv6。建议修改成 2001:db8::/32,因为是用于文档的保留地址。

change-ula-address.png

2. 安装必要的软件包

进入到 shell,并输入命令 opkg install ip6tables ip6tables-extra ip6tables-mod-nat iptables-mod-conntrack-extra iptables-mod-extra iptables-mod-dnetmap

3. 将 nptv6.sh 放进相应文件夹

Shell 文件在这里可以找到。在这篇文章中,我把这个脚本放进了 /usr/sbin/ 里面,并赋予了可执行的权限。

4. 在防火墙的“自定义规则”中添加 NPTv6 命令

这一步也可以在 Luci 上操作,如下图所示。

append-nat66-rule.png

脚本总共三个参数,第一个是实际接口名(比如 OpenWRT 设置了一个 PPPoE 拨号的接口叫 wan,那么实际接口名就是 pppoe-wan)。第二个是需要重定向到的 IPv6 地址(即内网 IPv6 地址)。第三个参数是可选的,只有不传和 connect 两个选择。如果不传的话就会把之前创建的 ip6tables 规则删掉,如果传 connect 会在删掉的同时去找相应接口的 IPv6 地址,并创建新的规则。

5. 添加 ifupdown 钩子

ifupdown 钩子的样例可以在这里找到

上面的钩子脚本的开头三个变量需要根据自己的环境去修改,钩子需要放入 /etc/hotplug.d/iface。如果第四步添加的 nptv6.sh 位置不在 /usr/sbin/ 的话,也需要把 /usr/sbin/ 替换掉。

钩子脚本也需要赋予可执行文件权限。

注意:OpenWRT 19.07 貌似并不会为 IPv6-ULA 地址添加 IPv6 的默认路由,所以脚本第 12 行还有一条添加路由的指令。如果是多线接入,需要修改 metric 调整顺序以及避免添加路由失败。

6. 重新拨号,测试网络连通性

nptv6-works.png

it-works.webp


License

如未明确声明,所有文章皆以

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。如果您需要商用,您可以通过电子邮件( [email protected] )联系。

隐私权

本站启用了由 Google Analytics 提供的统计服务,如果您不希望被跟踪,请安装 AdBlock (Plus) 或与 Google 联系。 请注意:根据相关的法律法规,本站不对欧盟用户提供服务。