Google Authenticator on FreeNas

Google Authenticator

Multi Factor Authentication is a useful way to tighten the security of your system.  Having it in place means that attackers can’t simply brute force your password, they need to steal your Hardware Authentication device as well.  In the case of Google Authenticator, that means stealing your phone.

Part I Get Google Authenticator installed and setup for users

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. Install the libqrencode. This is optional, but is a nice feature as it allows you to “scan” a QR code from the terminal with your smart phone.

pkg_add -r libqrencode

5. Install the Google-Authenticator PAM module

pkg_add -r pam_google_authenticator
chmod 555 /usr/local/lib/pam_google_authenticator.so

6. Install the Google Authenticator App on your smartphone. Google Play Store  Apple App Store Windows Phone – not sure if this works

7. Switch your user to the user you want to have two factor authentication. Then run google-authenticator. If you want to be all fancy, add the -l option and then a quoted string. Without that, when you scan the QR code into your Google Authenticator app it will display with an email@host description.  You can also add the user name at the end if you like.

su joe
google-authenticator -l "JoePaetzel.com:joe"

Output: Do you want authentication tokens to be time-based (y/n) y https://www.google.com/chart?chs=some_long_URL

Screen Shot 2014-05-13 at 9.40.26 AM

Your new secret key is: E3W7AB2KXXXXXX Your verification code is 78XXXX Your emergency scratch codes are: 7967XXXX 1820XXXX 1659XXXX 3623XXXX 3140XXXX Do you want me to update your "/home/joe/.google_authenticator" file (y/n) y

Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, tokens are good for 30 seconds and in order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. If you experience problems with poor time synchronization, you can increase the window from its default size of 1:30min to about 4min. Do you want to do so (y/n) n

If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting (y/n) y

8. Scan the QR code that was generated into your Google Authenticator app on your smart phone.

9. Repeat steps 7 & 8 for all the users you need to set up.

Part II. Doing something useful with Google Authenticator.

Let’s go ahead and add two factor authentication to SSH. There are several things we need to do to get that accomplished. The quick overview: 1. Make some config changes to sshd_config, some easy, some not so much 2. Tell PAM about the Google Authenticator module and how we want to use it. 3. Your homework is applying the concepts from my post on getting hacks to survive upgrades. Before we do any of that, we need to decide how we want to implement this. In my mind, it makes sense to initially allow users to login to ssh with a public key and either a Google Authenticator code or their user password. This will allow some time for everyone to get set up without any of them getting locked out. Eventually, I’ll probably switch it to require a public key and just the Google Authenticator code. The decision we make here affects how we set the sshd_config parameter AuthenticationMethods, as well as how we configure /etc/pam.d/sshd. For a more in-depth explanation of the options that AuthenticationMethods offers, please see: http://lwn.net/Articles/544640/ For a full explanation of setting up the PAM module in /etc/pm.d/sshd, please see: FreeBSD Man Pages I’ll show you how I have mine set up.

10. We need to make some configuration changes to sshd. One we can make in the terminal, the other we need to do in the FreeNAS gui.

a. Now go back to the terminal, make sure you are root. We need to change the sshd_config file in three places.

/etc/ssh/sshd_config   /etc/ix.rc.d/ix-sshd and /conf/base/etc/ix.rc.d/ix-sshd

We are making the same change in all three places.

The quick way:

sed -i -e 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config
sed -i -e 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ix.rc.d/ix-sshd
sed -i -e 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /conf/base/etc/ix.rc.d/ix-sshd

The long way (do in each of the three locations):

vi /etc/ssh/sshd_config

Scroll down to: ChallengeResponseAuthentication no

Change the no to yes. To do that in vi, put the cursor over the n in no. Hit “x” twice. Now hit “a” then type “yes”. Hit the esc key to exit insert mode. type “:wq” to write it and quit. Do not type any of the quotes.

*Feature Request*

There is a chance that in future releases all of that will become an option in the gui.

b. Open the FreeNAS gui and go to the Services tab. Click on SSH. Click on Advanced Mode button. In the extra Options Field, type:

AuthenticationMethods publickey,keyboard-interactive

c. Under Services, click on Control Services. Then turn ssh off and then back on. If we did everything right, it should start right up.

11. Now we need to edit the /etc/pam.d/sshd file so that pam knows to use Google Authenticator.  There a couple of options you have for this…like required, requisite or sufficient.  We’ll use sufficient for now so that we have the option of using the Google code or a password.  Later on we will change it to required so that there is no longer the password option.  Here’s what it looks like to start with:

