In my previous post, we went over how to get Google Authenticator installed on FreeNAS. Then we setup SSH to use it. In this guide, we’ll get Multi-Factor Authentication working for OpenVPN. This guide will be specific to FreeNAS, but should be applicable to FreeBSD as well.
Part I
Get Google Authenticator installed and setup for users
Go see my previous guide on getting Google Authenticator installed.
Part II
Configure OpenVPN to use both certificates and an OTP (one time password) provided by Google Authenticator.
1. Open a terminal either through the GUI or ssh.
2. Switch user to root.
su enter root password
3. Mount the file system and make it writeable
mount -uw /
4. First we need to create an entry for openvpn under /etc/pam.d This will tell OpenVPN that authentication with the pam_google_authenticator.so module is required. Also need to remember to copy this file to /conf/base/etc/pam.d so that our change will survive a reboot.
touch /etc/pam.d/openvpn printf "auth required /usr/local/lib/pam_google_authenticator.so" >> /etc/pam.d/openvpn cp /etc/pam.d/openvpn /conf/base/etc/pam.d/openvpn
5. Check to make sure the permissions are correct on the pam_google_authenticator.so module. sshd doesn’t seem to care, but OpenVPN does seem to care. Side note, there are several guides written for Linux that say you have to modify the MakeFile with LDFLAGS=”-lpam” when building the pam_google_authenticator.so module. That is NOT the case in FreeNAS / FreeBSD as the port takes care of that.
chmod 555 /usr/local/lib/pam_google_authenticator.so
6. Now we need to add a few settings to our OpenVPN server config. If you followed my guide on setting up OpenVPN on FreeNAS, your server config is on your data drive. Change the part after the “>>” to match your setup.
printf "\n#Enable Multi-Factor Authentication\n" >> /mnt/Files/openvpn/openvpn.conf printf "plugin /usr/local/lib/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn\n\n" >> /mnt/Files/openvpn/openvpn.conf printf "#Prevent re-authorization every 3600 seconds\n" >> /mnt/Files/openvpn/openvpn.conf printf "reneg-sec 0\n\n" >> /mnt/Files/openvpn/openvpn.conf
7. Now, on your client computers, you need to add the following to your openvpn-client config. You can just add it at the bottom.
#Add this to the client config to enable Multi-Factor Authentication
auth-user-pass
#Prevent the password file from being cached
auth-nocache
8. Now restart openvpn on your FreeNAS box.
service openvpn restart
Your output should look like this:
Stopping openvpn.
Waiting for PIDS: 494.
Starting openvpn.
AUTH-PAM: BACKGROUND: INIT service='openvpn'
add net 10.8.0.0: gateway 10.8.0.2
9. Make the filesystem read only again.
mount -ur /
10. Fire up your VPN connection on a client computer and you should get a field that asks for a username and password in order to connect.
You will put in your user name for one of the accounts you set up using the google-authenticator command on your FreeNAS server. The password will just be the 6 digit OTP you get from the Google Authenticator App on your smart phone. Don’t bother saving it in the keychain. If everything goes right, you will connect and then see this in your terminal session:
AUTH-PAM: BACKGROUND: received command code: 0
AUTH-PAM: BACKGROUND: USER: joe
AUTH-PAM: BACKGROUND: my_conv[0] query='Verification code: ' style=1
Part III
Questions and such…
We’ve done it. We now have multi-factor authentication setup for our VPN. I’m left wondering though. Many of the guides I looked at related to this subject said that /etc/pam.d/openvpn needed a lot more in it that what I have used. For instance, one guide over at askubuntu.com says to use this:
account [success=2 new_authtok_reqd=done default=ignore] pam_unix.so
account [success=1 new_authtok_reqd=done default=ignore] pam_winbind.so
account requisite pam_deny.so
account required pam_permit.so
auth required pam_google_authenticator.so
Is all of that account stuff really needed? My hunch is that it is not. If you have any insight, please share it in the comments section.