SSH with Yubikey
November 3, 2017
One of the common way to create more secure authentication in systems is adding more “factors”, creating in this way a Multi-Factor Authentication (MFA). The idea behind MFA is that there are many different ways to authenticate a user, and those can be split in different “categories” based on the kind of challenge we require. Generally speaking, it’s common to divide the authentication methods in mainly three categories:
- Something you know
- Something you have
- Something you are
The most known example of a “something you know” method is the password. You know the password and therefore the system assumes that since the current user knows the password, the current user is you. This assumption might be wrong, for instance if you wrote the password on a post-it and posted on your monitor. Also the password might be guessed by a third party using educated guesses or simply brute forcing it.
An example of “something you have” is a token device such as a Yubikey. You need to have near you the device in order to prove your identity. This makes very hard for anyone in the world - if not an handful of them that are near you - to be able to impersonate you. Usually those devices have no protection against their usage, so they can not safely be used alone otherwise anyone near you could impersonate you.
Examples of “something you are” are the fingerprint, and the face shape. Lately we have seen a lot of mobile devices adopting those kind of technologies due to the easiness for the user to use them, without having to remember anything nor to find their security device. Those technologies do have down sides as well, mainly due to margin they have to prevent false-negative they risk to have false-positive (or viceversa). Other concerns are around what a hill-intentioned person might be willing to do to you to impersonate you.
As you can see, every category of authentication methods have some weakness. The idea of Multi-Factor Authentication is to leverage more than one method (or factor) so that the weakness of a specific factor gets balanced out by the strength of a different factor. This does not mean that the strength of a specific factor gets balanced out by the weakness of a different factor, since the user will have to pass positively all factors. As you can immagine, although it could be done, usually the different factors are not going to be part of the same category, since that would mean that those factors would have similar weaknesses and strength, making the overall process not much safer than the one using a single factor.
Moving to the specific kind of authentication we are going to discuss here, the SSH authentication, support multiple authentication methods, usually in a single factor fashion. The most common supported SSH authentication methods are:
- SSH Key
The passphrase is a simple “password” and is often disregarded, since unsecure if used a Single-Factor Authentication (SFA)
SSH Keys are far more secure than passphrases, for multiple reasons:
- Way longer than passphrases
- The private pare never gets sent to the SSH server
- Optionally it is possible to add a password to the private part
Although SSH can make your system more secure, there are many reasons why those might not be enough for you. The main reasons I encountered are:
- In the past many broken implementation of SSH Keys generators have been discovered, and if you rely only on them for security, this might be dangerous, if additional broken generators are around
- There is no guarantee, nor no way to know, if your user is using or not passphrases with SSH Keys or not
- Due to compliance reasons, you might be forced to use Multiple-Factors Authentication, PCI-DSS being a certification that requires it
A way to solve this, could be to stack-up multiple factors as we discussed in the first section. Although passphrase and SSH Key can be stack-up to create MFA, this has some downsides, due to some client-OS potential compatibility problems.
On the other hand, there are some devices (like the Yubikey) that are USB and fake to be a keyboard, typing an always-changing code.
Enable Yubikey in SSH
It is easy to add Yubikey as a method to connect to SSH.
In Red Hat Enterprise Linux 7 (and derived distros such as CentOS and Scientific Linux), you need to follow the following steps:
Register on Yubikey website as developer to obtain the
sudo yum install -y pam_yubico
Add the following line at the begin of
/etc/pam.d/sshd, or close to the top if you don’t want to use this as first method:
auth required pam_yubico.so id=YUBIKEY_USER key=YUBIKEY_KEY authfile=/etc/yubikey_mappings. Where
YUBIKEY_KEYwill need to be the ones that you retrieved from Yubikey website.
Create the file
/etc/yubikey_mappingswith a content like:
fale:ccccccdudfhr. You can add multiple users, one per line. The second value is the first 12 characters of the Yubikey code, which is the Yubikey ID.
All your SSH logins now will require a proper Yubikey token to be provided.
Tweaking Yubikey SSH authentication
There are various things that can be tweaked to change the behaviour of the SSH Yubikey module.
As first thing, you might want to have multiple enabled Yubikeys for the same user.
This is possible, simply by adding a trail
:YUBIKEY_ID at the enf od the mapping file.
An example of this is:
You might also want to use the Yubikey in place of your passphrase and SSH key.
Although this is less secure since would be a SFA, it might make sense in your environment.
To achieve it, you will simply need to change the line we added in
/etc/pam.d/sshd, changing the
Another change that could make sense in your environment is to force Yubikey authentication only for users above a certain ID, so that system users are not affected.
To do so, you will simply need to append to the like we added in
debug uid > 1000 string.
If you are running with SELinux enabled (as you should), it will give you problems, due to a bug. To solve this, you might consider putting SELinux in permissive mode (un-suggested) or create a policy for it:
policy_module(local_pam_yubikey, 1.0) gen_require(' type sshd_t; type cert_t; ') allow sshd_t cert_t:dir write;
Also, remember that you will need to enable the