cheap two factor authentication with google

2011-07-18

I can be a glutton for punishment for a nearly trivial amount of gain. So lets bring on the two-factor authentication for my personal FreeBSD server.

I’ve been using Google’s 2-step verification since Jenny told me about it, along with my android powered phone.

What is nice about Google’s Authenticator app is its availability for multiple smartphone platforms:

  • Android version 1.5 or later
  • BlackBerry OS 4.2 - 4.7
  • iPhone iOS 4 or later

How it works is pretty simple. First, you have to install the GAuthenticator app form whatever market your smartphone uses. Once you convert your Google account, you are presented with a QR code, which you can scan with your smart phone. This ties your phone’s GAuth app to your account.

I’ve been doing this for the last month or so, and everything has been working out just fine. There are a lot of cool things you can do with this extra layer of authentication. Since not all web services or applications support the verification code generated from your phone, you can have backup passwords (which are only usable once, but great if you don’t have your phone with you), as well as application passwords. These static and randomly generated passwords are revoke-able.

Alright, so, how does this apply as a cheap way to do two-factor authentication?

Okay, I know, a phone isn’t exactly cheap. I’m sure a RSA token, or (expecially) a Gooze token or far more economical if you don’t already have a iPhone, Android or BB.

A lot of people in IT do have one of these phones, and the app is free. Hence me calling this cheap…

Anyway, the Google Authenticator project also has a PAM module, it is really simple and easy to compile/install. Simple check out the mercurial repository and use gmake to compile:

[server]-[mcarlson] 9:40pm: ~/projects/google-authenticator/libpam>gmake
gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -o google-authenticator.o google-authenticator.c
gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -o base32.o base32.c
gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -o hmac.o hmac.c
gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -o sha1.o sha1.c
gcc -g   \
    -o google-authenticator google-authenticator.o base32.o hmac.o sha1.o
gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -o pam_google_authenticator.o pam_google_authenticator.c
pam_google_authenticator.c: In function 'log_message':
pam_google_authenticator.c:69: warning: implicit declaration of function 'pam_get_item'
gcc -shared -g  -o pam_google_authenticator.so pam_google_authenticator.o base32.o hmac.o sha1.o
gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -o demo.o demo.c
gcc -DDEMO --std=gnu99 -Wall -O2 -g -fPIC -c  -o pam_google_authenticator_demo.o pam_google_authenticator.c
pam_google_authenticator.c: In function 'log_message':
pam_google_authenticator.c:69: warning: implicit declaration of function 'pam_get_item'
gcc -g  -rdynamic                                         \
    -o demo demo.o pam_google_authenticator_demo.o base32.o hmac.o sha1.o
gcc -DTESTING --std=gnu99 -Wall -O2 -g -fPIC -c  -o pam_google_authenticator_testing.o pam_google_authenticator.c
pam_google_authenticator.c: In function 'log_message':
pam_google_authenticator.c:69: warning: implicit declaration of function 'pam_get_item'
gcc -shared -g  -o pam_google_authenticator_testing.so pam_google_authenticator_testing.o base32.o hmac.o sha1.o
gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -o pam_google_authenticator_unittest.o pam_google_authenticator_unittest.c
gcc -g  -rdynamic -lc                                     \
        \
    -o pam_google_authenticator_unittest pam_google_authenticator_unittest.o base32.o hmac.o sha1.o

At this point, as root, you can install the two important files:

   
[server]-[mcarlson] 9:42pm: ~/projects/google-authenticator/libpam>sudo gmake install
Password:
cp pam_google_authenticator.so /usr/lib
cp google-authenticator /usr/local/bin

After I did all of this by hand I though “I should make another Port!!”

Turns out, I just missed it. On a FreeBSD system, you can install this with a simple:

    $ portinstall security/pam_google_authenticator

Silly me…

I decided to only add the PAM object to /etc/pam.d/sshd (here is the diff):

--- /usr/src/etc/pam.d/sshd     2010-06-13 19:09:06.000000000 -0700
+++ /etc/pam.d/sshd     2011-07-17 22:05:18.000000000 -0700
@@ -9,6 +9,7 @@
auth           requisite       pam_opieaccess.so       no_warn allow_local
#auth          sufficient      pam_krb5.so             no_warn try_first_pass
#auth          sufficient      pam_ssh.so              no_warn try_first_pass
+auth           required        pam_google_authenticator.so noskewadj
auth           required        pam_unix.so             no_warn try_first_pass
    
# account

This PAM plugin is pretty forgiving, if a user has not ran the /usr/local/bin/google-authenticator tool, it will gracefully fail and allow for a normal authentication conversation.

When I ran the google-authenticator tool, I was presented a URL (to a QR Code image), and a list of backup codes. I scanned the QR image with my smart phone’s Google Authenticator app, which tied mcarlson@server.m87-blackhole.org to the one time passcode that my phone now generates.

When I log in to my server now, I get this:

This server is public facing, so two factor is legitimately safer

And my phone has something similar to this:

I'm not alice... or am I?

Other users are not bothered with this, unless they choose to do so.

Final Thoughts

This is a good tool, and more people should consider taking advantage of protecting their identity with really easy tools like this. I started using this because it really hit my how much I rely on my Google account. Not just email, but the calendar, the Music service, plus all of my other online activities like Amazon and domain registration all end up terminating at my gmail account. It would be devastating if it was compromised.

I’m also a big fan of open source security tools that use well understood approaches and well documented algorithms. That means there are more eyes on it, good and bad, but at least it is out there in the open for everyone to evaluate.

I’d like to test out a few more things, like can I use the same ~/.google_authenticator file on multiple systems, or do I need one on each system (and therefore, a 1:1 identity mapping on my phone). How well would this work in an environment with a central home directory NFS server?

Chris logged in using ssh keys without being prompted, and that makes also want to test out if this can play alongside ssh keys as well.

I think companies, such as the one I work for, should consider a cheap service like this to help protect public facing servers. If you can provide Blackberrys and iPhones to your employees, it would be nice if they could actually use it for work.