How to install and host OpenVPN server with Docker


How to install and host OpenVPN server with Docker

Overview

This post covers the procedure of how to install and host OpenVPN server with Docker. Meaning, that we are going to be able to use Docker to install OpenVPN server and run it as a service, generate client connection configs and certificates, which afterwards we can use to connect multiple clients on our VPN server. This method works on any Linux distro that has Docker installed and running.

NOTE – This setup is for a password-less environment, meaning – client won’t use user name and password to connect on the server, instead it will user client certificates to connect.

Prerequisites:

– Docker installed and running – if not installed, check this post for Docker install instructions on Debian and Ubuntu

– Docker container we’re going to user – LINK (also check out for more info if needed)

OpenVPN server Docker container installation

1. First step is to create data volume container for OpenVPN, so it can store all the data, configuration files and certificates. It’s suggested to add “ovpn-data-” prefix and then add another word you want at the end. For an example, it should look something like this – ovpn-data-example. And you replace the word example with whatever you want.

So in terminal run the command:

OVPN_DATA="ovpn-data-example"

Now we will create the data volume container:

docker volume create --name $OVPN_DATA

Note – if you haven’t added Docker the elevated privileges on your Linux host, then you’ll need to add sudo everytime you want to run docker commands.

2. Then download the OpenVPN docker image file with the argument to set it to use your server’s(host) public IP address or your domain name via UDP protocol(also can use TCP protocol as well):

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm kylemanna/openvpn ovpn_genconfig -u udp://VPN.SERVERNAME.COM

Replace the VPN.SERVENAME.COM with your public IP address or with a domain name you registered and pointed to your server. This is the setup if you’re hosting your server on a cloud(Like on AWS, Azure, UpCloud, Digital Ocean, Linode etc…).

install openvpn with docker

For self-hosting option at home – this also applies if you have a static public IP address, plus you’ll need to do port-forwarding on your router(modem) to point to your host(server). If you don’t have a static IP address, then you’ll need to use a Dynamic DNS.

Generating and retrieving CA certificate and client certificates

3. Now we need to initiate our PKI system in order to generate the CA certificate for our server and to generate client certificates as well:

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it kylemanna/openvpn ovpn_initpki

Follow the instructions. If you plan to install the OpenVPN on a cloud server which has limited resources(example, 1 CPU and 1 GB of RAM) then it can take a while to generate the CA server certificate(cca 15 min).

setup openvpn with docker

When you initiate the PKI for OpenVPN, first it will ask you to provide a password for the CA certificate.

IMPORTANT NOTE – Write down somewhere the CA passphrase, you will need it later on during the setup process and every time when you generate a client certificate.

install openvpn with docker

Next it will ask you to provide a name for the CA. You can enter anything.

The CA generation process will take a while.

install openvpn with docker

Once it’s complete, it will generate a private key and it will ask again to provide the CA passphrase you entered earlier. It will prompt you 2 times for the password.

host openvpn on docker

The generated CA certificate will be valid for the next 3 years.

Start the OpenVPN server service

4. Run the Docker command to start the OpenVPN container:

docker run -v $OVPN_DATA:/etc/openvpn -d -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn

Note – the argument in the command -p 1194:1194/udp – also an important part of this setup. This argument will set our OpenVNP on which port to listen and use in order to establish communication between the server and client. In the command above is set to use port 1194(left number for the Docker container and right number for the host server), because OpenVPN by default uses port number 1194 via UDP protocol. Change this number if you plan to use a different port number.

Generate the client certificate and extract the client configuration file from the container to host

5. Run this command to generate a certificate for a client device:

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it kylemanna/openvpn easyrsa build-client-full CLIENTNAME nopass

The argument CLIENTNAME in the command above you can replace with what you want. That’s for the filename of the certificate and for client identification. The command also will generate a password-less certificate. The certificate will be placed at user’s home directory on hosts filesystem(username you’re using to login on the host via SSH) NOT on the Docker container.

When generating the client certificates, OpenVPN will prompt you to provide the CA passphrase.

NOTE – Generated certificates, as seen on pictures will last for 3 years from the time you’ve created them.

6. Run this command to compile the OpenVPN connection config file and to retrieve it from the Docker container to the host server

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm kylemanna/openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn

 

After that, you’ll need an FTP, SFTP or SCP client to connect on your host server and download the OpenVPN file and use it in order to connect to your VPN server.

 

Connect to your OpenVPN server

In order to connect to your VPN server, you’re going to need to install OpenVPN client. There are client apps for Windows and Android – OpenVPN connect. In the app just import the openvpn file as a new profile and connect.

There’s of course the client for linux. Network manager on Linux supports the OpenVPN but it asks to import all the certificates separately. So, for the simplicity, i suggest to install the app client as well. On Debian and Ubuntu distros:

$ sudo apt install openvpn

Once it’s installed, navigate to the location where the certificate file is placed and run the command:

$ sudo openvpn ./CLIENTNAME.ovpn

The successful connection result should look like this

Make sure to open appropriate ports to your server

Also an important note for this to work. If you plan to host this on a cloud or if you have installed a firewall on your server, you need to open and allow ports you assigned ports to your OpenVPN server.

In this case, the server is on cloud and I needed to open ports 1194 for UDP protocol on the firewall.

Connect multiple clients

You can connect multiple clients with this setup. One method is to use one certificate on multiple devices, but the method is less secure. For this you would need to access the OpenVPN server config file located in the Docker container and add argument:

duplicate-cn

I recommend to issue/generate a new separate certificate for each client. To achieve this, you need to repeat a couple of commands:

Re-initiate the docker volume for OpenVPN.

OVPN_DATA="ovpn-data-example"
docker volume create --name $OVPN_DATA

Then generate a new client certificate but use a different name instead of CLIENTNAME:

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it kylemanna/openvpn easyrsa build-client-full CLIENTNAME nopass

and of course retrieve the OpenVPN config file and download the file:

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm kylemanna/openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn

Summary

We covered the process how to install OpenVPN with Docker, how to host OpenVPN with Docker,  run the PKI system, generate the CA certificate and client certificate and how to connect. I personally like this setup, first because of ease of use, management and how the setup has pretty high security on both server and client’s end. All props and credit to KyleManna for building such an awesome Docker image.


You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *