Enable Multi-Factor Authentication for OpenVPN

Google Authenticator and OpenVPN

Google Authenticator and OpenVPN

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.

Tunnelblick

 

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.

Advertisement

20 thoughts on “Enable Multi-Factor Authentication for OpenVPN

  1. Pingback: Google Authenticator on FreeNas | The Joe Paetzel Method

  2. Pingback: OpenVPN on FreeNas 9.1 | The Joe Paetzel Method

  3. quote:
    “The password will just be the 6 digit OTP you get from the Google Authenticator App on your smart phone.”

    Isn’t this single factor authentication?

    • If it were just the OTP 6 digit password, then yes, but it also requires your user name. So, your user name is the something you know and the OTP password is the something you have. Not to mention your RSA key pair.

      • You hit connect, then a login window pops up asking for a user name and “password”. Not sure technically what sequence things are happening behind the scenes.

      • It does. I think maybe you missed it.

        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

      • Sorry to still miss it. The word “just” in this sentence means to me that there isn’t any field to enter your password: “The password will just be the 6 digit OTP you get from the Google Authenticator App on your smart phone”. And the screen shot only has one field shown. Some implementations use a colon to separate the OTP and password in order to get both into one field.

      • Multi-factor implies both a secret password and the OTP integer. Are you saying that my password is the OTP? If so, than it isn’t multi-factor. If there are both, then how do I input the account password?

      • Hi Jim-
        I do not recommend using password auth on your VPN. My tutorial shows you how to set up OpenVPN using a key pair. So factor 1 is your key pair. Factor two is your user name. Factor three is your OTP password. So in my scenario, I have two things (key and OTP device) and know one (user name). Some people consider a key pair as something you know…but I have no desire to debate that. As I have never setup a VPN with password auth, I can not tell you how to enter your user password. I’d recommend using a key pair instead.

  4. Dear Joe,

    I can connect to my openVPN server without inputting the Google authorization code (just a blank space or anything in the password field). Might the last few last be necessary for denying the connection?

    • Hi Patrik.

      It looks like you don’t have these lines loaded in your openvpn server config:

      #Enable Multi-Factor Authentication
      plugin /usr/local/lib/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn

      #Prevent re-authorization every 3600 seconds
      reneg-sec 0

      The Plugin line is the one that tells OpenVPN to require a valid Google Authenticator password. It is possible that you have those lines in your config, but did not stop and restart your running OpenVPN server. To do that, log in as root and type:

      service openvpn stop
      service openvpn start

      Hope that all helps.

      • Thanks Joe,
        I made a typo when using the printf commands in your guide and did not restart the server. Actually I am using NAS4Free, and was somewhat modifying your guides to make it work for me. I couldn’t login afterwards. The problem was, the system time of the server was not correct. I recommend using an NTP server on your FreeNAS or NAS4Free to ensure time is always correct. You might want to highlight that in the guide, if people can’t log in.

        Cheers,

        Patrik

  5. Hi Joe,

    First thank you for sharing these great tutorials, I find them amazing.
    I know this post is a from 2014 and I wonder if this is the reason why I cannot get it to work.. Could you please help?

    I am runing FreeNAS 9.3 and when I do server openvpn restart, I haven’t got the same output than you

    Stopping openvpn.
    Starting openvpn.
    route: writing to routing socket: File exists
    add net 192.168.0.108: gateway 10.8.0.1 fib 0: route already in table
    add net 10.8.0.0: gateway 10.8.0.2

    When I try to connect I type my username and the code generated on my phone but I keep getting the following error:

    From client log:

    ERROR: could not read Auth username/password/ok/string from management interface
    Fri Apr 22 11:34:09 2016 Exiting due to fatal error

    From FreeNAS log (I changed the names and ip):

    Apr 22 11:37:06 SRV-FREENAS-NSP openvpn[6445]: 82.27.xxx.xxx:62004 TLS: Initial packet from [AF_INET]82.27.xxx.xxx:62004, sid=a6a15fa4 a44ddb7b
    Apr 22 11:37:07 SRV-FREENAS-NSP openvpn[6445]: 82.27.xxx.xxx:62004 VERIFY OK: depth=1, C=GB, ST=Yorkshire, L=mycity, O=myltd, OU=Accounting-Dept, CN=SRV-FREENAS-NSP.myltd, emailAddress=liz@mydomain.com
    Apr 22 11:37:07 SRV-FREENAS-NSP openvpn[6445]: 82.27.xxx.xxx:62004 VERIFY OK: depth=0, C=GB, ST=Yorkshire, L=mycity, O=myltd, OU=Accounting-Dept, CN=first.last, emailAddress=me@mydomain.com
    AUTH-PAM: BACKGROUND: user ‘myuser’ failed to authenticate: session failure
    Apr 22 11:37:07 SRV-FREENAS-NSP openvpn[6445]: 82.27.xxx.xxx:62004 PLUGIN_CALL: POST /usr/local/lib/openvpn/plugins/openvpn-plugin-auth-pam.so/PLUGIN_AUTH_USER_PASS_VERIFY status=1
    Apr 22 11:37:07 SRV-FREENAS-NSP openvpn[6445]: 82.27.xxx.xxx:62004 PLUGIN_CALL: plugin function PLUGIN_AUTH_USER_PASS_VERIFY failed with status 1: /usr/local/lib/openvpn/plugins/openvpn-plugin-auth-pam.so
    Apr 22 11:37:07 SRV-FREENAS-NSP openvpn[6445]: 82.27.xxx.xxx:62004 TLS Auth Error: Auth Username/Password verification failed for peer
    Apr 22 11:37:07 SRV-FREENAS-NSP openvpn[6445]: 82.27.xxx.xxx:62004 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 4096 bit RSA
    Apr 22 11:37:07 SRV-FREENAS-NSP openvpn[6445]: 82.27.xxx.xxx:62004 [first.last] Peer Connection Initiated with [AF_INET]82.27.xxx.xxx:62004
    Apr 22 11:37:09 SRV-FREENAS-NSP openvpn[6445]: 82.27.xxx.xxx:62004 PUSH: Received control message: ‘PUSH_REQUEST’
    Apr 22 11:37:09 SRV-FREENAS-NSP openvpn[6445]: 82.27.xxx.xxx:62004 Delayed exit in 5 seconds
    Apr 22 11:37:09 SRV-FREENAS-NSP openvpn[6445]: 82.27.xxx.xxx:62004 SENT CONTROL [first.last]: ‘AUTH_FAILED’ (status=1)
    Apr 22 11:37:14 SRV-FREENAS-NSP openvpn[6445]: 82.27.xxx.xxx:62004 SIGTERM[soft,delayed-exit] received, client-instance exiting

    when I comment
    plugin /usr/local/lib/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn
    and
    reneg-sec 0
    and restart, I can get access again but obviously without autentification

    • Check your owner and permissions for /etc/pam.d/openvpn and the .google_authenticator file you created for your user. You did set up a .google_authenticator file for the user you are trying to log in as and not root right?

  6. Hey Joe first wanna say thank you for the helpfull tutorials you make. I was wondering if it was possible to make the multifactor login for the VPN client with a User, Password+Google Authenticator Code so it is more secured. I’m currently working with Linux Ubutu but can’t get the google authenticator part to work so I wanna try your tutorials instead.

  7. hello, i am failed allow your piont.
    is version different?
    [root@vpnserver openvpn]# rpm -qa|grep openvpn
    openvpn-2.3.11-1.el6.x86_64
    ==========================================openvpn.log
    [root@vpnserver openvpn]# tail -f /var/log/openvpn.log
    Sun Aug 28 21:44:24 2016 us=562415 192.168.14.1:60087 PLUGIN_CALL: plugin function PLUGIN_AUTH_USER_PASS_VERIFY failed with status 1: /usr/lib64/openvpn/plugin/lib/openvpn-auth-pam.so
    Sun Aug 28 21:44:24 2016 us=562495 192.168.14.1:60087 TLS Auth Error: Auth Username/Password verification failed for peer
    WRSun Aug 28 21:44:24 2016 us=566113 192.168.14.1:60087 Control Channel: TLSv1.2, cipher TLSv1/SSLv3 DHE-RSA-AES256-GCM-SHA384, 2048 bit RSA
    Sun Aug 28 21:44:24 2016 us=566225 192.168.14.1:60087 [lanny] Peer Connection Initiated with [AF_INET]192.168.14.1:60087
    RSun Aug 28 21:44:27 2016 us=35673 192.168.14.1:60087 PUSH: Received control message: ‘PUSH_REQUEST’
    Sun Aug 28 21:44:27 2016 us=36005 192.168.14.1:60087 Delayed exit in 5 seconds
    Sun Aug 28 21:44:27 2016 us=36073 192.168.14.1:60087 SENT CONTROL [lanny]: ‘AUTH_FAILED’ (status=1)
    WWSun Aug 28 21:44:27 2016 us=243375 192.168.14.1:60087 Connection reset, restarting [0]
    Sun Aug 28 21:44:27 2016 us=243473 192.168.14.1:60087 SIGUSR1[soft,connection-reset] received, client-instance restarting
    Sun Aug 28 21:44:27 2016 us=243614 TCP/UDP: Closing socket
    ===================================================
    server.conf
    port 1194
    proto tcp
    dev tun
    ca keys/ca.crt
    cert keys/server.crt
    key keys/server.key
    dh keys/dh2048.pem
    server 10.8.0.0 255.255.255.0
    ifconfig-pool-persist ipp.txt
    push “route 172.16.24.0 255.255.255.0”
    client-to-client
    duplicate-cn
    keepalive 10 120
    tls-auth keys/ta.key 0
    comp-lzo
    persist-key
    persist-tun
    status openvpn-status.log
    log-append /var/log/openvpn.log
    verb 5
    plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-pam.so /etc/pam.d/openvpn
    reneg-sec 0
    ===========================================================
    [root@vpnserver openvpn]# cat /etc/pam.d/openvpn
    auth required pam_google_authenticator.so
    ========================================
    wait u reply, thk my friend

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s