LiuSY

校园网配置IPv6
许多大学里,校园网都是IPv4+IPv6双栈,大多数同学都通过IPv4上网,在校园使用过甚至听说过IPv6的少之又...
扫描右侧二维码阅读全文
24
2019/03

校园网配置IPv6

许多大学里,校园网都是IPv4+IPv6双栈,大多数同学都通过IPv4上网,在校园使用过甚至听说过IPv6的少之又少。有的学校甚至没有计走IPv6的流量费(然而我们学校并不是这种制度),所以你可以用它免流。同时各大高校也有IPv6的PT站。而路由器接入校园网后只有路由上有IPv6地址,子网的设备并不能通过IPv6上网。

前言

下面介绍一下如何使子网设备获取IPv6地址,并通过IPv6上网。这篇介绍的是nat6方式(缺点:子网设备获得的是内网IPv6地址,对PT等做种不友好)。在IPv6地址如此充足的情况下,NAT算是歪门邪道。

NAT百科:

NAT英文全称是“Network Address Translation”,中文意思是“网络地址转换”,它是一个IETF(Internet Engineering Task Force, Internet工程任务组)标准,允许一个整体机构以一个公用IP(Internet Protocol)地址出现在Internet上。顾名思义,它是一种把内部私有网络地址(IP地址)翻译成合法网络IP地址的技术,如下图所示。因此我们可以认为,NAT在一定程度上,能够有效的解决公网地址不足的问题。
img

准备和需求

  • 已知自己能够获得IPv6地址
  • 基于Openwrt系统的路由器(尽量是官网原版,魔改版一般由于内核依赖等无法安装其他软件包)
  • 能通过SSH连接路由器终端的设备:电脑或者手机都可以

开始配置

将以下命令依次在SSH中运行

opkg update && opkg install kmod-ipt-nat6
uci set network.globals.ula_prefix="$(uci get network.globals.ula_prefix | sed 's/^./d/')" 
uci commit network
uci set dhcp.lan.ra_default='1' 
uci commit dhcp
touch /etc/init.d/nat6
vi /etc/init.d/nat6

进入vi编辑器之后,将下面的全部代码贴进去,保存。

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=5

# 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
}


然后回到SSH

chmod +x /etc/init.d/nat6 
/etc/init.d/nat6 enable
uci set firewall.@rule["$(uci show firewall | grep 'Allow-ICMPv6-Forward' | cut -d'[' -f2 | cut -d']' -f1)"].enabled='0' 
uci commit firewall

然后修改/etc/sysctl.conf,新版的Openwrt貌似不在这,自己找一下,vi /etc/sysctl.conf添加如下几行

net.ipv6.conf.default.forwarding=2
net.ipv6.conf.all.forwarding=2
net.ipv6.conf.default.accept_ra=2
net.ipv6.conf.all.accept_ra=2

最后设置防火墙ip6tables -t nat -I POSTROUTING -s $(uci get network.globals.ula_prefix) -j MASQUERADE

检查是否成功

重启路由器,稍等路由器获取到IPv6地址,用手机等设备连接路由器,能获得一个dd开头的内网地址。img再去 http://test-ipv6.com 测试一下,基本就没什么问题了。img

最后修改:2019 年 04 月 24 日 10 : 48 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论