使用 OpenVPN 将 HE Tunnel Broker 的 IPv6 搬回家

ipv6google

之前我们已经给 VPS 配置好了 HE Tunnel Broker 提供的 IPv6 地址,但是这 2^80 个 IPv6 地址都放在服务器上有些太浪费了,为何不弄到家里电脑来,让家里电脑也可以使用 IPv6 呢?等着国内运营商提供 IPv6 恐怕得猴年马月了吧?

Google 了一下,使用 OpenVPN Tunnel 可以轻松完成这个工作,有两种方法:第一种是用 tap 模式建立网桥,服务器端运行 radvd 给客户端分配 IPv6 地址并作路由。第二种使用 sit 设备,不需要配置服务,但是需要客户端做相应的绑定。我选择第二种,主要是想将 OpenVPN 维持在 tun 模式。

基本思路是根据给客户端分配的内部 IPv4 地址的最后一位(X)在服务器端(在 Debian / Ubuntu 测试通过)起一个 sitX 设备,并且绑定 2001:1111:2222:X::1 这个地址,同时客户端(我这里是 Mac OS X,Windows / Linux 也可以分别使用批处理 / Bash 脚本调用 ip 命令搞定) gif 设备绑定 2001:1111:2222:X::2,并将默认路由设置为 2001:1111:2222:X::1,从而实现 IPv6 通路。下面是简单的设置过程和脚本文件:

服务器端设置:

vi /etc/openvpn/server.conf

最后加入:

script-security 2
client-connect /etc/openvpn/client-connect.sh
client-disconnect /etc/openvpn/client-disconnect.sh

编辑客户连接脚本

vi /etc/openvpn/client-connect.sh

内容:

#!/bin/bash

# This is a script that is run each time a remote client connects
# to this openvpn server.
# it will setup the ipv6 tunnel depending on the ip address that was
# given to the client

BASERANGE="2001:xxxx:xxxx"
# v6net is the last section of the ipv4 address that openvpn allocated
V6NET=$(echo ${ifconfig_pool_remote_ip} | awk -F. '{print $NF}')

SITID="sit${V6NET}"

# setup the sit between the local and remote openvpn addresses
sudo /sbin/ip tunnel add ${SITID} mode sit ttl 255 remote ${ifconfig_pool_remote_ip} local ${ifconfig_local}
sudo /sbin/ip link set dev ${SITID} up

# config routing for the new network
sudo /sbin/ip -6 addr add ${BASERANGE}:${V6NET}::1/64 dev ${SITID}
sudo /sbin/ip -6 route add ${BASERANGE}:${V6NET}::/64 via ${BASERANGE}:${V6NET}::2 dev ${SITID} metric 1

# log to syslog
echo "${script_type} client_ip:${trusted_ip} common_name:${common_name} local_ip:${ifconfig_local} \
remote_ip:${ifconfig_pool_remote_ip} sit:${SITID} ipv6net:${V6NET}" | /usr/bin/logger -t ovpn

客户断开脚本

vi /etc/openvpn/client-disconnect.sh

内容:

#!/bin/bash

# This is a script that is run each time a remote client disconnects
# to this openvpn server.

BASERANGE="2001:xxxx:xxxx"
# v6net is the last section of the ipv4 address that openvpn allocated
V6NET=$(echo ${ifconfig_pool_remote_ip} | awk -F. '{print $NF}')

SITID="sit${V6NET}"

sudo /sbin/ip -6 addr del ${BASERANGE}:${V6NET}::1/64 dev ${SITID}

# remove the sit between the local and:q

remote openvpn addresses
sudo /sbin/ip link set dev ${SITID} down
sudo /sbin/ip tunnel del ${SITID} mode sit ttl 255 remote ${ifconfig_pool_remote_ip} local ${ifconfig_local}

# log to syslog
echo "${script_type} client_ip:${trusted_ip} common_name:${common_name} local_ip:${ifconfig_local} \
remote_ip:${ifconfig_pool_remote_ip} sit:${SITID} ipv6net:${V6NET} duration:${time_duration} \
received:${bytes_received} sent:${bytes_sent}" | /usr/bin/logger -t ovpn

开启 IPv6 包转发:

sudo vi /etc/sysctl.conf

设置

net.ipv6.conf.all.forwarding=1

之后

sudo sysctl -p

客户端,编辑 client.conf,加入

up ./up.sh
down ./down.sh

如果选中了 Set nameserver 的话,这时候 TunnelBlick 在连接时就会调用

--up /Applications/Tunnelblick.app/Contents/Resources/client.up.tunnelblick.sh

从而造成 up ./up.sh 失败,所以我们不选 Set nameserver,然后将那个脚本并入我们自己的脚本中

up.sh 内容:

#!/bin/bash -e
bash /Applications/Tunnelblick.app/Contents/Resources/client.up.tunnelblick.sh -m -w -d

INTERFACE=$1; shift;
TUN_MTU=$1; shift;
UDP_MTU=$1; shift;
LOCAL_IP=$1; shift;
REMOTE_IP=$1; shift;
MODUS=$1; shift;

#script that is run on the client when it creates a tunnel to the remote OpenVPN server
IPV6BASE=2001:xxxx:xxxx

SERVER_IP=10.8.0.1

V6NET=$(echo ${LOCAL_IP} | cut -d. -f4)

GIFID="gif0"

sudo /sbin/ifconfig ${GIFID} tunnel ${LOCAL_IP} ${SERVER_IP}
sudo /sbin/ifconfig ${GIFID} inet6 ${IPV6BASE}:${V6NET}::2/64
sudo /sbin/route delete -inet6 default
sudo /sbin/route add -inet6 default ${IPV6BASE}:${V6NET}::1

exit 0

down.sh 内容

#!/bin/bash –e
INTERFACE=$1; shift;
TUN_MTU=$1; shift;
UDP_MTU=$1; shift;
LOCAL_IP=$1; shift;
REMOTE_IP=$1; shift;
MODUS=$1; shift;

# script that is run on the client when it creates a tunnel to the remote OpenVPN server
IPV6BASE=2001:xxxx:xxxx

SERVER_IP=10.8.0.1

V6NET=$(echo ${LOCAL_IP} | cut -d. -f4)

GIFID="gif0"

sudo /sbin/route delete -inet6 default
sudo /sbin/ifconfig ${GIFID} inet6 ${IPV6BASE}:${V6NET}::2 -alias
sudo /sbin/ifconfig ${GIFID} deletetunnel

bash /Applications/Tunnelblick.app/Contents/Resources/client.down.tunnelblick.sh -m -w -d --up-restart

exit 0

至此设置完毕,如果一切顺利的话以后再连接这个 OpenVPN 就可以在 gif0 上获取到 IPv6 地址了。

参考:Personal IPv6 Tunnel Broker with OpenVPN

This entry was posted in 我的工作学习, 电脑相关 and tagged , , , . Bookmark the permalink.

4 Responses to 使用 OpenVPN 将 HE Tunnel Broker 的 IPv6 搬回家

  1. tjmao says:

    脚本不错,话说/64换成/128也是可行的,这样不浪费。。

  2. Pingback: Tweets that mention 使用 OpenVPN 将 HE Tunnel Broker 的 IPv6 搬回家 | gkp's post -- Topsy.com

  3. Zeddicus says:

    学习了!不过还是等到牛年马月运营商给了IPV6再玩玩,赶绝这样有些折腾哈~

Leave a Reply

Your email address will not be published. Required fields are marked *


− 4 = two

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>