发现楼里其实是自带 IPv6 的(不过不清楚为什么之前的 Linux 没法直接用,必须 ISATAP)。最近买了一个 R2S 软路由,买过来也想整上 IPv6,但是弄了好久都没有弄好,以为 ISATAP 方案大多要使用 radvd 这个包,但是这个包在近期版本的 OpenWRT 上貌似被废弃了,始终找不到,然而网上的 ISATAP 教程即便是近期的也还是在说 radvd。后来巧合中我给 R2S 刷了一个新的固件: QiuSimons / R2S-OpenWrt,然后就意外的发现在路由器上能 Ping 通 IPv6 Only 的站点了。然而 LAN 网的设备还不能访问 IPv6 资源。显然这是缺乏 NAT6 导致的。

经过一番搜索,我在 OpenWRT 路由器作为 IPv6 网关的配置 这篇文章里找到了配置方法(这个仓库貌似是 tuna 建的),我把内容附在下面.

OpenWRT 是一种嵌入式 Linux 操作系统,广泛应用于家用路由器/网关。本文将介绍几种在清华校园网中,使用 OpenWRT 路由器为接入设备提供 IPv6 服务的配置方法。

本文内容综合有多位贡献者,如有疑问、建议,可以参与内容讨论

1 IPv6 NAT

虽然 IETF 的设计中,IPv6 不再有 NAT (网络地址转换), 但 Linux 内核从 3.7 版本开始实现了 IPv6 的 NAT。早年也曾有过 NAT66 等非官方项目,但缺乏维护,目前已经不再推荐使用。 OpenWRT IPv6 NAT 配置部分,由 @Blaok 贡献。

1.1 零: 检查内核模块和有用的软件包

1
ip6tables kmod-ipt-nat6 kmod-ip6tables kmod-ip6tables-extra luci-proto-ipv6 iputils-traceroute6

较新的 OpenWrt 已经内置了 IPv6 支持。对于较老的版本(Backfire 10.03 或 Attitude Adjustment 12.09 及之前),还需要安装kmod-ipv6

kmod开头的内核模块一般无法通过 opkg 直接安装,其他软件包虽然可以通过opkg install直接安装,但会多占路由器存储空间,推荐在编译固件时就将这些软件包都放入固件

kmod-ipt-nat6提供 IPv6 NAT 支持,ip6tables kmod-ip6tables kmod-ip6tables-extra等提供 IPv6 防火墙,luci-proto-ipv6为 LuCI 提供 IPv6 设置选项,iputils-traceroute6为 IPv6 提供 traceroute 功能(mtr是个不错的支持双栈的traceroute替代品,如果路由器存储空间够大的话)

1.2 壹: 打开 OpenWRT IPv6 私网地址分配

OpenWRT 默认会分配 IPv6 私网地址,在Network->Interfaces页面底下有个Global network optionsIPv6 ULA-Prefix这里应该有一个随机的fd开头的/64地址,LAN 客户端应该能自动获得这个地址范围内的 IPv6 地址,DHCPv6 和 SLAAC 默认都开了

为了让 OpenWRT 后面的设备始终能够获得 IPv6 网关,需要在Network->Interfaces->LAN下方的DHCP Server部分的IPv6 Settings部分,勾选Always announce default router。否则,由于默认分配的是私网地址,OpenWRT 不会向下游设备公布 IPv6 默认路由(即网关),可能导致路由器上 IPv6 连通但下游设备不通的情况 (感谢@terro提醒)

1.3 贰: 打开 IPv6 NAT

客户端有了正确的地址以后,需要在路由器上打开 IPv6 NAT。OpenWRT 默认的防火墙配置不会管 IPv6 的 nat 表,可以在/etc/firewall.user里面加上

1
2
3
4
5
WAN6=eth0
LAN=br-lan
ip6tables -t nat -A POSTROUTING -o $WAN6 -j MASQUERADE
ip6tables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A FORWARD -i $LAN -j ACCEPT

WAN6 和 LAN 分别改成外网 IPv6 和内网网卡(interface)的名字,注意不是防火墙区域(zone)的名字,也不是 LuCI 里面Network->Interfaces里面看到的名字,而是ifconfig看到的名字

1.4 叁: 正确配置网关

在路由器上ip -6 route看一下自己的默认网关。如果获得的是

1
default from 2402:f000:x:xxxx::/64 via fe80::xxxx:xxxx:xxxx:xxxx dev eth0  proto static  metric 512

这样坑爹的网关,在转发 NAT 包的时候会有问题,需要把去掉from 2402:f000:x:xxxx::/64这一部分的以后的默认路由添加到路由表中。可以新建一个/etc/hotplug.d/iface/99-ipv6,它的内容是

1
2
3
4
5
6
#!/bin/sh
[ "$ACTION" = ifup ] || exit 0
iface=wan6
[ -z "$iface" -o "$INTERFACE" = "$iface" ] || exit 0
ip -6 route add `ip -6 route show default|sed -e 's/from [^ ]* //'`
logger -t IPv6 "Add IPv6 default route."

这里iface是 LuCI 里面Network->Interfaces里面看到的名字,一般叫 wan6。这个脚本的意思是在 wan6 起来以后读取默认网关,把带 from 的内容去掉,再加到系统路由表里。记得

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