先普及一下IPv6 地址。
IPv6 地址大小为 128 位。
首选 IPv6 地址表示法为8组数字用冒号分隔,其中每组是 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
文件
1net.ipv4.ip_forward=1
2 ...
3net.ipv6.conf.all.forwarding=1
4net.ipv6.conf.all.proxy_ndp = 1
5 ...
6net.ipv4.conf.all.accept_redirects = 0
7net.ipv6.conf.all.accept_redirects = 0
8 ...
9net.ipv4.conf.all.send_redirects = 0
接下来,可以先做iptable,使得openvpn server对包进行SNAT
1iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
2或者
3iptables -t nat -A POSTROUTING -s 10.11.0.0/16 -j SNAT --to 172.16.8.1
编辑/etc/openvpn/variables
变量
1# 客户端IP段前缀
2# Tunnel subnet prefix
3prefix=aaaa:bbbb:cccc:dddd:80:
4# netmask
5prefixlen=112
准备两个脚本,在与客户端建立连接和断开连接时执行,用来建立或者取消NDP proxy rules。 /etc/openvpn/up.sh
1#!/bin/sh
2
3# Check client variables
4if [ -z "$ifconfig_pool_remote_ip" ] || [ -z "$common_name" ]; then
5 echo "Missing environment variable."
6 exit 1
7fi
8
9# Load server variables
10. /etc/openvpn/variables
11
12ipv6=""
13
14ipp=$(echo "$ifconfig_pool_remote_ip" | cut -d. -f4)
15if ! [ "$ipp" -ge 2 -a "$ipp" -le 254 ] 2>/dev/null; then
16 echo "Invalid IPv4 part."
17 exit 1
18fi
19hexipp=$(printf '%x' $ipp)
20ipv6="$prefix$hexipp"
21
22# Create proxy rule
23/sbin/ip -6 neigh add proxy $ipv6 dev eth0
/etc/openvpn/down.sh
1#!/bin/sh
2
3# Check client variables
4if [ -z "$ifconfig_pool_remote_ip" ] || [ -z "$common_name" ]; then
5 echo "Missing environment variable."
6 exit 1
7fi
8
9# Load server variables
10. /etc/openvpn/variables
11
12ipv6=""
13
14ipp=$(echo "$ifconfig_pool_remote_ip" | cut -d. -f4)
15if ! [ "$ipp" -ge 2 -a "$ipp" -le 254 ] 2>/dev/null; then
16 echo "Invalid IPv4 part."
17 exit 1
18fi
19hexipp=$(printf '%x' $ipp)
20ipv6="$prefix$hexipp"
21
22# Delete proxy rule
23/sbin/ip -6 neigh del proxy $ipv6 dev eth0
这两个脚本权限应该都是755
服务器端server.conf中的相关配置:
1# Run client-specific script on connection and disconnection
2script-security 2
3client-connect "/etc/openvpn/up.sh"
4client-disconnect "/etc/openvpn/down.sh"
5
6# Server mode and client subnets
7server 10.8.0.0 255.255.255.0
8server-ipv6 aaaa:bbbb:cccc:dddd:80::/112
9topology subnet
10
11# IPv6 routes
12push "route-ipv6 aaaa:bbbb:cccc:dddd::/64"
13push "route-ipv6 2000::/3"
客户端client.ovpn中的相关配置
1remote 1.2.3.4 1194
启动服务器端,然后再启动客户端连接 测试一下:
1 traceroute6 ipv6.google.com
这样就ok了。