YubiKey OTP Two-Factor Authentication with OpenVPN and Viscosity
After setting up your own OpenVPN server, you may want to enhance it's security. One way to do that is to use 2FA (Two Factor Authentication). This adds another security measure to prevent unwanted users connecting to your server. One type of 2FA is OTP (One Time Password) with a YubiKey. This guide will expand on setting up an OpenVPN server on Ubuntu by adding YubiKey OTP support to that server using Viscosity's built in Challenge/Request support.
For this guide, we assume:
- You have already installed the latest version of Ubuntu (16.04 at time of writing)
- You have root access to this installation
- You have already an OpenVPN server running using one of our guides
- You already have a copy of Viscosity installed on your client device and already setup for this server
- You have a YubiCo YubiKey that supports OTP
This guide assumes you have followed one of our server setup guides and you are already able to connect to the server we will be modifying using certificate/key authentication. This guide will add two more authentication steps. A username and password using PAM, and a challenge request using a YubiKey's OTP support.
PAM authentication is the simplest form of username/password authentication we can use with OpenVPN. PAM uses the Ubuntu's user management to authenticate against so we don't need to manage an extra database of username and passwords. If you want to add a new user to be able to authenticate, you can simply add the new user with the useradd command in Ubuntu.
The follow instructions for Ubuntu assume that you have already setup an OpenVPN server using our Setting up an OpenVPN server with Ubuntu and Viscosity guide.
Modifying the Server
To get started, we need to install some extra dependancies. The first one is Python PIP, this will allow us to install extra packages, install it by running the following from your Ubuntu server's command line:
apt-get install python-pip
Next, install PAM and yubico-client using PIP:
pip install pam
pip install yubico-client
Next you will need to download our script for OpenVPN to use. Do this with:
After the file is in place, we need to make it executable by running:
chmod +x /etc/openvpn/opevnpn_otp_auth.py
We now need to get a YubiCo apikey for their cloud services for checking YubiKeys. To do this, go to https://upgrade.yubico.com/getapikey/ and simply follow the instructions to get your ClientID and Secret Key. Once you have these, edit opevnpn_otp_auth.py with
nano /etc/openvpn/opevnpn_otp_auth.py and find the following lines:
yubicoClientId = 'YOURCLIENTID' yubicoSecretKey = 'YOURSECRETKEY'
Replace YOURCLIENTID with your Client ID, and YOURSECRETKEY with your Secret Key and save the script.
Finally, we need to modify the OpenVPN server configuration. First, stop the server using:
systemctl stop [email protected]
Then edit the server configuration using:
Scroll all the way to bottom then on a new line add the following:
#Use a script to authenticate username/password and yubikey OTP auth-user-pass-verify openvpn_otp_auth.py via-env script-security 3
Now find the following two lines:
user nobody group nobody
And comment them out, changing them to:
#user nobody #group nobody
Save the configuration then restart the server:
systemctl start [email protected]
Setting up Viscosity
Now the server is setup, we need to make two small changes to our configuration in Viscosity.
- Open Viscosity's Preferences and edit your connection.
- Go to the Networking tab and tick 'Use Username/Password authentication'
- Go to the Advanced tab, then on a new line add:
static-challenge "Activate your YubiKey" 0
- Save the connection
The comment in quotes for the static-challenge command you added, i.e. "Activate your YubiKey" is what is displayed to the user when the YubiKey OTP password needs to be entered. You can change this message to whatever you like.
Now that changes to your configuration in Viscosity have been made, connect to the server to test the changes! You will see an extra Password window appear during the connection process, tap your YubiKey when you see it.