Apr 24

route ipv6 /64 via openvpn

Although many believe splitting up a /64 net shouldn't be done at all, you sometimes don't have a choice. Say you did get a /64 network from your serverhoster and you want to use it to get native ipv6 to every client in your vpn.

Here you go, for this example we use feed:dead:beef:affe/64 as our basenet :) Every client gets a /80 subnet, feel free to adjust

Server side config:
Just a basic openvpn server config with the three scripts from below linked.
server.conf
port 1195
proto udp
dev tap
ca ca.crt
cert mondialu.crt
key mondialu.key
tls-auth ta.key 0
dh dh2048.pem
server 10.23.1.0 255.255.255.0
script-security 2
up /etc/openvpn/server-up.sh
client-connect /etc/openvpn/client-connect.sh
client-disconnect /etc/openvpn/client-disconnect.sh
ifconfig-pool-persist ipp.txt
keepalive 10 120
comp-lzo
user vpn
group vpn
persist-key
persist-tun
status openvpn-status.log
verb 3

Bring up the routing and neighbor proxy.

server-up.sh
#!/bin/sh
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
echo 1 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp

Add the /80 to the interface and set the appropriate route. Add the new network to the neighbor proxy table.
client-connect.sh
#!/bin/bash
BASERANGE="feed:dead:beef:affe"
V6NET=$(echo ${ifconfig_pool_remote_ip} | awk -F. '{print $NF}')
# config routing for the new network
sudo /sbin/ip -6 addr add ${BASERANGE}:${V6NET}::1/80 dev $dev
sudo /sbin/ip -6 route add ${BASERANGE}:${V6NET}::/80 via ${BASERANGE}:${V6NET}::2 dev ${dev} metric 1
# add neighbor
sudo /sbin/ip -6 neigh add proxy ${BASERANGE}:${V6NET}::2 dev eth0
# 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

Tear everything down.

client-disconnect.sh
#!/bin/bash
BASERANGE="feed:dead:beef:affe"
V6NET=$(echo ${ifconfig_pool_remote_ip} | awk -F. '{print $NF}')
sudo /sbin/ip -6 addr del ${BASERANGE}:${V6NET}::1/80 dev ${dev}
# 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

client config

Typical openvpn client config.

client.conf
dev tap
proto udp
remote your.hostname.de 1195
script-security 2
cert mondialu-maya.crt
key mondialu-maya.key
ca mondialu-ca.crt
tls-auth /etc/openvpn/mondialu-ta.key 1
ping 10
ping-restart 60
up /etc/openvpn/mondialu-up.sh
down /etc/openvpn/mondialu-down.sh
client
resolv-retry infinite
nobind
user nobody
group nobody
persist-key
persist-tun
ns-cert-type server
comp-lzo

After we're connected setup the ipv6 address and default route.

mondialu-up.sh
#!/bin/bash
# script that is run on the client when it creates a tunnel to the remote OpenVPN server
IPV6BASE=feed:dead:beef:affe
V6NET=$(echo ${ifconfig_local} | awk -F. '{print $NF}')
/sbin/ip -6 addr add ${IPV6BASE}:${V6NET}::2/80 dev $dev
/sbin/ip route add ::/0 via ${IPV6BASE}:${V6NET}::1
exit 0

Tear everything down when we go down.

mondialu-down.sh
#!/bin/bash
IPV6BASE=feed:dead:beef:affe
V6NET=$(echo ${ifconfig_local} | awk -F. '{print $NF}')
sudo /sbin/ip -6 addr del ${IPV6BASE}:${V6NET}:2/80 dev $dev
sudo /sbin/ip route del ::/0 via ${IPV6BASE}:${V6NET}:1
exit 0

Share