In this tutorial I'll show you how to set up two-factor authentication for SSH using Google Authenticator. Two-factor authentication is where you authenticate to a service (SSH in our case) 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 few seconds. So even if your password is stolen, unless an attacker has the means to get the right PIN (tied to a hardware device), they cannot log into the protected service.
To enable two-factor authentication, you will need to download and compile the PAM module for your system. The examples here will be based on CentOS 5.6, but it should be easy enough to figure out the equivalents for whatever distribution you happen to be using.
You will need mercurial installed to initially check out the code.
Enter the following commands:
yum install mercurial yum install pam-devel hg clone https://google-authenticator.googlecode.com/hg/ google-authenticator/ cd google-authenticator/libpam/ make make install
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_google_authenticator.so
auth include system-auth
account required pam_nologin.so
account include system-auth
password include system-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session include system-auth
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open env_params
session optional pam_keyinit.so force revoke
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:
Your new secret key is: 4RUPTGQJNL3REOJP
Your verification code is 334864
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 Android, iPhone 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.
You will also need to edit /etc/ssh/sshd_config to enable "ChallengeResponseAuthentication" and "UsePAM" (set them both to “yes”). Don't forget to restart sshd service.
When this is done, try logging into the system via SSH:
ssh 192.168.1.1 Verification code: Password: Last login: Thu Jun 23 13:27:47 2011 from 192.168.1.2 [root@aphrodite ~]#
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).
NOTE: Time is very important, so the server you are logging into should have an NTP client installed in order to keep the time accurate.Print This Post