我的博客: 菱歌's Blog | 听见美好
笔记原文地址:OpenWrt上开启NAT6为内网提供IPv6支持
校园网IPv6免流量,不限带宽,同时也有一些v6 only的PT资源,非常有用,但是大部分情况下使用路由器后,内网设备就无法使用IPv6了。可以通过NAT6为路由器内网设备提供IPv6支持。
坐标THU,使用教育网IPv6,运营商的v6没有测试过。
问题
之前一直使用的relay(中继)模式为路由器下的各个设备提供IPv6,具体方法可以参考这篇博客,这种模式的好处是可以为内网设备分配到真实的公有IPv6地址,但是因为odhcpd不间断抽风,需要经常重启服务才能使用。
近期突然发现实验室的relay配置失效了,具体表现为:能够分配到IPv6地址但是无法访问v6网络,经过检查发现此时分配到的IPv6是2402:f000:xxxxx/128
的形式,/128
表明此时的地址已经过了dhcpv6分配,而relay模式也是借助dhcpv6进行分配。因而此时只能使用IPv6的NAT,虽然它有一些效率问题。
NAT6配置
- 安装所需支持,事实上许多OpenWrt系统没有安装
odhcpd
和odhcp6c
,前者在这里用于内网v6地址的分配,而后者作为路由器获取外网v6地址的客户端。opkg update && opkg install kmod-ipt-nat6 odhcpd odhcp6c
- 更改内网IPv6 ULA 前缀,也可以再Luci界面中操作,将首位的
f
改为d
,这样问题少些。uci set network.globals.ula_prefix="$(uci get network.globals.ula_prefix | sed 's/^./d/')" uci commit network
- 设置LAN口dhcp
uci set dhcp.lan.ra_default='1' uci commit dhcp
- 新建NAT6服务,内容见NAT6
touch /etc/init.d/nat6 vi /etc/init.d/nat6
- 启动NAT6服务
chmod +x /etc/init.d/nat6 /etc/init.d/nat6 enable
- 在
/etc/firewall.user
中添加转发规则,否则内网v6流量不能被转发。ip6tables -t nat -A POSTROUTING -o eth0.2 -j MASQUERADE
- 重启路由器
-
(可选)为PT服务提供UPnP高位端口映射,提高效率。uTorrent下载效果:
满速下载
NAT6服务脚本
#!/bin/sh /etc/rc.common
# NAT6 init script for OpenWrt // Depends on package: kmod-ipt-nat6
START=55
# Options
# -------
# Use temporary addresses (IPv6 privacy extensions) for outgoing connections? Yes: 1 / No: 0
PRIVACY=1
# Maximum number of attempts before this script will stop in case no IPv6 route is available
# This limits the execution time of the IPv6 route lookup to (MAX_TRIES+1)*(MAX_TRIES/2) seconds. The default (15) equals 120 seconds.
MAX_TRIES=15
# An initial delay (in seconds) helps to avoid looking for the IPv6 network too early. Ideally, the first probe is successful.
# This would be the case if the time passed between the system log messages "Probing IPv6 route" and "Setting up NAT6" is 1 second.
DELAY=10
# Logical interface name of outbound IPv6 connection
# There should be no need to modify this, unless you changed the default network interface names
# Edit by Vincent: I never changed my default network interface names, but still I have to change the WAN6_NAME to "wan" instead of "wan6"
WAN6_NAME="wan6"
# ---------------------------------------------------
# Options end here - no need to change anything below
boot() {
[ $DELAY -gt 0 ] && sleep $DELAY
logger -t NAT6 "Probing IPv6 route"
PROBE=0
COUNT=1
while [ $PROBE -eq 0 ]
do
if [ $COUNT -gt $MAX_TRIES ]
then
logger -t NAT6 "Fatal error: No IPv6 route found (reached retry limit)" && exit 1
fi
sleep $COUNT
COUNT=$((COUNT+1))
PROBE=$(route -A inet6 | grep -c '::/0')
done
logger -t NAT6 "Setting up NAT6"
WAN6_INTERFACE=$(uci get "network.$WAN6_NAME.ifname")
if [ -z "$WAN6_INTERFACE" ] || [ ! -e "/sys/class/net/$WAN6_INTERFACE/" ] ; then
logger -t NAT6 "Fatal error: Lookup of $WAN6_NAME interface failed. Were the default interface names changed?" && exit 1
fi
WAN6_GATEWAY=$(route -A inet6 -e | grep "$WAN6_INTERFACE" | awk '/::\/0/{print $2; exit}')
if [ -z "$WAN6_GATEWAY" ] ; then
logger -t NAT6 "Fatal error: No IPv6 gateway for $WAN6_INTERFACE found" && exit 1
fi
LAN_ULA_PREFIX=$(uci get network.globals.ula_prefix)
if [ $(echo "$LAN_ULA_PREFIX" | grep -c -E "^([0-9a-fA-F]{4}):([0-9a-fA-F]{0,4}):") -ne 1 ] ; then
logger -t NAT6 "Fatal error: IPv6 ULA prefix $LAN_ULA_PREFIX seems invalid. Please verify that a prefix is set and valid." && exit 1
fi
ip6tables -t nat -I POSTROUTING -s "$LAN_ULA_PREFIX" -o "$WAN6_INTERFACE" -j MASQUERADE
if [ $? -eq 0 ] ; then
logger -t NAT6 "Added IPv6 masquerading rule to the firewall (Src: $LAN_ULA_PREFIX - Dst: $WAN6_INTERFACE)"
else
logger -t NAT6 "Fatal error: Failed to add IPv6 masquerading rule to the firewall (Src: $LAN_ULA_PREFIX - Dst: $WAN6_INTERFACE)" && exit 1
fi
route -A inet6 add 2000::/3 gw "$WAN6_GATEWAY" dev "$WAN6_INTERFACE"
if [ $? -eq 0 ] ; then
logger -t NAT6 "Added $WAN6_GATEWAY to routing table as gateway on $WAN6_INTERFACE for outgoing connections"
else
logger -t NAT6 "Error: Failed to add $WAN6_GATEWAY to routing table as gateway on $WAN6_INTERFACE for outgoing connections"
fi
if [ $PRIVACY -eq 1 ] ; then
echo 2 > "/proc/sys/net/ipv6/conf/$WAN6_INTERFACE/accept_ra"
if [ $? -eq 0 ] ; then
logger -t NAT6 "Accepting router advertisements on $WAN6_INTERFACE even if forwarding is enabled (required for temporary addresses)"
else
logger -t NAT6 "Error: Failed to change router advertisements accept policy on $WAN6_INTERFACE (required for temporary addresses)"
fi
echo 2 > "/proc/sys/net/ipv6/conf/$WAN6_INTERFACE/use_tempaddr"
if [ $? -eq 0 ] ; then
logger -t NAT6 "Using temporary addresses for outgoing connections on interface $WAN6_INTERFACE"
else
logger -t NAT6 "Error: Failed to enable temporary addresses for outgoing connections on interface $WAN6_INTERFACE"
fi
fi
exit 0
}
网友评论