Creating a VPN With 2 Factor Authentication Using OpenVPN and Docker
By: Armindo Cachada
Tags: Openvpn, Docker Compose, Security, 2 Factor Authentication, Programming

Creating a VPN With 2 Factor Authentication Using OpenVPN and Docker Armindo Cachada Follow Oct 3 · 8 min read

Photo by Petter Lagson on Unsplash

I recently set up a VPN with 2-Factor Authentication using the Community Edition of OpenVPN and using Google’s standard authenticator. I am writing this article to save you time and effort because this was not straightforward.

Most guides I found on the internet, if not all, talk about using a PAM plugin to extend OpenVPN with 2 Step Authentication. Not only is this plugin difficult to install because of Linux library dependencies, but most importantly it requires a real Unix user for each VPN account you need to setup. For me, that was a non-starter as all my existing VPN users reside only inside a database.

Background

Before the need for extra security via 2-factor authentication came up, I was already using OpenVPN with the help of an excellent open-source project in GitHub which provides a web administration interface (https://github.com/Chocobozzz/OpenVPN-Admin). Since I only use the community edition of OpenVPN, this project gives you access to a neat management interface, from which you can create & manage VPN user accounts, and also allow VPN users to download the files that they need to connect to the VPN. The management interface is a simple PHP web interface that uses a MariaDB as a backend.

What is OpenVPN?

According to Wikipedia: “OpenVPN is an open-source commercial software that implements virtual private network techniques to create secure point-to-point or site-to-site connections in routed or bridged configurations and remote access facilities. It uses a custom security protocol that utilizes SSL/TLS for key exchange”.

Why we need it

With more people working from home due to lockdowns, this has required ways for workers to be able to access intranet websites from within their homes without compromising security and without relying on IP address whitelisting as Home IP addresses are not normally static.

To make the VPN more secure I added 2-Factor authentication using Google’s Authenticator reference application.

How it works

This OpenVPN solution uses three separate open-source projects:

OpenVPN which provides the VPN functionality

OpenVPN-Admin which provides a UI for an administrator and users to set up VPN users.

The PHP gangsta — Google Authenticator project — a PHP implementation of the Google Authenticator reference app originally written for mobile.

The Community edition of OpenVPN does not provide 2 Factor authentication, therefore I had to add this feature.

So I forked the GitHub project https://github.com/Chocobozzz/OpenVPN-Admin and added extra functionality required for enabling the Google Authenticator functionality.

The new OpenVPN implementation runs as 4 docker containers:

openvpn docker container runs the OpenVPN server

docker container runs the OpenVPN server webadmin runs the webadmin interface for OpenVPN

runs the webadmin interface for OpenVPN googleauth is a docker container that runs a small PHP microservice to do the 2 step authentication(pairing and validation).

is a docker container that runs a small PHP microservice to do the 2 step authentication(pairing and validation). openvpn_docker_nginx is the docker container that exposes the OpenVPN interface via SSL

Preparation:

Install Docker Install docker-compose

Steps for setup:



$cd OpenVPN-Docker-GoogleAuth

docker-compose up -d $git clone https://github.com/armindocachada/OpenVPN-Docker-GoogleAuth $cd OpenVPN-Docker-GoogleAuthdocker-compose up -d Creating network "openvpn-docker-googleauth_default" with the default driver

Creating volume "openvpn-docker-googleauth_openvpn_config" with default driver

Creating volume "openvpn-docker-googleauth_db_data" with default driver

Building openvpn Step 1/16 : FROM centos/php-72-centos7

latest: Pulling from centos/php-72-centos7

75f829a71a1c: Pull complete

e2c4942f4189: Pull complete

f1498894b11c: Pull complete

da56c9694723: Pull complete

07fa76fc639e: Pull complete

8adb3980d23d: Pull complete

bf52e0852ccc: Pull complete

022196718e3e: Pull complete

8d81a4f20bd7: Pull complete Digest: sha256:8eee082936869e8c77abb2eb18f10f61de02dc10c36b01cb35955114be2afd64 Status: Downloaded newer image for centos/php-72-centos7:latest ---> 6df586f63c89 Step 2/16 : USER root ---> Running in 2ea6f77e847c .... bootstrap#3.4.1 vendor/bootstrap

└── jquery#2.2.4

Removing intermediate container cc0508eca502

---> d94208cdefe1

Step 14/15 : RUN rm -fr /root/OpenVPN-Admin && chown -R www-data:www-data /var/www/html

---> Running in 319edaf415c7

Removing intermediate container 319edaf415c7

---> 5aaa0ae56087

Step 15/15 : COPY ./webadmin/start.sh /usr/local/bin

---> d8a662dbafd5

Successfully built d8a662dbafd5

Successfully tagged openvpn-docker-googleauth_webadmin:latest

Creating googleauth ... done

Creating db ... done

Creating openvpn ... done

Creating webadmin ... done

Now check that you have 4 docker containers running in your system:

$docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0917e2be15b4 openvpn-docker-googleauth_webadmin "docker-php-entrypoi…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp webadmin da8c0f04bdfe openvpn-docker-googleauth_openvpn "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 8080/tcp, 0.0.0.0:1099->1099/tcp, 8443/tcp openvpn 4985a54a5594 openvpn-docker-googleauth_googleauth "docker-php-entrypoi…" 2 minutes ago Up 2 minutes 80/tcp googleauth 970f978c37d1 mariadb "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 3306/tcp db

The googleauth docker container is needed for the 2 factor authentication. It is called internally by openvpn and the webadmin when doing the 2 factor authentication.

The db docker container is used to store usernames/passwords.

The OpenVPN container runs the OpenVPN server to which the OpenVPN will connect.

The webadmin container contains the OpenVPN web administration interface where you can create VPN accounts and setup 2 Factor authentication.

To access the OpenVPN web administration interface you can use:

http://localhost:8080/

OpenVPN Web Admin

Before we can log in, we need to do the initial setup:

Go to the following URL:

http://localhost:8080/index.php?installation

Pick an admin username and a secure password.

Now we should be able to login:

Let’s create a VPN user

The new user should be visible in the list below:

Now that you have a VPN user, there are three steps required for setup of each VPN user.

Set up 2-Factor Authentication: Each VPN user needs to download the Google Authenticator app and pair the app with their VPN account. Note that it is possible to switch off 2 Factor authentication via the admin UI. Download OpenVPN zip file: To be able to create a new profile, you need to download a ZIP file that contains the client certificate(.ovpn file) that you will need later when setting up the OpenVPN client. Setting up the OpenVPN client

Setting up 2-Factor Authentication

Navigate to the OpenVPN Web Administration Page, at http://localhost:8080 Click Setup Google Authentication on the navigation bar Enter the credentials given by your administrator to log in.

4. After login you should see the following page:

At this stage, you should install the Google Authenticator app on your mobile phone.

Open your Google Authenticator App, and press the ‘+’ icon in the top right and then press ‘Scan Barcode’

Point your camera at the QR code and you should see the profile appear with your details.

5. Next you need to type the 6 digit PIN number you see in the Authenticator app. If it all goes well, the pairing will succeed and you will see a “Pairing succeeded” message. If you see an error instead, it is possible that you were too slow typing the PIN number. Try again.

Download OpenVPN zip file

Navigate to the OpenVPN Web Administration Page, at http://localhost:8080 Click Configurations on the navigation bar Enter the VPN user credentials given by your administrator to log in. Choose the correct OS from the dropdown: Linux, OS X(MacOS) or Windows Click “Get Configuration Files”. You will be downloading a ZIP file with the required client configuration for OpenVPN. Keep it in a safe folder. You will need it soon.

Setting up the OpenVPN Client

I am assuming at this stage that you have already completed the steps above and your VPN is accessible via a public IP address on a given port. The VPN IP address will be stored in the client certificates that we downloaded earlier.

Download the OpenVPN client for your operating system. Ensure that you download version 3 or above. Version 2 will not work.

MacOS Download: https://openvpn.net/downloads/openvpn-connect-v3-macos.dmg

Windows Download: https://openvpn.net/downloads/openvpn-connect-v3-windows.msi

Install the OpenVPN client.

Install the client Certificate

After installing the OpenVPN client, you should see the following screen:

Initial screen without any VPN profiles

Click the + sign, and select file.

Select the client.ovpn file you downloaded in the earlier step(don’t forget to unzip).

At this stage, you need to supply your VPN credentials. Click Save Password. But remember that every time you log in, if you don’t disable 2 Factor Authentication you will need to add your 6 digits PIN number to the end of your password. This is slightly annoying, but worth it because of the extra security.

Click Save when you are done.

And that’s it, you now have a VPN profile setup ready to connect.

Connecting to the VPN using 2 Factor Authentication

Every time you try to connect to the VPN you will need to supply a six-digit PIN that is everchanging. This PIN is available from the google authenticator app.

Just before you login take note of the latest PIN number(you need to be quick) Click the toggle button on the left-hand side to connect to the VPN

3. At this stage you will be prompted for your password.

Enter your password and add at the end of your password without any extra spaces the PIN number from step 1. Click OK

4. You will see a Connection Error message. Click “Continue”

5. If all goes well, you are connected to the VPN!

And a new world opens up!

Hope you enjoy it.

Resources: