Leveraging Google’s two-factor-identification to secure SSH logins

Recently, Google began to offer two factor authentication as an available option to securely login to Google accounts (Gmail, Google Docs, etc). Insodoing, they also offered an open source PAM module that will allow you to do one excellent thing: Force 2FA (two factor authentication) for SSH (secure shell) logins (or local logins) for Linux computers. This is a fully open source module as referenced in the open standard, RFC 4226.

What this means is, that when you SSH into your Linux box, you’ll not only be asked for a password, but a code that you’ll need to use your mobile phone or tablet to generate. This will greatly enhance security on your Linux box, because hackers won’t simply be able to brute force attack your publically accessible SSH box anymore — they’ll also need a way to generate that unique, time-sensitive sequence of numbers that changes every 30 seconds on your android, iPhone or Blackberry device. It essentially turns your cell phone or tablet into a token that you will almost always have on your person, but a hacker wouldn’t. Even if your SSH password somehow were compromised, your system would be completely safe, since now you need two factors to login to your Linux computer.

To allow this concept to be more fully understood, Google created a video, which I’ll post below. While this video explains how two factor authentication can be applied to access your Google account more securely, in this blog post I am going to show how to use the same Google technology generically (without having to activate Google’s 2-step verification on your Google account!) as an extension of your own security tools to better secure your Linux computer(s). This tool is independent of any Google account, you don’t even need a Google account to use this two factor authentication tool.

The underlying technology used by Google is made freely available as open source software. You can use this software to further secure your SSH logins (or local desktop logins) on your Linux boxes.

While the video explains that Google can text you your numeric code (which only lasts for 30 seconds), this PAM module cannot send SMS messages, instead it requires that you use the Google Authenticator App which is available for Android, Blackberry and iPhone/iPads to generate your 30 second code.

My explanation below is going to be Debian (Ubuntu, Mint, etc.) specific. There is a page that explains this for Fedora users. This process is exceeding simple, and easy to implement. It is also very easy to reverse, should you want to stop using 2FA for your Linux box. I’ll explain all this in detail.

First, you’ll want to install the ‘libpam-google-authenticator’ package, which is a standard Debian package:

sudo apt-get install libpam-google-authenticator

Next, you’ll need to run the google-authenticator program from command line to generate your keys and provide a QR Code for you to scan using your phone/tablet. The purpose of the QR Code is just to save you time entering the code into your Google Authenticator App manually. You’ll need an application installed on your phone that can scan QR Codes. I use QR Droid on my Android phone. The QR Code is generated in ASCII and will scroll up on your command shell screen; you may need to widen your terminal window to allow you to see the entire QR Code.

To run the Google-Authenticator program, just type from command line:

google-authenticator

This command will generate the large ASCII QR Code as well as some other information you’ll need. Here’s a sample of what you’ll see below the large ASCII QR Code in your terminal window:

Your new secret key is: DAEP55X5AZEVCAFB

Your verification code is 866046
Your emergency scratch codes are:
67868555
26247221
12215527
55436461
21077916

Do you want me to update your "~/.google_authenticator" file (y/n)

At this point, you’ll want to hit ‘y’ to allow this information to be entered into your /home/user/.google_authenticator file on your Linux box. Simply put, the information above is your secret key and verification code which is also the contents of the QR Code should you choose to scan it instead of typing it manually into your Google Authenticator App.

The scratch codes are one time use codes that if for any reason your phone/tablet is lost or stolen, you can use to login in case of emergency. At that point, you can choose to delete the .google_authenticator file and issue a new one, or temporarily stop using 2FA until you get your mobile device or tablet back for future logins. Be sure to write those scratch codes in a safe place where they can be accessed if needed (like when you don’t have your mobile device with you!)

After you entered ‘y’ to the question above, the next question asked will be:

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)

This is basically asking if you are OK with allowing a generated code to be used more than once in a 30 second period assuming multiple, concurrent SSH logins. This is a matter of preference.

Next, you’ll be asked:

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)

What this really means is that a code generated is really good for 90 seconds instead of 30. Even after a new code is generated at the 31st second, the old code will still be good for another 60 seconds, and it’s configurable up to 4 minutes. I chose ‘n’ here, to allow for the default, 90 second time frame.

It is very important, however that you set up NTP on your system, so that you do not rely on your computer’s clock which will likely drift over time. Since the second factor code generated by the Google Authenticator App is time sensitive, it is critical that your PC have the accurate time of day to match Google’s servers.

In Debian based distros of Linux (Debian, Ubuntu, Mint, etc) – here’s how to install the NTP client on your computer and make sure it’s working:

