先普及一下IPv6 地址。
IPv6 地址大小为 128 位。首选 IPv6 地址表示法为 x:x:x:x:x:x:x:x,其中每个 x 是地址的 8 个 16 位部分的十六进制值。IPv6 地址范围从 0000:0000:0000:0000:0000:0000:0000:0000 至 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff。
除此首选格式之外,IPv6 地址还可以用其他两种短格式指定:
省略前导零
通过省略前导零指定 IPv6 地址。
例如,IPv6 地址 1050:0000:0000:0000:0005:0600:300c:326b 可写作 1050:0:0:0:5:600:300c:326b。双冒号
通过使用双冒号(::)替换一系列零来指定 IPv6 地址。
例如,IPv6 地址 ff06:0:0:0:0:0:0:c3 可写作 ff06::c3。
一个 IP 地址中只可使用一次双冒号。
在一般IPv6网络环境下,一个局域网的子网大小为/64,接口通过NDP协议获得自己的唯一IPv6地址(前64位为子网前缀,后64位一般由接口本身的MAC地址产生)
我们的场景:
- 服务器的IPV4地址是 1.2.3.4
- 服务器的IPV6地址是 aaaa:bbbb:cccc:dddd::/64
- IPV4和IPV6的地址都在eth0上
- VPN分配给客户端的IPV6地址是aaaa:bbbb:cccc:dddd:80::/112,使用的接口是tun0
配置过程如下:
首先修改/etc/sysctl.conf
文件
net.ipv4.ip_forward=1
...
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.proxy_ndp = 1
...
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
...
net.ipv4.conf.all.send_redirects = 0
接下来,可以先做iptable,使得openvpn server对包进行SNAT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
或者
iptables -t nat -A POSTROUTING -s 10.11.0.0/16 -j SNAT --to 172.16.8.1
编辑/etc/openvpn/variables
变量
# 客户端IP段前缀
# Tunnel subnet prefix
prefix=aaaa:bbbb:cccc:dddd:80:
# netmask
prefixlen=112
准备两个脚本,在与客户端建立连接和断开连接时执行,用来建立或者取消NDP proxy rules。 /etc/openvpn/up.sh
#!/bin/sh
# Check client variables
if [ -z "$ifconfig_pool_remote_ip" ] || [ -z "$common_name" ]; then
echo "Missing environment variable."
exit 1
fi
# Load server variables
. /etc/openvpn/variables
ipv6=""
ipp=$(echo "$ifconfig_pool_remote_ip" | cut -d. -f4)
if ! [ "$ipp" -ge 2 -a "$ipp" -le 254 ] 2>/dev/null; then
echo "Invalid IPv4 part."
exit 1
fi
hexipp=$(printf '%x' $ipp)
ipv6="$prefix$hexipp"
# Create proxy rule
/sbin/ip -6 neigh add proxy $ipv6 dev eth0
/etc/openvpn/down.sh
#!/bin/sh
# Check client variables
if [ -z "$ifconfig_pool_remote_ip" ] || [ -z "$common_name" ]; then
echo "Missing environment variable."
exit 1
fi
# Load server variables
. /etc/openvpn/variables
ipv6=""
ipp=$(echo "$ifconfig_pool_remote_ip" | cut -d. -f4)
if ! [ "$ipp" -ge 2 -a "$ipp" -le 254 ] 2>/dev/null; then
echo "Invalid IPv4 part."
exit 1
fi
hexipp=$(printf '%x' $ipp)
ipv6="$prefix$hexipp"
# Delete proxy rule
/sbin/ip -6 neigh del proxy $ipv6 dev eth0
这两个脚本权限应该都是755
服务器端server.conf中的相关配置:
# Run client-specific script on connection and disconnection
script-security 2
client-connect "/etc/openvpn/up.sh"
client-disconnect "/etc/openvpn/down.sh"
# Server mode and client subnets
server 10.8.0.0 255.255.255.0
server-ipv6 aaaa:bbbb:cccc:dddd:80::/112
topology subnet
# IPv6 routes
push "route-ipv6 aaaa:bbbb:cccc:dddd::/64"
push "route-ipv6 2000::/3"
客户端client.ovpn中的相关配置
remote 1.2.3.4 1194
启动服务器端,然后再启动客户端连接 测试一下:
traceroute6 ipv6.google.com
这样就ok了。