Using a yubikey for OATH-based two-factor authentication

Version $Id: yubikey-oath.html,v 1.1 2014/03/10 13:02:26 madhatta Exp madhatta $

You can read about my earlier experiments with the yubikey here if you want, but the upshot is that I've been using my yubikey to control sudo access to my production server for two years, during which time it's been fine, but I've always wanted proper two-factor authentication for ssh logins. Specifically, certificate-based logins should be allowed to continue without a problem, but password-based logins should require a token output as well as the correct password.

The problem is that I can't require all my users to buy yubikeys (well, I can, but it would be mean). So I noticed that OATH, an Open Authentication standard, is making inroads. Particularly, there are now a crop of free (both libre and gratuit) OATH implementations for Android phones, so that anyone with a decent smartphone can have it act as an OATH token.

In this technote, I'll be discussing how to use yubikeys as OATH authenticatiors, but having done this and put the infrastructure in server-side, a soft OATH token would work equally well (it really does, I've tested it).

First, I configure the yubikey to have an 8-digit HOTP OATH password in slot one:
ykpersonalize -1 -o oath-hotp -o oath-hotp8 -o append-cr -a 123a567890123b567890123c567890123d567890
The long string is there to show that a forty-digit hex string is required; obviously, I'm not going to show the real string used. I generated it by doing
dd if=/dev/random bs=1k count=1 | sha1sum

On the server:

yum install pam_oath
ln -s /usr/lib64/security/pam_oath.so /lib64/security/
You should change lib64 to lib everywhere above if your system is still 32-bit. Also, you should schedule an upgrade. It'll be 2038AD soon.

Make the authentication file /etc/users.oath, mode 600, owner root:root, and populate it with lines like:

#type   username        pin     start seed
HOTP	madhatter	-	123a567890123b567890123c567890123d567890
Edit /etc/pam.d/sshd and add the line
auth required pam_oath.so usersfile=/etc/users.oath window=5 digits=8
before any mentions of password-auth. I would have preferred to have the regular password asked for before the OATH token was requested, but have thus far failed to make it work; the above works for me, and asks for the OATH token before the regular password.

Although I want ssh logins to be full two-factor (OATH token and regular password), I'm happy for sudo authentication to be OATH-only. For that, the following line goes at the top of /etc/pam.d/sudo:
auth sufficient pam_oath.so usersfile=/etc/users.oath window=5 digits=8

In /etc/ssh/sshd_config, I turn simple password auth off, and Challenge-Response on; this allows for the OATH token to be asked for separately to the password, so we don't have to have any of this "enter the four digits of your PIN followed by the six digits from the token" rubbish:
PasswordAuthentication no
ChallengeResponseAuthentication yes

Then restart sshd.

And it works!

[madhatter@risby ~]$ ssh lory
One-time password (OATH) for `madhatter': 
Password: 
X11 forwarding request failed on channel 0
Last login: Mon Mar 10 10:23:34 2014 from 2a01:2c0:e:300:7271:bcff:feac:445a
[madhatter@lory ~]$ sudo -l
One-time password (OATH) for `madhatter': 
[...]
User madhatter may run the following commands on this host:
    (ALL) ALL
[madhatter@lory ~]$ 

Back to Technotes index
Back to main page