[网络] 为阿里云 CentOS 6.x 添加 IPV6 支持

好吧,阿里云的公开CentOS 镜像将 IPV6 支持给去掉了,即使你按照网络上的教程,启用 /etc/sysconfig/network 中的 NETWORKING_IPV6 也没啥用,反正它就是不加载 IPV6 的相关模块。经过一番近乎绝望的折腾之后,终于搞定了。

我们首入进入 /etc/sysconfig/modules,然后创建一个脚本,我这里叫 ipv6.modules,然后编辑其内容如下:

#!/bin/sh
if [ ! -c /proc/net/if_inet6 ] ; then
  exec /sbin/insmod /lib/modules/`uname -r`/kernel/net/ipv6/ipv6.ko
fi

这样就可以让操作系统在启动时自动加载 IPV6 模块了,重启机器测试下,看看 lsmod 是否能找到 ipv6,找到就说明加载上了。

然后我们要为自己的服务器获取一个 IPV6 的地址,我们可以在 tunnelbroker.net 上申请一个免费的 IPV6 地址:

  1. 访问 tunnelbroker.net 注册一个自己的账号;
  2. 选择 Create Regular Tunnel 创建一个到自己公网 IP 的通道。
  3. 找到 Example Configurations 里,找到自己操作系统对应的脚本,CentOS 6.x 选择 Linux-route2,然后将脚本复制下来,在 linux 的控制台中执行脚本。
  4. ifconfig 看一下 IPV6 地址是否配置成功,配置成功的话,可以看到类似下面的内容:
    he-ipv6   Link encap:IPv6-in-IPv4
              inet6 addr: 你的全局IPv6地址/64 Scope:Global
              inet6 addr: fe80::731c:4992/128 Scope:Link
              UP POINTOPOINT RUNNING NOARP  MTU:1480  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0
              RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
  5. 现在你可以 ping 一下服务器的地址,看看 IPv6 是否工作正常(Linux 下IPv6 版的 ping 名为 ping6),如果通了就说明可以了:
    ping6 2001:470:18:ced::1
    PING 2001:470:18:ced::1(2001:470:18:ced::1) 56 data bytes
    64 bytes from 2001:470:18:ced::1: icmp_seq=1 ttl=64 time=340 ms
    64 bytes from 2001:470:18:ced::1: icmp_seq=2 ttl=64 time=348 ms
    64 bytes from 2001:470:18:ced::1: icmp_seq=3 ttl=64 time=349 ms

好了,现在看起来一切工作正常,不过问题来了,如果我们重新启动,使用 ifconfig 看一下,就会发现 he-ipv6 这个接口没有了,所以我们还需要做点处理,让系统每次自动执行我们复制下来的脚本。

我们修改 /etc/init.d/network 中的脚本,在 start) 的末尾加上我们复制的内容,大概结果如下:

case "$1" in
  start)
        [ "$EUID" != "0" ] && exit 4
        rc=0
        # IPv6 hook (pre IPv4 start)
        if [ -x /etc/sysconfig/network-scripts/init.ipv6-global ]; then
                /etc/sysconfig/network-scripts/init.ipv6-global start pre
        fi

        apply_sysctl

        # bring up loopback interface
        action $"Bringing up loopback interface: " ./ifup ifcfg-lo

        case "$VLAN" in
          yes)
            if [ ! -d /proc/net/vlan ] && ! modprobe 8021q >/dev/null 2>&1 ; then
                net_log $"No 802.1Q VLAN support available in kernel."
            fi
            ;;
        esac

        vlaninterfaces=""
        xdslinterfaces=""
        bridgeinterfaces=""

        # bring up all other interfaces configured to come up at boot time
        for i in $interfaces; do
                unset DEVICE TYPE SLAVE
                eval $(LANG=C fgrep "DEVICE=" ifcfg-$i)
                eval $(LANG=C fgrep "TYPE=" ifcfg-$i)
                eval $(LANG=C fgrep "SLAVE=" ifcfg-$i)

                if [ -z "$DEVICE" ] ; then DEVICE="$i"; fi

                if [ "$SLAVE" = "yes" ]; then
                        continue
                fi

                if [ "$TYPE" = "xDSL" ]; then
                        xdslinterfaces="$xdslinterfaces $i"
                        continue
                fi

                if [ "$TYPE" = "Bridge" ]; then
                        bridgeinterfaces="$bridgeinterfaces $i"
                        continue
                fi

                if [ "${DEVICE%%.*}" != "$DEVICE"  -o  "${DEVICE##vlan}" != "$DEVICE" ] ; then
                        vlaninterfaces="$vlaninterfaces $i"
                        continue
                fi

                if LANG=C egrep -L "^ONBOOT=['\"]?[Nn][Oo]['\"]?" ifcfg-$i > /dev/null ; then
                        # this loads the module, to preserve ordering
                        is_available $i
                        continue
                fi
                # If we're in confirmation mode, get user confirmation.
                if [ -f /var/run/confirm ]; then
                        confirm $i
                        test $? = 1 && continue
                fi
                action $"Bringing up interface $i: " ./ifup $i boot
                [ $? -ne 0 ] && rc=1
        done

        # Bring up xDSL and VPN interfaces
        for i in $vlaninterfaces $bridgeinterfaces $xdslinterfaces ; do
            if ! LANG=C egrep -L "^ONBOOT=['\"]?[Nn][Oo]['\"]?" ifcfg-$i >/dev/null 2>&1 ; then
                # If we're in confirmation mode, get user confirmation.
                if [ -f /var/run/confirm ]; then
                        confirm $i
                        test $? = 1 && continue
                fi
                action $"Bringing up interface $i: " ./ifup $i boot
                [ $? -ne 0 ] && rc=1
            fi
        done


        # Add non interface-specific static-routes.
        if [ -f /etc/sysconfig/static-routes ]; then
           grep "^any" /etc/sysconfig/static-routes | while read ignore args ; do
              /sbin/route add -$args
           done
        fi
        # Add non interface-specific static arp entries.
        if [ -f /etc/ethers ]; then
                /sbin/arp -f /etc/ethers
        fi

        # IPv6 hook (post IPv4 start)
        if [ -x /etc/sysconfig/network-scripts/init.ipv6-global ]; then
                /etc/sysconfig/network-scripts/init.ipv6-global start post
        fi
        # Run this again to catch any interface-specific actions
        apply_sysctl

        # 添加 IPv6 脚本支持       
        ip tunnel add he-ipv6 mode sit remote 216.218.221.6 local 你本机的外网IP ttl 255
        ip link set he-ipv6 up
        ip addr add 分配给你的IPv6地址/64 dev he-ipv6
        ip route add ::/0 dev he-ipv6
        ip -f inet6 addr
        # 修改结束

        touch /var/lock/subsys/network

        [ -n "${NETWORKDELAY}" ] && /bin/sleep ${NETWORKDELAY}
        ;;

好了,现在每次重启机器都可以自动分配好IP V6 地址了。那么接下来的问题就是为你的服务器域名解析IPv6 地址,国内的域名服务商许多不提供 AAAA 解析,不过 DNSPod 支持,所以你可以将你自己的 DNS 解析服务器切换到 DNSPod,从而提供 IPv6 的 DNS 解析支持。譬如:

C:\Users\swish>nslookup ddb.b86400.com
服务器:  UnKnown
Address:  10.1.1.1

非权威应答:
名称:    ddb.b86400.com
Addresses:  2001:470:18:cec::2
          218.60.14.203

我们可以看到它就有了一个 IPv6 的地址。

分享到: