- OpenVPN IPv6 and IPv4 configuration - Mon, Mar 1 2021
- 4sysops author and member competition 2020 - Fri, Jan 1 2021
- Assign an IPv6 address to an EC2 instance (dual stack) - Tue, Dec 15 2020
Many blog posts about configuring OpenVPN with IPv6 settings were not really needed for IPv6; some even had totally unrelated purposes. This can be quite confusing if you're trying to understand how OpenVPN and IPv6 work together. Understanding all the commands in your in your configuration is crucial because otherwise you might end up with an insecure setting.
Perhaps even worse are those posts that only explain the IPv6-related settings but fail to mention the other minimum requirements to get OpenVPN going. OpenVPN's official guide is one of them. Thus, I decided to write my own guide, which honors Albert Einstein's principle: "Everything should be made as simple as possible, but not simpler."
The other question you might ask is why you need IPv6 for OpenVPN. Every server on the Internet can still be reached with IPv4; thus, beefing up your OpenVPN setting with IPv6 seems to violate Einstein's principle. Actually, no. The main reason you want your OpenVPN setup to support IPv6 is, again, security.
I think many OpenVPN users are unaware of the consequences of an IPv4-only configuration on the Internet, with fast-growing support for IPv6. Let's say you are in a coffee shop with your laptop, and as usual, you connect via VPN because you are in an insecure network environment. What you don't know is that the coffee shop uses a service provider that supports IPv6. Hence, your laptop will automatically receive an IPv6 address.
The result is that whenever you connect to a server that has an IPv6 DNS entry, your traffic will probably not be routed via IPv4 and therefore not go through your OpenVPN connection. The bad thing is that you won't notice the difference. Everything will work just fine—but none of your IPv6 traffic will be encrypted.
OpenVPN IPv6 setup ^
For my guide, I worked with an Ubuntu server and a macOS client (Tunnelblick). Because the OpenVPN commands should be independent of the underlying operating system, the settings discussed here should work with any OS (even Windows). The only OS-dependent part is the installation of the OpenVPN server and the client, which I don't cover here. Suffice it to say that this installation is trivial for all operating systems.
To enable IPv6 for OpenVPN, you have to configure server and client settings. However, where those settings reside (server or client) is a matter of taste for some commands. With the help of the push command, you can add client-related settings to your server configuration file. The advantage is that you can work with one central configuration for all your clients. For the sake of simplicity, I put all client commands in the client configuration file.
Another simplification here is that I work with a static secret key rather than a certificate. This is fine, as long as you use this setup only to connect to your own servers. If you have end users that are supposed to work with OpenVPN, you'd better use certificates.
OpenVPN server configuration ^
On Ubuntu, the server configuration net.conf can be found in/etc/OpenVPN/. First, we need to create a virtual network device. This software-based interface is called tun (reference to tunnel) and is virtually connected to our OpenVPN process:
Next, we have to configure the tun device for IPv6:
Update: The next command is no longer required in the latest OpenVPN version.
Note that without this directive, you will still be able to establish a VPN connection by connecting to the IPv6 address of your server without any error message. However, your IPv6 traffic will not be routed through the VPN.
For some reason, many guides omit the next command. My guess is that it wasn't required with older OpenVPN versions. However, it is crucial to tell OpenVPN to also support IPv6 on the transport layer, which is UDP in our case.
Next, we have to assign a privateIPv4 address. If you omit this command, your VPN server won't work at all. Thus, even if you plan to use only IPv6, you still need this directive.
ifconfig 10.1.0.1 10.1.0.2
The first IP address is that of the server, and the second is that of the client. Note that you have to make sure that neither your server nor client already uses the same subnet. If one of them does, just choose another subnet for OpenVPN.
Of course, we also need to assign IPv6 addresses. Considering the number of possible IPv6 addresses, you can use any IPv6 address without expecting conflicts. However, to be on the safe side, it's better to use so-called unique local IPv6 unicast addresses, which are essentially the equivalent of private IPv4 addresses:
ifconfig-ipv6 fd00::1 fd00::2
As mentioned above, we use a static key for authentication. You can create a static key with the openvpn --genkey --secret static.key command. You have to save the static.key file in the OpenVPN configuration folders of the server and the client. The locations depend on your OS. In your server configuration file, add the command below:
That's all for the server. Make sure to restart the OpenVPN service. (For instance, on Ubuntu: sudo /etc/init.d/openvpn restart.)
OpenVPN client configuration ^
The client configurations are similar. First, we need to create a virtual device for IPv6:
Then, we enable IPv6 for the transport layer:
After that, we configure the private IPv4 address:
ifconfig 10.1.0.2 10.1.0.1
Note that the order of the IP addresses is reversed compared to the server configuration. The first address is for the client and the second for the server.
Then, we do the same for the IPv6 addresses:
ifconfig-ipv6 fd00::2 fd00::1
Again, the order is reversed compared to the server configuration.
To connect to your server via its public IPv6 address, you can use this command:
We also have to override the default gateway for IPv6 and IPv4 traffic to make sure that all traffic is routed through the VPN connection:
redirect-gateway ipv6 def1
As we did for the server, we need to add a directive to the static key:
This is essentially the minimal configuration required for IPv6. If you don't want to use a public DNS server for security reasons, you can use your own DNS server, which in our example resides on the OpenVPN server:
dhcp-option DNS 10.1.0.1
IP forwarding and iptables ^
If you only want to establish a secure connection to your server, the above configuration should be enough. However, if you want to connect to the Internet through your VPN server, you also have to make sure the IP traffic is forwarded. On an Ubuntu box, this can be done by adding the two lines below to /etc/sysctl.conf:
Reboot the server after you save the file.
Because many Linux configurations have an iptables firewall running, I add here the commands that allow OpenVPN in the firewall. These are the commands for IPv4:
iptables -A FORWARD -i tun0 -o ens3 -s 10.1.0.0/24 -m state --state NEW -j ACCEPT iptables -A FORWARD -i tun0 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A POSTROUTING -s 10.1.0.0/24 -o ens3 -t nat -j MASQUERADE
You might have to change the -o parameter, depending on the name of your network interface. Run ifconfig to find the name on your machine. This also applies to the IPv6 configuration for iptables:
ip6tables -A FORWARD -i tun0 -o ens3 -s fd00::/64 -m state --state NEW -j ACCEPT ip6tables -A FORWARD -i tun0 -m state --state ESTABLISHED,RELATED -j ACCEPT ip6tables -A POSTROUTING -s fd00::/64 -o ens3 -t nat -j MASQUERADE
Note that explaining these commands is beyond the scope of this article. If you work with iptables, make sure that you understand what you are doing here.
If you want to make the changes permanent, that is, reload them after a reboot, you can use these commands provided you installed iptables-persistent (sudo apt install iptables-persistent on Ubuntu):
iptables-save > /etc/iptables/rules.v4 ip6tables-save > /etc/iptables/rules.v6
Many things can go wrong here. It is important to understand you cannot conclude that everything is configured correctly just because your OpenVPN client is successfully connected to the server without error messages. Your traffic might still not go through your OpenVPN connection if something with your routing went wrong.
One way to verify your configuration is to run traceroute (IPv4) and traceroute6 (IPv6) on your client to see how your packets are routed. The commands below connect to Google servers:
traceroute 220.127.116.11 traceroute6 2001:4860:4860::8888
As you can see in the screenshot, IPv4 and IPv6 are properly routed through our private server IP addresses.
Subscribe to 4sysops newsletter!
You can also check whether WhatIsMyIPAddress displays the public IPv4 and IPv6 addresses of your server if you open the page with a web browser on your client.