Two Factors Are Better Than One

Although I've always been interested in security, there are just some security measures I've never liked. SSH brute-force attacks end up being a major way that attackers compromise Linux systems, but when it comes to securing SSH, I've never been a fan of changing your SSH port to something obscure, nor have I liked scripts like fail2ban that attempt to detect brute-force attacks and block attackers with firewall rules. To me, those measures sidestep the real issue: brute-force attacks require password authentication. If you disable password authentication (set PasswordAuthentication to no in your sshd_config) and use only SSH keys, you can relax about all those brute-force attacks knocking on your door.

In a past article ("Secret Agent Man", December 2013), I wrote about why you should set a passphrase on your SSH keys and how to use SSH Agent to make password-protected keys a bit less annoying. In one respect, you can think of password-protected SSH keys as a form of two-factor authentication. The key is something you have, and the password is something you know. The problem, however, is that if you host a system with multiple users, you can't enforce password-protected SSH keys from the server side. So in this article, I discuss how to add two-factor authentication to an SSH server that accepts only keys.

These days, more services on-line offer two-factor authentication (2FA) as an extra layer of security on top of a user name and password. After you perform your normal authentication, you provide your 2FA token (usually a string of digits) that authenticates you. Although in the past, 2FA required you to carry around a special hardware dongle, these days, a number of software approaches can use your cell phone instead. Some approaches use TOTP (Time-based One-Time Password), so your phone just needs accurate time but no network to function. Other approaches use push notifications, SMS or even a phone call to share the 2FA token, and some implementations can use all of the above.

Some 2FA SSH implementations work via the ForceCommand directive placed in the SSH configuration for a particular user and let you enable 2FA on a per-user basis. Others offer a PAM module you can add system-wide (and use for sudo authentication as well as SSH). Although a number of excellent 2FA SSH implementations exist for Linux, I've chosen Google Authenticator for a few reasons:

  • It's free, and the source is available.

  • It's been available and tested for a number of years.

  • Packages are available for a number of distributions.

  • Clients are available for a number of phone operating systems.

  • It uses a custom PAM module, so it's easy to add 2FA system-wide.

  • It provides a backup in the form of backup codes in case users lose or wipe their phones.

Install Google Authenticator

As I mentioned, Google Authenticator is packaged for a number of distributions, so, for instance, on Debian-based systems, you can install it with:

$ sudo apt-get install libpam-google-authenticator

If for some reason it isn't packaged for your distribution, you also can just go here, download the software and make and install it according to the documentation there. You also will need to install the Google Authenticator app on your phone.


Kyle Rankin is VP of engineering operations at Final, Inc., the author of many books including Linux Hardening in Hostile Networks, DevOps Troubleshooting and The Official Ubuntu Server Book, and a columnist for Linux Journal. Follow him @kylerankin