Setup your VPN in docker with OpenVpn in 5 minutes

Docker simplifies deployments so much that even setting up a VPN to a machine of your private network becomes trivial.

There are different docker containers running openvpn, but I am very thankful to kylemanna for his excellent image (available on the docker hub).

The usage of the image requires a few extra steps than just running it, because it can be conveniently used to run scripts to initialize the configuration and setup users, other than just running the service.

Here is a brief overview of the setup process (this just adds some context to the already comprehensive README that ships with the github repo):

  1. Use a “convenience” environment variable to store the path to your persistent storage location that will be bind-mounted to the container. You can also use a data volume as an alternative. For me, this is a ZFS filesystem (I create a ZFS filesystem for each container that requires persistent storage)
  2. Run an ephemeral instance (–rm) of the image to initialize the data directory of the container (ovpn-host should be the hostname of your openvpn server)
    docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://ovpn-host

    This will create the following content in your data directory, that includes the openvpn server configuration (the server network will be

    drwxr-xr-x 2 root root 4096 Mar 7 10:14 ccd
    -rw-r--r-- 1 root root 629 Mar 7 10:14 openvpn.conf
    -rw-r--r-- 1 root root 611 Mar 7 10:14
  3. Run an interactive ephemeral instance of the image to generate the opevnpn CA certificate and server key (you will have to type your passphrase for the private key)
    docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki

    This will setup the pki directory:

    total 44
    -rw------- 1 root root 1172 Mar 7 10:40 ca.crt
    drwx------ 2 root root 4096 Mar 7 10:40 certs_by_serial
    -rw------- 1 root root 424 Mar 7 10:40 dh.pem
    -rw------- 1 root root 42 Mar 7 10:40 index.txt
    -rw------- 1 root root 21 Mar 7 10:40 index.txt.attr
    -rw------- 1 root root 0 Mar 7 10:40 index.txt.old
    drwx------ 2 root root 4096 Mar 7 10:40 issued
    drwx------ 2 root root 4096 Mar 7 10:40 private
    drwx------ 2 root root 4096 Mar 7 10:40 reqs
    -rw------- 1 root root 3 Mar 7 10:40 serial
    -rw------- 1 root root 3 Mar 7 10:40 serial.old
    -rw------- 1 root root 636 Mar 7 10:40 ta.key
  4. Run the VPN service: start and detach the container (-d) and map a host port to the UDP container port where the openvpn server process is listening (1194). In this example the host port will be 1195

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

    The NET_ADMIN capability is needed so the container can setup the virtual tun0 interface to terminate the VPN tunnel.
    After this command, the VPN service is up and running on the specified host port (1195 in the example).

  5. Generate client configuration (i.e., add a user to the VPN). If you omit the nopass option, the client key will be encrypted with a passphrase.
    docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full vince nopass

    The client key will be in ${OVPN_DATA}/pki/private and the certificate in ${OVPN_DATA}/pki/issued

  6. Retrieve the client configuration to a local file:
    docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient vince > vince.ovpn

Access the VPN with the client configuration file.

If you need to add more users, just repeat the last two steps to create a user configuration on the server and retrieve the ovpn file.

If this isn’t just a test, you may want to add a restart policy to this container (get the container ID with docker ps):

docker update --restart=always 

4 thoughts on “Setup your VPN in docker with OpenVpn in 5 minutes

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s