2FA with the YubiKey & OpenBSD for SSH Access
By Calum MacRae
December 25, 2013
In this post, I'll be detailing the steps you can take to harden your remote SSH access, and achieve a two factor authentication setup with a YubiKey and OpenBSD's SSH server.
The authentication principle
After carrying out the steps detailed here, you'll have an SSH server with which you can only establish a connection once the following authentication requirements have been met:
- Key pair passes with the presence of a permitted private key
- Passphrase for the key pair is correct
- Unique OTP provided by the YubiKey is correct
This isn't quite multi factor authentication (by definition), but it's damn good!
Who this is for
Well, for anyone looking for a hardened SSH server really. I use this setup on the firewall/router I built for remote SSH access to my home network (see I'm even confident enough to disclose that information).
Perhaps not as badass as port knocking, but it's a hell of a lot better than some other proposed security measures.
What we'll be using
This setup is for use with the OpenSSH server. I won't specifically
state it's just for OpenBSD, but as this tutorial details the
YubiKey's use with BSDAuth, and specifically OpenBSD's
that's what you'll need to be using to follow these steps exactly. It
can certainly be achieved with PAM, and therefore used with a wide
variety of UNIX derived systems. So if you're confident you can adapt
these steps to fit your needs, by all means do so. Just pray you don't
lock yourself out of anywhere ;)
A quick note
I wanted to state; this tutorial does not walk you through the install/setup of OpenBSD. If you're looking for information on how to do so, visit OpenBSD's official site…. plus, it takes like 3 minutes from start to finish, just dive in people!
It's important to understand the technologies we're using here and how they relate to one another.
Logging in with BSDAuth
Let's start with the last step of authenticaion. I know that seems a bit backwards but, you'll understand once this all starts to come together. So, you can set up your OpenBSD system to accept a OTP from the YubiKey as a means of authenticating a user's login. Think of this as completely disjointed from remote access right now, we're just talking about logging into the system on, say, your desktop. In fact, I use my YubiKey to log into my desktop running OpenBSD.
This replaces the usual process of typing a static password you have safely locked away in your memory. Instead of typing in the name of your cat's favourite day of the week followed by the hexadecimal value of the colour of your first car….. or some other equally obscure collection of (dare I say) memorable data, you simply touch that little pad on the YubkiKey, it authenticates using BSDAuth, and away you go!
BSDAuth's relation to SSH access
So, if you understand the above (granted I didn't go into grooling detail, that is yet to come), then perhaps you can understand the following notion: One can log into a remote system via SSH using simply the user's password on that system (if it has been set up that way). Taking this into consideration, hopefully it becomes clear that once this static password has been replaced with the OTP process… you could still SSH as that user, but use the YubiKey instead of the static password.
Key pair authentication
It's imperitive that you, dear reader, understand at least the basic
concept of using key pair authentication with SSH. This is an important
thing to understand as it's a key component to this setup…. no pun
intended. Once we've set up our server for this kind of authentication,
the first thing the server will look at when someone attempts to
establish an SSH connection is the remote user's private key. If the
private key provided by the remote user does not legitimately match with
any public key listed in the
authorized_keys file of the user on the
destination host, the connection will be closed. This is, essentially,
the remote part of our mental map for this setup. We want to ensure
that, first, anyone attempting to access our system has a legitimate key
Tying the two together
- We must have a legitimate keypair to establish the initial connection with the SSH server
- We must then provide a OTP using the YubiKey for login authentication with BSDAuth
In fact, we'll also be adding a passphrase onto the public key. This adds another layer of security, as the user of the key pair will have to authenticate the key pair itself with a passphrase.
Let's get started!
First, going back to the BSDAuth/local login; the means by which we use
the YubiKey in conjunction with BSDAuth is a login module, called
Here's a clear and concice explaination of how it works, taken from the
login_yubikey will read the user's UID (12 hex digits) from the file user.uid, the user's key (32 hex digits) from user.key, and the user's last-use counter from user.ctr in the /var/db/yubikey directory. If user does not have a UID or key, the login is rejected. If user does not have a last-use counter, a value of zero is used and any counter is accepted during the first login. The one-time password provided by the user is decrypted using the user's key. After the decryption, the checksum embedded in the one-time password is verified. If the checksum is not valid, the login is rejected. If the checksum is valid, the UID embedded in the one-time password is compared against the user's UID. If the UID does not match, the login is rejected. If the UID matches, the use counter embedded in the one-time password is compared to the last-use counter. If the counter is less than or equal to the last-use counter, the login is rejected. This indicates a replay attack. If the counter is larger than the last-use counter, the counter is stored as the new last-use counter, and the login is accepted.
So first let's get these files set up:
Getting your UID and key
In order to obtain your UID and key, you'll need to install the
yubikey-personalization-gui package. This will let you generate a
paired UID and key, then write it to the YubiKey for use with
Once installed, run the application and select the first option at the top Yubico OTP, then select Quick. You'll be presented with a new screen. Under the Yubico OTP Parameters (auto generated) section, unselect the Hide values option. This will reveal the newly generated UID and key (this is auto generated upon each run of the application).
Using your UID and key with login_yubikey
Copy the Private Identity (6 bytes Hex) value into a file named after
your user in:
/var/db/yubikey/ For example, mine is as follows
/var/db/yubikey/cmacrae.uid. Do the same for the key, copy the Secret
Key (16 bytes Hex), paste it into a file like so:
cmacrae.key in my case).
Ensure the permissions on these files is set correctly:
chown -R root:auth /var/db/yubikey/ chmod -R 0644 /var/db/yubikey/
Now that you have these values recorded in the appropriate locations,
write them to Slot 1 on your key (or if you'd prefer to keep Yubico's
default config, write to Slot 2, however; each time you use the key, you
will have to hold the touch finger pad for 4 seconds). You can write
this config to the key by selecting 'Write configuration' and selecting
the desired slot. This will also prompt where to save a CSV file of the
config (something I'd deem unecessary, and a security risk) so just save
it to your
$HOME and remove it later.
Setting up login.conf
/etc/login.conf file and add
yubikey at the beginning of
auth-defaults entry, like so:
# Default allowed authentication styles auth-defaults:auth=yubikey,passwd,skey:
This takes care of the YubiKey part of our setup. You probably want to
test this works as expected. If anything is unusual, retrace your steps.
If you end up somehow locking yourself out of your system, you can boot
to the ramdisk by entering
bsd.rd at the bootloader. From here you can
drop into a shell, mount your filesystems and edit
back to use password authentication.
SSH key pair
If you're growing tired of reading; fear not. This part is nice 'n easy!
If you're following this tutorial, I'll assume a certain level of prior
knowledge and take it you already know how to generte an SSH key pair.
If you're not familiar with this, go read up on it! If you don't know,
I'll take pitty on you:
ssh-keygen …but still go and read up on it,
there are better options than the defaults given to you when running
this utility without any flags.
You can use any of the ciphers supported by OpenSSH for this (read more at https://openssh.com).
Make sure when you generate your key pair, you add a passphrase. This provides another layer of security!
And of course, once you have your keypair, you need to paste the public
key into the
~/.ssh/authorized_keys file of the user you're going to
be SSH'ing as.
Chaining authentication methods in sshd
Now, we can finally chain these authentication methods in the SSH daemon's configuration.
In the file
/etc/ssh/ssd_config, add the following lines:
# Chained authentication AuthenticationMethods publickey,password
This will tell the SSH server to first authenticate the key pair from the remote machine (also prompting for the passphrase you added to your public key…. you added one, right?), then ask for a password. This password of course will be the OTP provided by the YubiKey.
Try it out! You should see something like this:
$ ssh user@server Authenticated with partial success. user@server's password:
Note - If there is no passphrase prompt shown here, as in this example, this is because you have already unlocked your key pair with your passphrase using your desktop's keychain application for this session
So there you have it!
There are now, essentially, 3 points of authentication:
- The server ensures a legitimate, permitted key pair is present on the remote machine
- A correct passphrase has to be provided to unlock the key pair for authentication
- The server prompts for the users password, which is now a unique OTP provided by the YubiKey
That's pretty nifty, right?
I should get to bed…
Well, it's been a good night of writing. I hope you've enjoyed this post, and taken something decent from it.
Until next time, happy hacking :)
- Posted on:
- December 25, 2013
- 9 minute read, 1763 words
- security bsd networking