Skip to content

Latest commit

 

History

History
98 lines (68 loc) · 4.82 KB

otp.md

File metadata and controls

98 lines (68 loc) · 4.82 KB

Using two factor authentication for users

Instead of relying on complex passwords for client certificates (that usually get written somewhere) this image provides support for two factor authentication with OTP devices.

The most common app that provides OTP generation is Google Authenticator (iOS and Android) you can download it and use this image to generate user configuration.

Tutorial for New Installs

In order to enable two factor authentication the following steps are required.

  1. Generate server configuration with the -2 option. It's no longer necessary to supply the cipher option because OpenVPN 2.4 uses AES-256-GCM by default.

    docker run -v $OVPN_DATA:/etc/openvpn --rm registry.gitlab.com/ix.ai/openvpn ovpn_genconfig -u udp://vpn.example.com -2
  2. Init the EasyRSA PKI.

    docker run -v $PWD/data:/etc/openvpn --rm -it registry.gitlab.com/ix.ai/openvpn ovpn_initpki
  3. Generate your client certificate (possibly without a password since you're using OTP)

    docker run -v $OVPN_DATA:/etc/openvpn --rm -it registry.gitlab.com/ix.ai/openvpn easyrsa build-client-full <user> nopass
  4. Generate authentication configuration for your client. -t is needed to display the QR code, -i is also needed as google_authenticator prompts you to enter an OTP token to test. The QR code can be scanned with the Google Authenticator application. It also provides a link to a Google chart url that will display a QR code for the authentication.

    docker run -v $OVPN_DATA:/etc/openvpn --rm -it registry.gitlab.com/ix.ai/openvpn ovpn_otp_user <user>

Do not share QR code (or generated url) with anyone but final user, that is your second factor for authentication that is used to generate OTP codes

Here's an example QR code generated for an hypotetical user@example.com user.

Example QR Code

Generate client configuration for <user> and import it in OpenVPN client. On connection it will prompt for user and password. Enter your username and a 6 digit code generated by Authenticator app and you're logged in.

Tutorial for Existing Installs

If you have an existing installation with customised config, follow this tutorial instead.

  1. In openvpn.conf, add the config to enable 2FA.

    # Enable OTP+PAM for user authentication, add:
    plugin /usr/lib/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn
    reneg-sec 0
  2. In ovpn_env.sh, add the environment variable to enable 2FA

    declare -x OVPN_OTP_AUTH=1
  3. Restart the container for the new config to take effect. This step depends on your setup (ie. if it's docker or docker-compose).

  4. In the client configuration file <user>.ovpn, add the config to the end of the file.

    auth-user-pass
    auth-nocache
    reneg-sec 0
  5. Alternatively, you could regenerate the client config if yours doesn't have custom fields added.

    docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm registry.gitlab.com/ix.ai/openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn

TL;DR

Under the hood, this configuration will setup an openvpn PAM service configuration (/etc/pam.d/openvpn) that relies on the awesome Google Authenticator PAM module. In this configuration the auth part of PAM flow is managed by OTP codes and the account part is not enforced because you're likely dealing with virtual users and you do not want to create a system account for every VPN user.

ovpn_otp_user script will store OTP credentials under /etc/openvpn/otp/<user>.google_authentication. In this way when you take a backup OTP users are included as well.

Finally it will enable the openvpn plugin openvpn-plugin-auth-pam.so in server configuration and append the auth-user-pass directive in client configuration.

Debug

If something is not working you can verify your PAM setup with these commands

# Start a shell in container
docker run -v $OVPN_DATA:/etc/openvpn --rm -it registry.gitlab.com/ix.ai/openvpn bash

# Then in container you have pamtester utility already installed
which pamtester

# To check authentication use this command that will prompt for a valid code from Authenticator APP
pamtester -v openvpn <user> authenticate

In the last command <user> should be replaced by the exact string you used in the ovpn_otp_user command.

If you configured everything correctly you should get authenticated by entering a OTP code from the app.