Google Authenticator multi-factor authentication
Operating principle and function
Google multi-factor authentication (MFA) works on the principle of Time-based One Time Password (TOTP). The server and client agree on a shared key for each user. Using that key, and the current time and date, a calculation is done that yields a six-digit code. The server and client both do this calculation and the results match. During login, the client sends its result to the server and the user successfully signs in when if it matches. It does not match if either the shared key is wrong or the time and date are wrong on the device(s). To ensure the time and date are correct on OpenVPN Access Server, our prepared installation images come with an NTP client program to synchronize the time automatically via the internet. On the client device, however you'll have to ensure that the time and date are accurate.
You need an app like Google Authenticator or Microsoft Authenticator or any app that is capable of generating TOTP codes. The typical method of transferring the shared key from the server to the client is by scanning a QR code during the enrollment phase, but manual input is also possible. Once enrolled, when a user signs in with their credentials, they must enter a six-digit code. The six-digit codes are only valid for 30 seconds. After that, a new code is generated. In order to accommodate some small deviations in time drift we allow the codes immediately preceding and following the current code to also be accepted by Access Server.
The advantage of this added multi-factor authentication is that even if somehow your credentials are leaked, an attacker cannot sign in under your account because he does not have your app or device that generates the unique six-digit response codes. Even if someone is reading over your shoulder as you enter your credentials followed by the six-digit code, they can't really do anything with it, since 30 seconds later, it's expired. It is also important to note that at no point is a connection with Google's systems made when generating the unique shared code, enrolling a user, or generating the six-digit response codes. Google Authenticator is simply a popular program that uses time-based one-time password standard methods to allow MFA. More information on the conceptual and technical aspects of Google Authenticator can be found on this Google Authenticator WikiPedia page.
How to enable Google Authenticator MFA
OpenVPN Access Server supports the Google Authenticator MFA system, but it is not enabled by default. To enable it globally:
- Sign in to our Admin Web UI.
- Click Authentication > General (Access Server version 2.7.5 and newer) or Client Settings (Access Server version 2.7.4 and older).
- Enable Google Authenticator MFA, save and update your server.
Note: If you are using MFA added by post-auth script, enabling Google MFA will break user authentication. Ensure that no other MFA is enabled when enabling Google MFA.
Alternatively, you can be enable Google MFA for all users using the command line with the example commands given below.
You can also enable Google Authenticator for a user or a group using the command line. This can be important if, for example, a client device making a VPN connection is unable to provide the Google Authenticator key by itself. To use Google Authenticator you need an application or device that can accept a Google Authenticator type shared secret, and with that generate six-digit codes every 30 seconds. A smartphone with Android or Apple iOS with the free Google Authenticator app installed can do this. There are also plugins for browsers and applications for tablets and desktop computers, as well as separate credit card sized (or smaller) devices that can be provided with the unique key and can generate keys for years with the built-in battery keeping the clock going.
Command line configuration parameters
These commands are all assumed to be run as root user in the /usr/local/openvpn_as/scripts/ directory.
Disable Google Authenticator globally for all users and groups (the default):
./sacli --key "vpn.server.google_auth.enable" --value "false" ConfigPut ./sacli start
Enable Google Authenticator globally for all users and groups:
./sacli --key "vpn.server.google_auth.enable" --value "true" ConfigPut ./sacli start
Disable Google Authenticator for a specific user or group:
./sacli --user <USER_OR_GROUP> --key "prop_google_auth" --value "false" UserPropPut
Enable Google Authenticator for a specific user or group:
./sacli --user <USER_OR_GROUP> --key "prop_google_auth" --value "true" UserPropPut
Remove the setting restore default behavior:
./sacli --user <USER_OR_GROUP> --key "prop_google_auth" UserPropDel
Unlock the user's MFA code so the user can enroll on the web interface:
./sacli --user <USER> --lock 0 GoogleAuthLock
Lock the user's MFA code so the user cannot obtain/scan it on the web interface:
./sacli --user <USER> --lock 1 GoogleAuthLock
See the current MFA code in use for a particular user:
./sacli --pfilt <USER> UserPropGet | grep "pvt_google_auth_secret"
Check if MFA code is locked — a 1 or true means it is locked:
./sacli --pfilt <USER> UserPropGet | grep "pvt_google_auth_secret_locked"
Generate a new MFA code and unlock it so the user can enroll anew on the web interface:
./sacli --user <USER> --lock 0 GoogleAuthRegen
Generate a new MFA code and lock it so the user cannot enroll on the web interface:
./sacli --user <USER> --lock 1 GoogleAuthRegen
The GoogleAuthLock and GoogleAuthRegen functions manage these two keys:
- pvt_google_auth_secret — A 16 character alphanumerical value in capitals containing the MFA shared key.
- pvt_google_auth_secret_locked — A value either true (1) or false (0) indicating enrollment is completed.
Initially, the MFA shared key is not locked. In this state, the user can sign in on the web interface and obtain the MFA shared key that an app can use to generate six-digit MFA codes. After the user has successfully enrolled, the shared key is locked and the user must then enter their MFA key to sign in from then on.
If a user’s device that contains the Google Authenticator application with the MFA shared key in it gets lost, stolen, or otherwise compromised, use the sacli GoogleAuthRegen command as shown in the examples above to generate a new unique secret key for their account, making it impossible for the old secret key to be used. This command also unlocks the account Google Authenticator enrollment so that the user can enroll again. As an aside, the GoogleAuthRegen command also generates on the command line a string with otpauth:// URI format that can be used in a QR code generator. In the client web service, Access Server already does this for the user, but this could be helpful for customized process automation.
Auto-login profiles and MFA
Server-locked and user-locked profiles both adhere to the requirement for multi-factor authentication. However, by default, auto-login profiles do not adhere to this requirement. It is assumed that auto-login profiles are used for unattended devices such as servers in datacenters that must establish a connection autonomously without having to prompt a user for the six-digit MFA code.
If you do wish to enable MFA on an auto-login profile you can use this parameter:
./sacli --user <USER_OR_GROUP> --key "prop_google_auth_autologin" --value "true" UserPropPut ./sacli start
This requires all of the following to be met:
- The user has the auto-login privilege.
- An auto-login profile is installed on the VPN client.
- The VPN client is a modern VPN client such as OpenVPN Connect v3.3 or better.
- The requirement for MFA is enabled and configured for this user or group.
Bootstrap user accounts and MFA
The bootstrap administrative user account, openvpn, is an exception to the Google Authenticator requirement. Any other bootstrap users added manually to as.conf can also sign in without having to enter a (valid) Google Authenticator code. In certain configuration circumstances, a VPN client may still ask for an MFA code for such a user but any code is then accepted. This is done on purpose so that this user can always sign in and correct problems — the MFA requirement is bypassed for this type of special bootstrap account. During initial configuration, it is possible to specify a different user name for the initial administrative bootstrap account. By default, it is called openvpn.
This of course begs the question on how to secure this account when you want Google Authenticator to be required. The suggested solution is to create a new normal user account in Access Server, grant admin privileges and enrolling the user in Google Authenticator. This will then be your new administrative user account for the Admin Web UI and requires a valid Google Authenticator code to sign in. You can then disable the bootstrap administrative user account so that it cannot be used to sign in. Refer to these instructions on how to secure the openvpn administrative user account.