先普及一下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了。

comments powered by Disqus