How to prevent IPv6 leak with an OpenVPN client on GNU Linux?

You might want to use a VPN, so that you can browse the Internet from another location, but your ISP provides an IPv6 network which could route traffic differently than an ISP with only IPv4 connectivity.

How to prevent IPv6 leak with an OpenVPN client on GNU Linux?
Photo by Franck / Unsplash

You might want to use a VPN, so that you can browse the Internet from another location, but your ISP provides an IPv6 network which could route traffic differently than an ISP with only IPv4 connectivity.

This can be done by setting up your VPN connection on an IPv6-only network. Since the ISP does not provide IPv4 addresses to its customers, there is no way to connect through it with a standard VPN configuration. But not all customers have a luxury to work in IPv6-only network.

If you're subscribed to an internet service provider (ISP) that has IPv6 connectivity, you will have to block it in order to prevent leaks and enjoy uninterrupted access to US-based streaming services like Hulu, Netflix or Amazon Prime.

Configuring this VPN setup is easy in any GNU/Linux distribution of your choice, and we recommend the following two methods:

  • option –block-ipv6 available in OpenVPN 2.5.x and never
  • up and down scripts available in all OpenVPN versions

Option –block-ipv6

This method should work fine for all OpenVPN version 2.5.x clients on all major operating systems including our favorite GNU/Linux, macOS and Windows. The free OpenVPN client for Android has already included this option by default in all versions, including 6 and higher.

You can upgrade to the latest OpenVPN version using the official repo on the OpenVPN website, no matter which version of your Operating System you're currently running — it's available for Debian, Ubuntu, Fedora, CentOS and Red Hat Enterprise Linux, so there is absolutely no reason not update if you use OpenVPN software. We will guide you step by step.

  1. Open your terminal and verify the currently installed OpenSSL version:
$ openvpn --version
OpenVPN 2.6.0 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD]

We got version 2.6.0, and it's fresh enough, if yours is older - please update to the latest stable version.

  1. Edit your *.ovpn config and next lines to the bottom:
ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1
redirect-gateway ipv6
block-ipv6

Or we can automate it with one command:

printf "ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\nredirect-gateway ipv6\nblock-ipv6" > MY_VPN_CONFIG.ovpn

Also add the next lines at the end to handle DNS resolution correctly with resolvconf tool:

script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

or do the same with one command:

printf "script-security 2\nup /etc/openvpn/update-resolv-conf\ndown /etc/openvpn/update-resolv-conf" > MY_VPN_CONFIG.ovpn
  1. After saving, it's time to connect to VPN and verify if there are no leaks:
sudo openvpn MY_VPN_CONFIG.ovpn
...
Initialization Sequence Completed

All working fine, now we can visit to ping6.online.net - if this IPv6-only website isn't working, it means we did it!

The up and down scripts

Many people not want to upgrade OpenVPN packages from outside resources, either because they are stubborn or lazy. Also, many enterprise Linux and Windows Operating Systems will generate a lot of pain to update OpenVPN to the latest release. In this case, one magic update button will't bite the bullet. The OpenVPN scripts can work as extensions and do the job after connection established and reset all when the connection is down. Let's cover all step-by-step.

  1. Edit your *.ovpn config and next lines to the bottom:
script-security 2
up /etc/openvpn/v6down.sh
down /etc/openvpn/v6up.sh

Also add resolvconf hooks like before:

up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

If you don't want to add it all manually, we can automate it:

printf "%s\n" "script-security 2" "up /etc/openvpn/v6Odown.sh" "down /etc/openvpn/v6up.sh"  >> MY_VPN_CONFIG.ovpn
printf "%s\n" "up /etc/openvpn/update-resolv-conf" "down /etc/openvpn/update-resolv-conf"  >> MY_VPN_CONFIG.ovpn

The %s\n means printf will insert a new line after each its argument.

  1. Now we should create the v6down.sh and v6up.sh scripts. The command vim /etc/openvpn/v6down.sh will open the editor in and create new file in /etc/openvpn:
#!/bin/bash
sysctl -w net.ipv6.conf.all.disable_ipv6=1
sysctl -w net.ipv6.conf.default.disable_ipv6=1

