How to setup Multi-factor Authentication with OpenVPN Community Edition
Overview of the Process
- User executes google-authenticator to generate the QR code and verification code (secrets)
- User connects a MFA enabled device by scanning the QR code presented.
- Verfication code must be installed (stored) onto the VPN server itself
- 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.
- Upon verifying, users are able to connect to the VPN.
Initial Configurations
Pre-requisites
- OpenVPN server community edition installed Instance with root privileges
- Google Authenticator enabled device
- OpenVPN client installed device
Server-side
- 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
- 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