Simple OpenVPN Server Set Up with Docker

How to create your own dockerized VPN Server in a minute

When I was doing some works, there was a requirement to whitelist development machine by IP Address from the United States. Since I was located in one of South East Asia countries, obviously I didn’t have a connection with US IP Address. So it would be reasonable to buy a VPN service for this.

But why buy a VPN service if we could use the existing VPS and set up a VPN server on it?

As you may guess, I already have VPS running for my development needs. So I would like to install the OpenVPN server in it. There are tons of tutorials out there on how to set up a VPN server by yourself. But mostly it’s a long tutorial with a lot of steps like this one.

Usually, these long steps can be simplified by using a container like Docker. So, in this tutorial, I will show you how to install the OpenVPN server quickly by using existing Docker image.

Requirements

I assume you already have a VPS running by now. If not, you can buy a VPS with affordable price on DigitalOcean. I have one there too, and I would say it’s enough for our needs.

You can use any OS, but for simplicity, I’ll be using Ubuntu.

If you already have a VPS running, next thing you need is to install Docker.

After all of the requirements fulfilled, we can continue to the next step.

Solution

There are 3 variables need to be defined.

The first variable is $OVPN_DATA. It is for data volume container. It’s recommended to use the ovpn-data- prefix to operate seamlessly with the reference systemd service.

The second variable is $VPN_SERVERNAME. The value should be a domain name or IP Address.

The final variable is $CLIENTNAME. It’ll be used as a client definition. You can name it with something memorable, so you’ll be able to notice where you’re being connected.

The following is an example of value for each variable.

OVPN_DATA="ovpn-data-example-us01"
VPN_SERVERNAME="vpn.example.com"
CLIENTNAME="us01.vpn.example.com"

Let’s begin by creating $OVPN_DATA docker volume.

docker volume create --name $OVPN_DATA

Next step is to initialize the $OVPN_DATA container. It will be used to hold the configuration files and certificates.

docker run \
    -v $OVPN_DATA:/etc/openvpn \
    --log-driver=none \
    --rm \
    kylemanna/openvpn \
    ovpn_genconfig \
        -u udp://${VPN_SERVERNAME}

The container will ask you for a passphrase to protect the private key used by the newly generated certificate authority.

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

Wait until the initialize process finished.

After the previous process finished, we can start the OpenVPN server process.

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

Now that we already have OpenVPN service started, we can generate a client certificate without a passphrase to be used on our local machine.

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

After the certificate created, we can retrieve the client configuration with embedded certificates file.

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

And that’s it. Download ${CLIENTNAME}.ovpn to your local machine. Use OpenVPN client for Windows, or Tunnelblick for macOS, or any other VPN client for your operating system.

That’s all I can write today. Hope this quick tutorial useful for you.

References

Cover Photo by Petter Lagson on Unsplash