When Google introduced two-factor authentication for the Google and Google Apps accounts, they also created a pluggable authentication module (PAM) for Linux. This is great news for people running Linux servers who want to protect their remotely-accessible SSH accounts with two-factor authentication. For free.

Two-factor authentication is where you authenticate to a service with two pieces of information: one you know, and one you don’t. The information you know is your password (which can be stolen) while the information you don’t know is a randomly-generated PIN number that changes every 60 seconds. So even if your password is stolen or discovered, unless an attacker has the means to get the right PIN (tied to a hardware device), they cannot log into the protected service.

Google has created the Google Authenticator application for iPhone, Android, and Blackberry — effectively turning your phone into your hardware token device. Before you can make use of two-factor authentication to secure your Linux logins, you will need to enable it in your Google account (I also wrote a tip on setting up Google two-factor authentication for users of Mac/iPhone).

Once two-factor authentication is enabled and working with your Google or Google Apps account, you can begin setting up the same for your Linux server. To do so, you will need to download and compile the PAM module for your system. The examples here will be based on Fedora 14, but it should be easy enough to figure out the equivalents for whatever distribution you happen to be using. It also assumes you have sudo writes to run anything as root; if that is not the case, su to root to run those commands (as root) that are prefixed with sudo. You will need mercurial installed to initially check out the code.

$ sudo yum install pam-devel
$ hg clone https://google-authenticator.googlecode.com/hg/ google-authenticator/
$ cd google-authenticator/libpam/
$ make
$ sudo make install
$ sudo vim /etc/pam.d/sshd

Once the PAM module and the command-line google-authenticator application are installed, you need to edit the /etc/pam.d/sshd file to add the module, so it may end up looking like:

  auth required pam_sepermit.so
  auth required pam_google_authenticator.so
  auth include  password-auth

This sets up two-factor authentication for SSH. It is also possible to do the same for gdm, requiring the use of two-factor authentication to log in locally.

When that is done, as the user that you want to require two-factor authentication for, run the google-authenticator application, which will create a new secret key in your home directory:

% google-authenticator
Your new secret key is: SAEP64T5VZAVWAFB
Your verification code is 376046
Your emergency scratch codes are:
Do you want me to update your "~/.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

In your browser, load the URL noted above; it will show a QRCode that you can scan into your phone using the Google Authenticator application for iPhone, Android, or Blackberry. If you already have a Google Authenticator token being generated on your phone, you can add a new one and it will display them both (and distinguish them by name).

One quick tip: time is _very_ important, so the server you are logging into should have an NTP client installed in order to keep the time accurate. Keep an eye on this; if you are having trouble you may have to open the window size as noted by google-authenticator.

You will also need to edit /etc/ssh/sshd_config to enable “ChallengeResponseAuthentication” and “UsePAM” (set them both to “yes”).

Restart sshd after making any changes to the file.

When this is done, try logging into the system via SSH:

% ssh server
Verification code:
Last login: Tue May 10 11:54:21 2011 from client.example.com

You must provide the verification code as presented by your phone in order to log in. Even if the password is known, without the verification code, the login will fail. Also note that you will be unable to use this if you use ssh private/public keys as the two are mutually exclusive (key-based logins get a passphrase prompt client-side and never provide a password to the server).

Setting up two-factor authentication for SSH is surprisingly simple, thanks to Google. It only takes a few minutes to set up, the infrastructure and tools are free, and the security gains are great.