# # $FreeBSD: src/etc/pam.d/sshd,v 1.18 2009/10/05 09:28:54 des Exp $ # # PAM configuration for the "sshd" service #

# auth auth sufficient pam_opie.so no_warn no_fake_prompts auth requisite pam_opieaccess.so no_warn allow_local #auth sufficient krb5.so no_warn try_first_pass #auth sufficient pam_ssh.so no_warn try_first_pass auth required pam_unix.so no_warn try_first_pass

# account account required pam_nologin.so account required pam_login_access.so account required pam_unix.so

# session #session optional pam_ssh.so want_agent session required pam_permit.so

# password password required pam_unix.so no_warn try_first_pass

What we want to do is add “auth sufficient /usr/local/lib/pam_google_authenticator.so” after “#auth sufficient pam_ssh.so no_warn try_first_pass” and before “auth required pam_unix.so no_warn try_first_pass” You can either do it the long way with vi or the quick way with awk

awk '{ print $0; if(NR == 11) printf("auth            sufficient      '/usr/local/lib/pam_google_authenticator.so'\n"); }' /etc/pam.d/sshd > /etc/pam.d/sshd-temp && mv /etc/pam.d/sshd-temp /etc/pam.d/sshd

We should run cat on the file to make sure it turned out the way we want it.

cat /etc/pam.d/sshd

Output should be:

# # $FreeBSD: src/etc/pam.d/sshd,v 1.18 2009/10/05 09:28:54 des Exp $ # # PAM configuration for the "sshd" service #

# auth auth sufficient pam_opie.so no_warn no_fake_prompts auth requisite pam_opieaccess.so no_warn allow_local #auth sufficient krb5.so no_warn try_first_pass #auth sufficient pam_ssh.so no_warn try_first_pass auth sufficient /usr/local/lib/pam_google_authenticator.so auth required pam_unix.so no_warn try_first_pass

# account account required pam_nologin.so account required pam_login_access.so account required pam_unix.so

# session #session optional pam_ssh.so want_agent session required pam_permit.so

# password password required pam_unix.so no_warn try_first_pass

Also need to do the same with /conf/base/etc/pam.d/sshd and /conf/base/etc/ix/templates/pam.d/sshd

awk '{ print $0; if(NR == 11) printf("auth            sufficient      '/usr/local/lib/pam_google_authenticator.so'\n"); }' /conf/base/etc/pam.d/sshd > /conf/base/etc/pam.d/sshd-temp && mv /conf/base/etc/pam.d/sshd-temp /conf/base/etc/pam.d/sshd

awk '{ print $0; if(NR == 11) printf("auth            sufficient      '/usr/local/lib/pam_google_authenticator.so'\n"); }' /conf/base/etc/ix/templates/pam.d/sshd > /conf/base/etc/ix/templates/pam.d/sshd-temp && mv /conf/base/etc/ix/templates/pam.d/sshd-temp /conf/base/etc/ix/templates/pam.d/sshd

12. Now go read my article about getting hacks to stick and survive upgrades.  Apply that logic to this hack and enjoy Multi-Factor Authentication even after system upgrades. 13. Change the root folder back to read only.

mount -ur /

Final Thoughts

That should be everything.  Try logging in over ssh and you should get a prompt for your Verification Code

Seven:~ joe$ ssh 192.168.0.122 Authenticated with partial success. Verification code:

I need to give credit to Randy who wrote the foundation for much of this guide over at http://www.nytechgroup.com

http://www.nytechgroup.com/2011/10/05/two-factor-authentication-freebsd/

Make sure to also check out my guide on getting OpenVPN working with Google Authenticator.

Advertisement

