How to setup Multi-factor Authentication with OpenVPN Community Edition

Ruween Iddagoda
2 min readFeb 21, 2022

Overview of the Process

  1. User executes google-authenticator to generate the QR code and verification code (secrets)
  2. User connects a MFA enabled device by scanning the QR code presented.
  3. Verfication code must be installed (stored) onto the VPN server itself
  4. During the authentication, OpenVPN will call the PAM module to perform verification on the user submitted password (OTP code) against the secret shared by the user.
  5. Upon verifying, users are able to connect to the VPN.

Initial Configurations

Pre-requisites

  1. OpenVPN server community edition installed Instance with root privileges
  2. Google Authenticator enabled device
  3. OpenVPN client installed device

Server-side

  1. Create a new directory called /etc/google-auth
$ mkdir /etc/google-auth

2. Change permissions to 0400 since PAM does not prefer world/group readable objects

$ chown -R root /etc/google-auth

3. Install libpam-google-authenticator and libqrencode3 packages

$ sudo apt install libqrencode3 libpam-google-authenticator

4. Add the following line to your openvpn server config file to ask openvpn to authenticate against libpam , which has it’s own google-auth module

plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so openvpn
  • This states openvpn will use the pam authentication method with pam auth id as openvpn

5. To create the pam setup, create a new file named /etc/pam.d/openvpn and add the following lines

auth    requisite       /lib/security/pam_google_authenticator.so secret=/etc/google-auth/${USER}  user=root
account required pam_permit.so
  • By auth requisite we state that if unsuccessful the authentication will fail immediately.
  • By secret= we specify the location where the verification codes are stored and root user can access it.
  • In the last line we state that we allow the connection if successful

6. Append the client .ovpn file with the following

auth-user-pass
auth-nocache
reneg-sec 0
  • auth-user-pass — for openvpn-client to ask for username and password
  • auth-nocache — to not cache the password since it’s changing periodically
  • reneg-sec 0 — to not re-negotiate periodically

Client-side

  1. Install libpam-google-authenticator and libqrencode3 packages
$ sudo apt install libqrencode3 libpam-google-authenticator

2. Execute google-authenticator from the terminal

$ google-authenticator

3. Scan the generated QR code using Google Authenticator enabled device.

4. Proceed by providing y to all prompts. The secret file will be store in your $HOME directory as a hidden file.

5. Make sure to backup the verification codes and other secrets as well.

6. To view the the secret file use the command

$ ls -a | egrep '^\.'OUTPUT
.
..
.google-authenticator

7. Rename the secret file to your openvpn username

$ mv ~/.google-authenticator someuser

8. Transfer the file to the VPN server.

  • The server must store this file in the /etc/google-auth directory

How to connect?

  • Use the openvpn — config command to connect as usual. The openvpn-client will prompt for the username and password (OTP code).
$ sudo openvpn --config <client_config>.ovpn

--

--