Running an OpenVPN server on Ubuntu with dual stack IPv6
Where should I start? It took considerable amount of time to find my way and a lot of research to make it work, but at the end I succeeded. A well working OpenVPN server running on Ubuntu 24 with IPv6 support hosted at a VPS provider. Created my own self signed certificates, used dual stack at both sides (server and client) and decided that I only use one IP IPv6 address as I haven't succeeded in allocating addresses to the OpenVPN clients. Small price I decided to pay.
As I'm making these notes days after I've made it, there might be some discrepancies or missing steps, let me know if that's the case.
-
Sudo yourself
-
Install openvpn and easyrsa
apt install openvpn easy-rsa
-
Create CA store and the main certificates (I chose to put the CA files into the home of root for safety reasons). Obviously you need to change {{SERVER-NAME}} into something meaningful.
make-cadir /root/easy-rsa cd /root/easy-rsa ./easyrsa init-pki ./easyrsa build-ca ./easyrsa gen-req {{SERVER-NAME}} nopass ./easyrsa gen-dh ./easyrsa sign-req server {{SERVER-NAME}}
-
Copy certificates to the openvpn config folder
cp pki/dh.pem pki/ca.crt pki/issued/{{SERVER-NAME}}.crt pki/private/{{SERVER-NAME}}.key /etc/openvpn/
-
Create certificate for the (first) VPN user. You don't need to copy these files, you'll only need them present on the client, so you can remove these files if you like - after going through all the steps.
./easyrsa gen-req {{VPN-USERNAME}} nopass ./easyrsa sign-req client {{VPN-USERNAME}}
-
Make sure the user above ({{VPN-USERNAME}}) is a valid unix user, if not, you can create it:
adduser {{VPN-USERNAME}}
-
Create tls-auth key which I decided to use to harden my VPN server
openvpn --genkey secret ta.key cp ta.key /etc/openvpn/
-
Add unprivileged user for OpenVPN
adduser --system openvpn
-
Create OpenVPN config file, I used the following one for myself. Save it as /etc/openvpn/{{SERVER-NAME}}.conf
port 1194 # Port where OpenVPN listens proto udp # As above but the protocol dev tun ca ca.crt # CA file you created/copied cert {{SERVER-NAME}}.crt # Server you created/copied, change the name to what you've chosen key {{SERVER-NAME}}.key # Server's private key which you created/copied, change the name to what you've chosen dh dh.pem topology subnet ifconfig-pool-persist /var/log/openvpn/ipp.txt keepalive 10 120 tls-auth ta.key 0 user openvpn group nogroup persist-key persist-tun status /var/log/openvpn/openvpn-status.log verb 3 explicit-exit-notify 1 server 10.8.0.0 255.255.255.0 # IPv4 range server-ipv6 fd00:1234:abcd::/64 # IPv6 range push "route-ipv6 2000::/3" # Route all IPv6 traffic into the tunnel push "redirect-gateway ipv6" # see above push "redirect-gateway def1 bypass-dhcp" # Route all IPv4 traffic into the tunnel tun-ipv6 # Make tunnel ipv6 aware tun-mtu 1400 # Otherwise you'll have a lot of trouble with Windows clients mssfix 1360 # see above
-
Make the OpenVPN server start together with the server, edit the /etc/default/openvpn file, and uncomment the AUTOSTART="all" line
-
Restart OpenVPN service so we're sure the new service is running.
systemctl restart openvpn
-
Allow the forwarding of IPv4 and IPv6 packets in the kernel. Edit the /etc/sysctl.d/99-sysctl.conf file and add the following lines at the end or change their values if they're already present:
net.ipv6.conf.all.forwarding = 1 net.ipv4.ip_forward=1
Make the system pick up the new values
sysctl -p
-
Enable the port above to pass through the firewall, in case of ufw:
ufw allow 1194/udp
-
Find the name of your WAN facing ethernet interface (from ip addr for example) and allow routing between your tunnel and WAN adapter:
ufw route allow in on tun0 out on {{YOUR-ETH-INTERFACE}}
-
Add NAT masquerade to the ufw to translate the VPN client's IPv4 address into your WAN IPv4 address and back. Edit the /etc/ufw/before.rules file, add either at the top or the bottom the following:
# START OPENVPN RULES # NAT table rules *nat :POSTROUTING ACCEPT [0:0] -A POSTROUTING -s 10.8.0.0/24 -o {{YOUR-ETH-INTERFACE}} -j MASQUERADE COMMIT # END OPENVPN RULES
-
Add the same, but for IPv6. The file you'll need is /etc/ufw/before6.rules and you have to put the following text at the very top or at the very end (again).
# START OPENVPN RULES # NAT table rules *nat :POSTROUTING ACCEPT [0:0] -A POSTROUTING -s fd00:1234:abcd::/64 -o {{YOUR-ETH-INTERFACE}} -j MASQUERADE COMMIT # END OPENVPN RULES
-
Restart ufw:
ufw disable ufw enable
-
Configure the OpenVPN client, you'll need the server's public IPv4 address, the linux username you dedicated to VPN use (can be your already exising user as well) and the corresponding password and the following files:
/etc/openvpn/ta.key /root/easy-rsa/pki/ca.crt /root/easy-rsa/pki/private/{{VPN-USERNAME}}.key /root/easy-rsa/pki/issued/{{VPN-USERNAME}}.crt
I've used the following config file for the client:
client dev tun remote {{YOUR-SERVERS-IP-ADDRESS}} 1194 udp nobind tls-client key-direction 1 ping 15 ping-restart 45 persist-tun persist-key mute-replay-warnings verb 3 pull auth-user-pass connect-retry 1 reneg-sec 3600 remote-cert-tls server redirect-gateway def1 <ca> {{CONTENTS-OF:/root/easy-rsa/pki/ca.crt}} </ca> <cert> {{CONTENTS-OF:/root/easy-rsa/pki/issued/{{VPN-USERNAME}}.crt}} </cert> <key> {{CONTENTS-OF:/root/easy-rsa/pki/private/{{VPN-USERNAME}}.key}} </key> <tls-auth> {{CONTENTS-OF:/etc/openvpn/ta.key}} </tls-auth>
Save this file on the computer which you'll use as a client and import it into your favorite OpenVPN client.
That might be it! Attempt to make a connection, when asked for the username and password you will have to use the credentials you created.
Test your connectivity on http://ip4.me/ and https://ip6only.me/,
both of these should show you your server's IPv4 and IPv6 addresses.
If you run into errors, you can consult the journal, check the routing tables or leave a comment here so I can learn something too.
Don't know what will come here, let's wait and see... But in the first instance it will be a login box (for myself):
Leave a comment
Comments (if any)