现在的教育网和宽带基本都提供了IPv6支持。但是,由于网络性质使然,IPv6并不能像IPv4那样,直接使用路由器共享,这使得路由器接入IPv6后,所有连接到路由器的设备都不能连接v6。
为此,必须对路由器进行一番魔改。如果路由器使用的是OpenWrt,或基于OpenWrt的固件,那么在经过一番设置后,IPv6的共享就不再是传说了。原理就是借助OpenWRT提供的kmod-ipt-nat6
模块,启用IPv6的NAT功能(NAT6)。
设置脚本
【!!!注意!!!】
我编写这个脚本,旨在便于一键设置IPv6,使操作自动化。
由于年代久远,且设计时没有考虑鲁棒性,本脚本不能保证在所有OpenWRT环境中均正常使用。(例如,有些旧版本OpenWRT会无法安装
kmod-ipt-nat6
组件。)建议直接按照下文的“原理”部分来一步步操作。
为了方便路由器的配置,我将所有设置过程做成了一个脚本,并在GitHub上开源。
使用脚本的步骤很简单,只要你准备好用于发送文件的WinSCP,与用于远程登录路由器的PuTTY。
- 第一步,使用WinSCP,登录到路由器上,并将
operation.sh
上传到/tmp
文件夹中。 - 第二步,使用PuTTY或WinSCP自带的Shell,运行
/tmp/operation.sh
。稍等片刻,即可配置好。下次重启路由器,就可以自动将WAN的IPv6共享给路由器局域网内的设备了。
如果使用Linux,或在Windows下使用Cygwin或Git-SCM(一个在Windows下使用Git的套件),那么使用它们自带的scp
和ssh
工具,会方便得多:
1 |
|
原理
脚本完成的设置过程,包括了如下具体操作:
(1)安装kmod-ipt-nat6
kmod-ipt-nat6
是用于启用IPv6 NAT的内核模块。在OpenWrt中,使用包管理工具opkg
进行安装。
1 |
|
(2)更改IPv6 ULA前缀
ULA,全称为“唯一的本地IPv6单播地址”(Unique Local IPv6 Unicast Address)[^1]。这一步,我们要把它的前缀由f
改为d
,以将本地的IPv6地址向外广播,而不是localhost那样的闭环。
用于实现这一步的脚本如下:
1 |
|
OpenWrt的属性参数由uci
工具管理,类似于Android的property机制(setprop
/getprop
),使用“域”来组织各类参数。脚本的第一行,在$()
中调用uci
命令,获取当前的ULA前缀,将执行结果传递给sed
命令。这里sed
命令使用了替换语法——sed 's/<原文本>/<替换文本>/'
,将开头第一个字符替换为字符“d
”。Shell的$()
语法可将命令运行结果作为文本使用,那么该用法内的命令结果就作为新的ULA前缀被应用。最后,运行第二行的命令,提交修改。
(3)将DHCP服务器模式设置为“总是广播默认路由”
如果没猜错的话,DHCP服务器模式设置为“总是广播默认路由”,可让内网中的设备能够快速获取IPv6地址。但该选项的具体原理还得查查OpenWrt的文档。
1 |
|
(4)添加NAT6初始化脚本
NAT6初始化脚本的作用,就是在路由器启动时自动开启IPv6的NAT功能。该脚本保存到/etc/init.d/nat6
中,在我的脚本中使用bash
的Here Document功能来创建它。
NAT6的内容如下:
1 |
|
当然,为了让该脚本能够运行,还必须要修改权限。并且,存放在/etc/init.d
中的脚本作为Linux中的服务来看待,因此还需启用它。
1 |
|
(5)关闭不需要的防火墙规则
OpenWrt的防火墙中有一个默认规则,叫Allow-ICMPv6-Forward
。该规则在我们的实际使用中并不需要,因为我们用于IPv6内网穿透的Masquerade模块已经取代了它的功能。
1 |
|
(6)接收广播并开启IPv6转发
接下来要修改的文件是/etc/sysctl.conf
,其中包含的广播和IPv6转发有关的配置需要进行调整,将它们的值都设为“2
”:
net.ipv6.conf.default.forwarding
net.ipv6.conf.all.forwarding
net.ipv6.conf.default.accept_ra
net.ipv6.conf.all.accept_ra
一般地,上述设置需要用户手动修改。但为了实现脚本的自动化,我使用文本处理程序sed
来进行自动替换。
1 |
|
一般情况下,这些设置都会排在一起,所以在使用sed
进行操作时,可以先定位到其中一个设置项,然后对其值进行修改。有些设备上的/etc/sysctl.conf
并没有上面的设置项,因此还要考虑这一情况,在配置文件中加上相应的项——首先把net.ipv6.conf.default.forwarding=2
加到文件尾部,然后再依次添加剩下的几项。
TODO: 还需要讲解sed的用法!
(7)配置ip6tables,加入转发规则
最后设置ip6tables,加入IPv6 NAT转发的规则,并重启系统的防火墙服务:
1 |
|
测试IPv6使用状况
以上设置完成后,重启路由器,内网的IPv6设备就能够获得IPv6地址了。将任意一台设备连接到路由器上,打开它们的网络设置,如果得到了IPv6地址,且不是“fe80
”开头,就说明设置成功。
当然,想让内网设备使用IPv6上网,就必须确定外网能否支持。一个简便的方法是,使用ssh登录路由器,然后ping谷歌的IPv6地址(http://ipv6.google.com.hk/ ),若能够ping通,就说明外网访问IPv6没问题。
1 |
|
使用测试网站,可以更专业、更直观地检测IPv6的连接性。只要内网设备配置正确,测试均能通过:
注:
- “
fe80
”开头的地址是内网地址,而非公网。我路由器上的设备都能连接IPv6外网,它们的IPv6地址以 “d
” 开头。- 中国教育网(CERNET)支持IPv6访问。笔者的学校——华中科技大学,为教育网的重要节点,只要能登录校园网就能使用IPv6。
- 运营商网络,包括电信、联通、移动、各地广电和长城宽带,IPv6服务须额外申请,而且并不是所有地方都能办理。
拓展阅读
如果你习惯使用LuCI来配置,建议参考知乎网友一只大肥猫呦的文章:《校园网环境下Openwrt配置ipv6教程——以nat6为例》。
致谢与参考
- zqp19950813提供配置方法。本文的脚本基于他的教程编写。
- 【转发】 通过openwrt的NAT6转发,使后端设备获得ipv6网络
[^1]: 《IPv6地址》. 北海石松 - 博客园. https://www.cnblogs.com/gogly/articles/2558150.html
- 本文作者: 爱拼安小匠
- 本文链接: https://anclark.github.io/2018/11/12/OpenWRT/OpenWRT_IPv6_NAT6_Script/
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0(署名-非商用-禁止演绎 3.0) 许可协议。转载请注明出处!