24 thoughts on “Google Authenticator on FreeNas

  1. Pingback: Enable Multi-Factor Authentication for OpenVPN | The Joe Paetzel Method

  2. I’ve found a problem with the last version of freenas, after hours I’ve figured out that i need to move /usr/local/lib/pam_google_authenticator.so to /usr/lib/ otherwise it will give an error that can’t find it.
    Maybe can be helpful to somebody.
    Thank you for the well done job in this blog.

  3. Joe, had a lot of hope for this to work and it looks like your feature for this will be in the next major release. When attempting this now though I get the below:

    [root@freenas] ~# pkg_add -r pam_google_authenticator
    Error: Unable to get ftp://ftp.freebsd.org/pub/FreeBSD/ports/amd64/packages-9-st able/Latest/pam_google_authenticator.tbz: No address record
    pkg_add: unable to fetch ‘ftp://ftp.freebsd.org/pub/FreeBSD/ports/amd64/packages -9-stable/Latest/pam_google_authenticator.tbz’ by URL

    Thoughts?

    • Try creating a new jail. I’ve had much headache with jails after one of the last few upgrades. Seems like using a standard jail has worked the best for me. Otherwise, you can try installing it from the ports tree and compiling it. 1) portsnap fetch 2) portsnap extract 3) cd /usr/ports/security/pam_google_authenticator 4) make install

  4. Hi,
    I am using FreeNAS 9.3-RELEASE but the commands pkg_add -r libqrencode and pkg_add -r pam_google_authenticator are not working.
    I tryied pkg install but that didn’t worked either.

    Can you help?
    Thank you

    • In 9.3, pam_google_authenticator should already be included, if I remember right. Is your filesystem writeable? Not sure what else would be the issue. Would help if you provided any error messages. Maybe try it without the -r switch.

      • Yes you are righth pam_google_authenticator is already in /usr/local/lib/
        But I cannot run google-authenticator when I switch to my user:
        su freenasadmin
        google-authenticator -l “mycompagnyname:freenasadmin”
        Failed to create “/nonexistent/.google_authenticator” (Permission denied)freenasadmin@SRV-FREENAS-NSP:~ %
        Can you help from that error message?

  5. Sure. Looks like you have your user set as a nonexistent user. That won’t work. Set your user to have a shell associated to them. You can do that in the User tab of the FreeNas UI if you don’t know how to from the command line.

  6. Got all the way to Step 11. I’m having issues inputting the awk command. Im in FreeNas shell and when I type the command “awk ‘{ print $0; if(NR == 11) printf(“auth sufficient……” etc i get the error;

    “awk: non-terminated string auth … at source line 1
    context is
    >>> <<<
    awk: giving up
    source line number 2 "

    Any ideas? I'm very new to this type of language.
    Im running FreeNAS-9.2.1.8-RELEASE-x64 (e625626)

    • Hi Ryan. You can do all of that manually…awk just allowed me to “automate it” for the purpose of the tutorial. So if you edit /etc/pam.d/sshd using the vi, you can add at the end of the file “auth sufficient ‘/usr/local/lib/pam_google_authenticator.so'” Without the double quotes, but with the single quotes. No need to make the /etc/pam.d/sshd-temp file, just go ahead and edit /etc/pam.d/sshd

  7. I must be very blonde. But after some difficulties and research I suspect this entire process should be performed inside a Jail?

    None the less, thank you for taking the time to document all of this, and for replying to comments 2 years later.

    • If I recall, I did not do any of this in a jail. It takes a little more effort to get things to survive upgrades. My issue two years ago was routing into the jail was not easy. I think that has been fixed in since updates. What issue are you having?

      • I couldn’t install anything.

        I did a clean install in a virtual environment.

        FreeBSD 10.3-RELEASE-p3 (FreeNAS.amd64) #0 215c0d0(9.10-STABLE): Mon May 23 21:4 [root@testbed] ~# pkg install libqrencode
        Updating local repository catalogue…
        pkg: file:///usr/ports/packages/meta.txz: No such file or directory
        repository local has no meta file, using default settings
        pkg: file:///usr/ports/packages/packagesite.txz: No such file or directory
        Unable to update repository local
        All repositories are up-to-date.
        pkg: No packages available to install matching ‘libqrencode’ have been found in the repositories

        I thought I had DNS problems:
        [root@testbed] ~# ping google.com
        PING google.com (220.244.136.20): 56 data bytes
        64 bytes from 220.244.136.20: icmp_seq=0 ttl=59 time=23.753 ms
        64 bytes from 220.244.136.20: icmp_seq=1 ttl=59 time=28.746 ms
        — google.com ping statistics —
        6 packets transmitted, 6 packets received, 0.0% packet loss
        round-trip min/avg/max/stddev = 23.350/25.578/29.338/2.471 ms

        However install of pam_google_authenticator indicates it possibly is already installed (I might have done it and forgotten).
        [root@testbed] ~# pkg install pam_google_authenticator
        Updating local repository catalogue…
        pkg: file:///usr/ports/packages/meta.txz: No such file or directory
        repository local has no meta file, using default settings
        pkg: file:///usr/ports/packages/packagesite.txz: No such file or directory
        Unable to update repository local
        All repositories are up-to-date.
        Checking integrity… done (0 conflicting)
        The most recent version of packages are already installed

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