Install NTP: sudo apt-get install ntp

That’s it!!! Now, to confirm that the server is working using the ‘ntp query’ program:

ntpq -np

The output of this command will show you a small table. You’ll want to look for a list of IP addresses under the ‘remote’ column. One of them should have an asterisk * next to it — that means that you’re successfully checking time with the time server that owns that IP address. If you don’t have a star next to one of the IP addresses, it means that the clocks are unreachable.

Also, to ensure correct synchronization make sure the delay and offset values are non-zero and the jitter value is under 100. Here’s a couple of links for more info: One, two.

Anyway, back to our setup process. You’ll be asked one final question before you’re returned to the command prompt:

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)

Again, this is a matter of preference, but I did enable rate limiting by entering ‘y’.

Once this is done, your system now has the correct codes in the “.google_authenticator” file in your home directory. You must now configure your Google Authenticator App and Linux system to use it.

Run your Google Authenticator app and add an account. You can scan that ASCII generated QR Code, or do it manually. I did mine manually, so I entered “Linux Box One” as my account name, and I entered “DAEP55X5AZEVCAFB” as my key (from the example above). Next you have an option for Time Based or Counter Based — I went with the default, Time Based.

Once this is done, the app will begin rotating your codes. You can add as many accounts as you like and you can remove them as well, if you choose to regenerate your codes.

You now need to configure your Linux box to use the Google codes for SSH logins.

On your Linux box, you will have to modify you /etc/ssh/sshd_config file:

sudo nano /etc/ssh/sshd_config

. . . and enable ChallengeResponseAuthentication. Search for this line and if disabled, replace the ‘no’ with a ‘yes’. Save your changes.

Restart your ssh service. When I tried this using ‘sudo’ I got some odd error, so I had to forcibly switch to root using the ‘su’ command, then restart ssh from there. Either way, you bounce ssh in Debian with the command:

sudo service ssh restart

. . . if this errors for you try this as full root:

su
(enter your root password)
service ssh restart
exit

Next, you’ll need to modify the /etc/pam.d/sshd file to let the Linux PAM SSH module know about the google authenticator module:

sudo nano /etc/pam.d/sshd

. . . and add the following line to the bottom of the file:

auth required pam_google_authenticator.so

Save your changes.

Once this is done, you’re good to go.

Start a fresh SSH session into your Linux box and you’ll be asked for your password AND YOUR CODE. You’ll need to get that code from your Google Authenticator App.

To undo all this, simply change the ChallengeResponseAuthentication line in your /etc/ssh/sshd_config file from ‘yes’ to ‘no’. Then edit your /etc/pam.d/sshd file and delete that line at the bottom (auth required pam_google_authenticator.so). Restart your SSH service (sudo service ssh restart) and on your next login, you’ll just be prompted for your password.

You can delete the “.google_authenticator” file if you like, or leave it there. So long as you reversed your changes to sshd_config and PAM’s sshd file, you will not be asked for the Google code.

A very cool thing about this, is the contents of the “.google_authenticator” file is user specific. This means you can repeat this process on the same Linux box as various non-root users, creating unique .google_authenticator files in each user’s home directory. Each user will have different (but valid) codes being generated on their respective mobile devices to login to the same Linux box. Each user will also get their own sets of scratch codes.

If you want this to also work for LOCAL LOGINS on your Linux box, you need to add the ‘auth required pam_google_authenticator.so’ line to your /etc/pam.d/common-auth file.

sudo nano /etc/pam.d/common-auth

Paste this line at the bottom of the file:

auth required pam_google_authenticator.so

Save your changes. On your next login to your Linux box locally (as opposed to using SSH), your Linux box will ask for your password and your Google code.

Here’s some sources I used for this blog post: Onetwo, three.

Linux Noobs – stop reading here!!

1. One word of warning to advanced users — if you don’t use passwords for your SSH sessions but instead use keys (PubKeyAuthentication), remember that SSH does NOT USE PAM when you have keys enabled! PAM and PubKeyAuthentication are mutually exclusive of each other in OpenSSH, therefore this will not work for you!

2. Yes, there is a Java-based Google Authenticator app out in the wild (for running the Google Authenticator app on your laptop or desktop instead of your mobile device) — but I have not tested it — here’s the link.

3. Also, if your home partition is encrypted, you may have a catch-22 where the  .google_authenticator file is inaccessible because it’s encrypted on your home partition and therefore your Linux box cannot authenticate the code you’ve entered. Check the comments under this web page, where this issue is briefly discussed.

Enjoy!