Configuring a dualstack IPv4/IPv6 OpenVNP 2.4 server


The way a VPN works is quite simple, a client connects to a server, a ciphered tunnel is created between the client and the server. And as soon as this tunnel is up and running, the client and the server start to exchange their network traffic trough that tunnel. There are many possible applications to create with a such tool, this article focus on the following(s):

  • Reaching the VPN server through both IPv4 and IPv6

Table of contents


How To

After a few searches, it seems to be pretty easy to activate both IP stacks, just need to replace proto udp by proto udp6 into the server.conf file. So by forcing only IPv6 on the server side, it enables both IP stack… How is it possible ? That has simply nothing to do with OpenVPN, it is a feature of the Linux kernel. It seems to be enabled by default, but to be sure, it is possible to check the status of this parameter with the sysctl command. The parameter name is net.ipv6.bindv6only and has to have its value set to 0 to enable both IP stack when an IPv6 binding is done.

user@openvpn.server:~# sysctl net.ipv6.bindv6only
net.ipv6.bindv6only = 0

This parameter is not really new, it has existed since 2003 and has been introduced since Linux 2.4.21 and 2.6. See IPV6_V6ONLY in IPv6 manpage.

Do not expect to see this double binding through command like lsof or ss, it is totally transparent, only IPv6 will show up.

user@openvpn.server:~# lsof -i -P -n | grep openvpn
openvpn   1234   nobody  7u   IPv6  9876543  0t0      UDP  *:1194
user@openvpn.server:~# ss -nulp | grep openvpn
State   Recv-Q Send-Q   Local Address:Port  Peer Address:Port 
UNCONN  0      0        :::1194             :::*              users:(("openvpn",pid=1234,fd=42))

At this point, I was a little bit confuse about the OpenVPN configuration lines proto udp, proto udp4, and proto udp6.

These parameters allow to have impact on two different family of protocols, transport and network. It would have been simpler to understand if two different kind of parameters have existed, one for each protocol.

To add more complexity, these parameters exist in both client and server configuration files. On the server side, it will impact what IP version the server is listening on. On the client side, it will impact what IP version the client pick to connect the server. That’s two different mechanisms! I apologize for those looking for difference between UDP and TCP, I mainly focused on the network layer. Here is a summary of what I found.

configurationon the server sideon the client side
proto udpdepends (1)depends (2)
proto udp4IPv4 onlyIPv4 only
proto udp6IPv6 only or IPv6 +IPv4 (3)IPv6 only

(1) that was really hard to find details about that one. I had to read OpenVPN source code to have a better idea of it. What you have to remember is that OpenVPN prefers to pick IPv6 stack when it has the choice. But OpenVPN also asks the operating system which IP stack it should use to create a server. If the operating system answers to use IPv4 stack, OpenVPN will use it even if the IPv6 stack works perfectly. So don’t be surprised if most of the time, with the parameter proto udp, your server uses the IPv4 stack only.
If you are curious to know what IP stack your system prefers, just start an OpenVPN server with the parameter proto udp. In the log file, you should see a line like this Could not determine IPv4/IPv6 protocol. Using AF_INET. Meaning that no stack choice has been made by configuration and the OpenVPN took the one suggested by the operating system. In this example, the selected one is AF_INET, meaning IPv4. (explanation for this log line)

(2) client will also asked to the operating system which IP stack to use to connect a server. But with a huge difference, if the first IP stack does not work, a fallback mechanism will try the second IP stack.

(3) bind to both IP stacks only if the parameter net.ipv6.bindv6only is set to 0. Otherwise it will only use the ipv6 stack.

I was curious to know how OpenVPN was asking the system the IP stack to use. It uses the function getaddrinfo. (manpage) This function allow to ask a list of IP for the local host or for any remote host. The order of the list will depend of the system preferences. If the system prefers IPv6, that will be the first addresses in the list. But if the system prefers IPv4, IPv6 addresses will be at the end of the list and IPv4 addresses at the beginning.


With the configuration line proto udp6 in the OpenVPN server configuration, and the parameter net.ipv6.bindv6only set to 0 on the server side, it is now possible to reach the OpenVPN server through both ipv4 and IPv6.

Configuration files

For obvious security reasons, the following files are not provided: ca.crt, crl.pem, dh.pem, server.crt, server.key, ta.key



Related Posts


  1. Valentin17 June 2021 at 08:37

    Hey there,

    I struggled for quite a while with a OpenVPN server behind a DSLite internet connection. The client would just not connect because the server config contained udp instead of udp6. My misconception was, that proto udp would eventually listen to both IPv4 and IPv6, if available. I fixed it by myself with some research and trial and error but could not really grasp why proto udp would not work. Then I found your article 😀

    Thanks for explaining the differences of these options cleary, they are imho not documented as thoroughly as they could.

  2. Hey there,

    this concise and clear explanation helped me a lot while setting up an OpenVPN server behind a DSlite (native IPv6 only) tunnel. I think it is pretty strange that it is so hard to find a decent and clear explanation of these important options and how they behave under certain circumstances.

    Thanks for sharing your findings.


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.