OpenVZ 架构 VPS 配置 IPv6 TunnelBroker

虽然现在 IPv6 尚未完全普及,但是作为一个本地有 IPv6 连接,盒子也是双栈 IP 的用户,双栈 VPS 对我来说也算是一个很有意义的特性。但是很多 Low End VPS 商家售卖的 OpenVZ VPS 并不提供 IPv6 地址,OpenVZ 架构也不像 KVM 一样可以方便地添加 TunnelBroker 实现双栈网络,因此便需要寻找其他的解决方案。

所幸并不是我一个人有这个需求,借助 tb_userspace 这个小工具,可以很快地完成这样的配置工作。记录配置过程如下:

  1. 在 tunnelbroker.net 创建一个新的 Regular Tunnel,取得 Server IPv4 Address 和 Client IPv4 Address 两个配置
  2. 下载 tb_userspace 源代码,编译。此时假设 tb_userspace 存放于 /root目录下
    wget https://down.gloriousdays.pw/Tools/tb_userspace.c
    gcc tb_userspace.c -l pthread -o tb_userspace
  3. 创建自启动脚本 /etc/init.d/ipv6tb
    #! /bin/sh
     
    ### BEGIN INIT INFO
    # Provides:          ipv6
    # Required-Start:    $local_fs $all
    # Required-Stop:     $local_fs $network
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Short-Description: starts the ipv6 tunnel 
    # Description:       ipv6 tunnel start-stop-daemon
    ### END INIT INFO
     
    # /etc/init.d/ipv6tb
     
    touch /var/lock/ipv6tb
     
    case "$1" in
      start)
        echo "Starting ipv6tb "
          setsid /root/tb_userspace tb <Server IPv4 Address> <Client IPv4 Address> sit > /dev/null 2>&1 &
          sleep 3s #ugly, but doesn't seem to work at startup otherwise
          ifconfig tb up
          ifconfig tb inet6 add <Client IPv6 Address from your Routed /64> ::XXX/128 #Add as many of these as you need from your routed /64 allocation
          ifconfig tb mtu 1480
          route -A inet6 add ::/0 dev tb
          route -A inet6 del ::/0 dev venet0
        ;;
      stop)
        echo "Stopping ipv6tb"
          ifconfig tb down
          route -A inet6 del ::/0 dev tb
          killall tb_userspace
        ;;
      *)
        echo "Usage: /etc/init.d/ipv6tb {start|stop}"
        exit 1
        ;;
    esac
     
    exit 0
    
    
    chmod 0755 /etc/init.d/ipv6tb
    update-rc.d ipv6tb defaults #May cause problems, explain later
  4. Ubuntu 16.04 (systemd) 的额外配置
    如果是使用 Upstart 的 Ubuntu 版本,使用 update-rc.d 就可以创建相应的启动项,但是在某些 Ubuntu 16.04 上,如 HostDare 的 VPS,update-rc.d 在将 SysVinit 脚本做一个 wrapper 以后产生的 Systemd 自启动脚本并不能正常工作。经过排查,发现这个问题产生于 Systemd 脚本的 Type 问题,ipv6tb 应给以 Forking 方式启动,而不是默认的 Simple 模式,如果按照默认模式启动,就会莫名其妙地卡住。因此,如果在 Ubuntu 16.04 上配置,不应该使用 update-rc.d 方式创建 Systemd Wrapped SysVinit 脚本,而应该自己在 /etc/systemd/system 里写一个脚本。

    [Unit]
    Description=ipv6tb
    After=network-online.target
    
    [Service]
    Type=forking
    ExecStart=/usr/bin/sudo /etc/init.d/ipv6tb start
    ExecStop=/usr/bin/sudo /etc/init.d/ipv6tb stop
    Restart=always
    
    [Install]
    WantedBy=multi-user.target

之后执行 systemctl enable ipv6tb.service 就可以正常使用了。

发表评论

电子邮件地址不会被公开。