Great, applying same approach for v6up.sh: vim /etc/openvpn/v6up.sh:

#!/bin/bash
sysctl -w net.ipv6.conf.all.disable_ipv6=0
sysctl -w net.ipv6.conf.default.disable_ipv6=0
nmcli networking off
nmcli networking on

This time, we need to tell NetworkManager to reload all connection and enable IPv6. If you don't use NetworkManager, the ip command can save us:

$ ip route | grep default
default via 192.168.0.1 dev wlp6s0 proto dhcp metric 600

So, our desired interface is wlp6s0. Let's reload it:

ip link set wlp6s0 down
ip link set wlp6s0 up

Do not forget to make both scripts executable: sudo chmod +x v6up.sh v6down.sh.

  1. After saving, it's time to connect to VPN and verify if there are no leaks:
sudo openvpn MY_VPN_CONFIG.ovpn
...
Initialization Sequence Completed

All working fine, now we can visit to ping6.online.net - if this IPv6-only website isn't working, it means we did it!

Automation scripts

Let's automate the stuff we talked about to use it comfortable every day.

Option –block-ipv6

Create the script called block-leaks1.sh
The VPN config *.ovpn should be located in the current directory. The script will create a backup and save it to MY_VPN_CONFIG.ovpn.backup.

#!/bin/sh
printf "%s\n" "ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1" "redirect-gateway ipv6" "block-ipv6" > MY_VPN_CONFIG.ovpn

printf "%s\n" "script-security 2" "up /etc/openvpn/update-resolv-conf" "down /etc/openvpn/update-resolv-conf" > MY_VPN_CONFIG.ovpn

sudo openvpn MY_VPN_CONFIG.ovpn

To undo all changes, let's create another script called reset-block-leaks1.sh:

#!/bin/sh
mv MY_VPN_CONFIG.ovpn.backup MY_VPN_CONFIG.ovpn
sudo openvpn MY_VPN_CONFIG.ovpn

Now we can run both in one step:

# start connection with our script
sudo ./block-leaks1.sh
# undo all changes and start the connection without it
sudo ./reset-block-leaks1.sh

up and down scripts

Create the script called block-leaks2.sh, this is another version of block-leaks1.sh.
The VPN config *.ovpn should be located in the current directory. The script will create a backup and save it to MY_VPN_CONFIG.ovpn.backup.

#!/bin/sh
cp MY_VPN_CONFIG.ovpn MY_VPN_CONFIG.ovpn.backup
printf "%s\n" "script-security 2" "up /etc/openvpn/v6Odown.sh" "down /etc/openvpn/v6up.sh" >> MY_VPN_CONFIG.ovpn
printf "%s\n" "up /etc/openvpn/update-resolv-conf" "down /etc/openvpn/update-resolv-conf" >> MY_VPN_CONFIG.ovpn

echo "#!/bin/bash" >> /etc/openvpn/v6down.sh
echo "sysctl -w net.ipv6.conf.all.disable_ipv6=1" >> /etc/openvpn/v6down.sh
echo "sysctl -w net.ipv6.conf.default.disable_ipv6=1" >> /etc/openvpn/v6down.sh

echo "#!/bin/bash" >> /etc/openvpn/v6up.sh
echo "sysctl -w net.ipv6.conf.all.disable_ipv6=0" >> /etc/openvpn/v6up.sh
echo "sysctl -w net.ipv6.conf.default.disable_ipv6=0" >> /etc/openvpn/v6up.sh
echo "nmcli networking off" >> /etc/openvpn/v6up.sh
echo "nmcli networking on" >> /etc/openvpn/v6up.sh
openvpn MY_VPN_CONFIG.ovpn

To undo all changes, let's create the script called reset-block-leaks2.sh:

#!/bin/sh
mv MY_VPN_CONFIG.ovpn.backup MY_VPN_CONFIG.ovpn
rm -rf /etc/openvpn/v6down.sh /etc/openvpn/v6up.sh
openvpn MY_VPN_CONFIG.ovpn

Now we can run both in one step:

# start connection with our script
sudo ./block-leaks2.sh
# undo all changes and start the connection without it
sudo ./reset-block-leaks2.sh

Enjoy, thanks for reading!

Read more