This article explains how to configure 2FA (two factor authentication) for OpenVPN via the google authenticator PAM plugin. The configuration example below is done on a Debian bullseye Server. If you do this on a remote connection, you should have backup access to the server if something goes wrong during configuration.

Install libpam-google-authenticator on the server

After installing and configuring openvpn in general, install the package libpam-google-authenticator:

sudo apt install libpam-google-authenticator

Create a OpenVPN specific PAM configuration:

cat /etc/pam.d/openvpn < EOF
@include common-account
auth required pam_google_authenticator.so
EOF

This configuration will enable the google authenticator PAM module for the OpenVPN daemon.

In the OpenVPN configuration the following line has to be added:

plugin /usr/lib/x86_64-linux-gnu/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn

Configure google-authenticator for a user

To enable the google authenticator for the VPN user, the user has to run google-authenticator on the server. The following questions during configuration setup should be answered according to your needs.

google-authenticator

Do you want authentication tokens to be time-based (y/n) y

<QRCODE>

Your new secret key is: <secret>
Your verification code is: <number>
Your emergency scratch codes are:
  <number>
  ....
Do you want me to update your "/home/user/.google_authenticator" file? (y/n) y

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

y default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n) y

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) y

Connect google authenticator on your smartphone

The QR-Code can now be scanned by a mobile app like Google Authenticator or similar applications on your smart phone. If a YubiKey is available, the Yubico Authenticator could also be used.

The emergency codes should be stored on a safe place e.g. a password manager like pass. They could be used to access the VPN if the access to the 2FA device get's lost.

Updating openvpn client config for google authenticator

In the openvpn client configuration, the following line has to be added:

auth-user-pass

With this line, the openvpn client will ask for a additional password before the connection is established. Now you can enter the 6 digit code on your smartphone app.

Last modified: Dec. 15, 2022

binsec GmbH
binsec GmbH is a consulting firm for information security and was founded in 2013 by security experts. Our team consists of experienced, certified specialists with different areas of expertise. Due to our extensive expertise in many different IT security fields, we can support our customers with a wide array of issues. Most of our customers are medium-sized companies, for whom security is pivotal to success.
Keywords