OpenVPN Security Advisory: Dec 14, 2018
Action needed: Important update for OpenVPN Access Server

Google Authenticator multi-factor authentication

Operating principle and function

The basic principle of how Google Authenticator works is reasonably simple but very secure. When this option is enabled on the Access Server, the server generates a unique key of 16 random characters which is different for each user account. When the user logs on and has not yet enrolled in Google Authenticator, the user must enroll. This enrollment process is simply the act of logging on to the Access Server’s client web service, and then transferring this unique key to a device or program that the user has. For example, you as a user can install the Google Authenticator app on your smartphone and add the key in there. This is usually accomplished by scanning a QR code on the client web service of the Access Server during the enrollment process but can also be manually entered. After this step is completed, both the server and user device hide this unique key from view.

The client device uses this unique key plus the current time and date and uses these two items together to create a 6 digit response code every 30 seconds. This does mean the time and date need to be accurate on both the server and client side. Our OpenVPN Access Server cloud images and appliance images now run on an operating system that updates the time and date automatically via the Internet, and a similar method of keeping time synchronized is usually present in a smartphone as well. This is usually done via Network Time Protocol using NTP or chrony or other similar software. If the unique key agreed upon between the Access Server and the Google Authenticator compatible app/device are the same on both ends, and the time and date are also correct, then they should both always result in the same 6 digit response code.

Now when the user logs on, after checking username and password, a 6 digit Google Authenticator response code should also be entered. If it is correct, the user will be allowed to log on. If it is incorrect, because the unique key stored in the app/device is the wrong one, or because the time and date are off, then the user cannot log in. There is an inherent time limit on the 6 digit response codes. They are only valid for 30 seconds, after that, a new code is generated. In order to accommodate some small deviation in time drift we allow the code immediately preceding and following the current code to also be accepted.

The advantage of this added multi-factor authentication is that even if somehow your credentials are leaked, an attacker cannot log in under your account because he does not have your app or device that is generating the unique 6 digit response codes. Even if someone is reading over your shoulder as you enter your credentials followed by the 6 digit code they can’t really do anything with it, since 30 seconds later, it’s already an expired and useless code. It is also important to note that at no point a connection with Google’s systems is made when generating the unique shared code, enrolling a user, or generating the 6 digit response codes. It is simply a popular program that uses time-based one-time password standard methods to allow multi-factor authentication. 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

The Access Server supports the Google Authenticator multi-factor authentication system, but it is not enabled by default. It can be enabled globally via the admin web service in the section titled “Client Settings" (AS 2.7.4 and older) or via the “Authentication" section (AS 2.7.5 and newer) or via the command line with the command line examples given below. It is also possible to enable or disable the requirement for a Google Authenticator per user or per group on the command line. This can be important if for example for some reason 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 6 digit codes that change every 30 seconds. For example, 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 off the built-in battery.

Command line configuration parameters

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

Undo an enable/disable override for Google Authenticator on a group or user, so that it inherits the setting instead:

./sacli --user <USER_OR_GROUP> --key "prop_google_auth" UserPropDel

To unlock an already scanned and locked secret for a user, so the user can obtain/scan it again:

./sacli --user <USER> --lock 0 GoogleAuthLock

To manually lock a secret key, for example when you as administrator have already set up the user’s device yourself:

./sacli --user <USER> --lock 1 GoogleAuthLock

To generate a new secret key and unlock it so the user can enroll anew:

./sacli --user <USER> --lock 0 GoogleAuthRegen

To generate a new secret key and lock it so the user must obtain the secret key from the server administrator:

./sacli --user <USER> --lock 1 GoogleAuthRegen

The GoogleAuthLock and GoogleAuthRegen functions that actually handle these two keys, which can also be edited manually:

./sacli --user <USER> --key "pvt_google_auth_secret" --value <GOOGLE_AUTH_SECRET> UserPropPut
./sacli --user <USER> --key "pvt_google_auth_secret_locked" --value <SCANNED/LOCKED> UserPropPut

Where <GOOGLE_AUTH_SECRET> must be a 16 character alphanumerical value in capitals and must be known at the Google Authenticator device/application to generate the 6 digit codes, and the <SCANNED/LOCKED> value must be either 1 or 0, indicating that the code is scanned and must now be used by the user, or is awaiting enrollment by the user.
If a user’s device that contains the Google Authenticator application with the shared key in it has been lost, stolen, or otherwise compromised, you should use the sacli GoogleAuthRegen command as shown in the examples above to generate a new unique secret key for his 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. Of course in the client web service the Access Server already does this for the user, but this could be some use for customized process automation.

Exceptions to Google Authenticator requirement

An exception to the Google Authenticator requirement is for obvious reasons any client using the auto-login type connection profiles. A common problem people encounter is creating a user account with auto-login privileges, and then downloading and installing an OpenVPN Connect Client from the Access Server. Such an installation will come bundled with an auto-login type profile. Enabling the Google Authenticator afterwards on such an account will not make this Connect Client installation require a Google Authenticator password to make a connection. It will simply use its stored copy of the auto-login type profile to make a connection. To resolve this, remove the auto-login privilege from this user account, and uninstall the already installed Connect Client and download a new copy from the client web service and install it. It will then be configured with a server-locked connection profile, and will ask for user name, password, and Google Authenticator to make a connection. Of course don’t forget to enroll the user with a Google Authenticator application or else you will receive a message telling you that the user must complete enrollment into Google Authenticator before a connection can be made.

Another exception to the Google Authenticator requirement is less obvious. The default bootstrap administrative user account called ‘openvpn’ is an exception to the requirement for Google Authenticator. It can log in without having to enter a valid Google Authenticator code. Due to certain configuration options, it might ask for a code, but it may then accept any code you enter for this account. This is done on purpose so that this user can always log in and correct problems. So if you are testing with this account and aren’t asked for Google Authenticator code, you now know why this is so. Also, during initial configuration, it is possible to reconfigure the user name so it does not specifically have to be called openvpn, but in most cases it is by default.

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 the Access Server and giving it admin privileges and enrolling it in Google Authenticator. This will then be your new administrative user account for the Admin UI. And this account will require a valid Google Authenticator code to log on. Then disable the bootstrap administrative user account so that it cannot be used to log on. Please refer to the instructions on how to secure the openvpn administrative user account on how to accomplish this.

Share