2016-02-07 13:28:45 +00:00
# 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](https://itunes.apple.com/it/app/google-authenticator/id388497605?mt=8) and
[Android ](https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=it )) you can download it
and use this image to generate user configuration.
## Usage
In order to enable two factor authentication the following steps are required.
2017-01-24 14:37:48 +00:00
* Choose a more secure [cipher ](https://community.openvpn.net/openvpn/wiki/SWEET32 ) to use because since [OpenVPN 2.3.13 ](https://community.openvpn.net/openvpn/wiki/ChangesInOpenvpn23#OpenVPN2.3.13 ) the default openvpn cipher BF-CBC will cause a renegotiated connection every 64 MB of data
* Generate server configuration with `-2` and `-C $CIPHER` options
2016-02-07 13:28:45 +00:00
2017-01-24 14:42:51 +00:00
docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://vpn.example.com -2 -C $CIPHER
2016-02-07 13:28:45 +00:00
* Generate your client certificate (possibly without a password since you're using OTP)
2016-09-03 23:08:49 +00:00
docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full < user > nopass
2016-02-07 13:28:45 +00:00
* Generate authentication configuration for your client. -t is needed to show QR code, -i is optional for interactive usage
2016-09-03 23:08:49 +00:00
docker run -v $OVPN_DATA:/etc/openvpn --rm -t kylemanna/openvpn ovpn_otp_user < user >
2016-02-07 13:28:45 +00:00
The last step will generate OTP configuration for the provided user with the following options
```
google-authenticator --time-based --disallow-reuse --force --rate-limit=3 --rate-time=30 --window-size=3 \
-l "${1}@${OVPN_CN}" -s /etc/openvpn/otp/${1}.google_authenticator
```
It will also show a shell QR code in terminal you can scan with the Google Authenticator application. It also provides
a link to a google chart url that will display a QR code for the authentication.
**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 ](https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/user@example.com%3Fsecret%3DKEYZ66YEXMXDHPH5 )
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.
## 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 ](https://github.com/google/google-authenticator ).
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
2016-09-03 23:08:49 +00:00
docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn bash
2016-09-03 11:23:19 +00:00
# Then in container you have pamtester utility already installed
which pamtester
2016-02-07 13:28:45 +00:00
# To check authentication use this command that will prompt for a valid code from Authenticator APP
pamtester -v openvpn < user > authenticate
```
2016-09-03 11:23:19 +00:00
In the last command `<user>` should be replaced by the exact string you used in the ovpn_otp_user command.
2016-02-07 13:28:45 +00:00
If you configured everything correctly you should get authenticated by entering a OTP code from the app.