OpenWrt上开启NAT6为内网提供IPv6支持

我的博客: 菱歌'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配置

  1. 安装所需支持,事实上许多OpenWrt系统没有安装odhcpdodhcp6c,前者在这里用于内网v6地址的分配,而后者作为路由器获取外网v6地址的客户端。
    opkg update && opkg install kmod-ipt-nat6 odhcpd odhcp6c
    
  2. 更改内网IPv6 ULA 前缀,也可以再Luci界面中操作,将首位的f改为d,这样问题少些。
    uci set network.globals.ula_prefix="$(uci get network.globals.ula_prefix | sed 's/^./d/')"
    uci commit network
    
  3. 设置LAN口dhcp
    uci set dhcp.lan.ra_default='1'
    uci commit dhcp
    
  4. 新建NAT6服务,内容见NAT6
    touch /etc/init.d/nat6
    vi /etc/init.d/nat6
    
  5. 启动NAT6服务
    chmod +x /etc/init.d/nat6
    /etc/init.d/nat6 enable
    
  6. /etc/firewall.user中添加转发规则,否则内网v6流量不能被转发。
    ip6tables -t nat -A POSTROUTING -o eth0.2 -j MASQUERADE
    
  7. 重启路由器
  8. (可选)为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
}

你可能感兴趣的:(OpenWrt上开启NAT6为内网提供IPv6支持)