Two-factor SSH authentication using YubiKey OTP
Two-factor authentication means that in order to authenticate,
a principal should prove its identity using at least two different methods.
Often, a principal is required to authenticate using both a password,
and a one-time token; this is especially popular on cloud services,
where the token is either generated cryptographically or sent through a
side channel, such as SMS.
In this document, we'll set up an SSH server that will use SSH public key
cryptography as one factor and YubiKey OTP as another. For trusted networks,
the YubiKey OTP is never needed, while public key cryptography is always
This will leave us with an SSH server that requires an SSH key to log in,
but may require a YubiKey OTP as a second factor if authentication is
attempted from an untrusted location.
Registering API keys
In order to use pam_yubico against YubiCloud, you need to get an API key.
You need an unmodified YubiKey to do this. Go to the
Get API Key page,
fill out your e-mail address, select the second textbox and press the
button on your YubiKey. You will now get a Client ID
and Secret key. Take note of these.
Alternatively, you can set up your own validation server, but that is not
covered by this document. Please refer to the
YubiKey OTP Validation Server
for more information.
Setting up pam_yubico
In this case we'll be using FreeBSD, but pam_yubico(8) is available on most
UNIX-like operating systems. Install the module.
pkg install pam_yubico
After installation, you must update your pam configuration file.
This process is documented on the
GitHub project, but we'll go through it here as well.
In /etc/pam.d/sshd, before the first
add the following line.
auth required /usr/local/lib/security/pam_yubico.so id=
Remove all other auth statements by commenting them out.
Now create the file /etc/yubikey_mappings, which contains a mapping
of usernames to one or more YubiKeys. The format is:
yubikeyid consists of the first twelve bytes of the OTP
generated by a YubiKey when you press the button. The OTP is
different every time you press the button, but the first twelve
bytes are always the same. This is the YubiKey ID.
Since we've configured PAM to always require YubiKey authentication,
UsePAM yes will, in combination with
AuthenticationMethods keyboard-interactive already provide
YubiKey OTP authentication. However, this is not exactly what we want,
as this would allow anyone who finds a YubiKey to log in as that user.
This sshd_config will require both SSH public key authentication, and
YubiKey authentication. Replace the existing sshd_config with this one:
However, we want public key authentication to suffice for hosts
in a trusted subnet. This is simply done by appending the following
to the end of sshd_config:
Congratiolations, you've now set up two-factor authentication using