How to log on to Linux using a Yubikey FIDO U2F

Posted on Wednesday, 07 March 2018 in IT

I've recently bought a Yubikey NEO for trying things related to the Web Authentication API. But I wondered if I can use it for more, like authenticating to my Linux system.

Fortunately, the answer is yes. And as most of the time, people have already tried things before me. This post by John McDermott explains it very nicely. So let's follow John's tutorial.

udev rules for Yubico devices

Get the Yubikey udev rules published by the Yubico guys and put them in /etc/udev/rules.d/.

In case you wonder what you are doing here: these udev rules allow a well-known list of Yubico hardware devices (which are actually behaving as Human Interface Devices, thus: pseudo-keyboards) to be used by any user, not just root.

pam_u2f

There exists a Pluggable Authentication Module (PAM) for U2F, developed by the Yubico people. It's called pam_u2f. For those who don't know it: PAM is the standard Linux technology stack for everything around authentication, password policies, etc. This means that if you find a PAM module for something, then you can use that something for authenticating.

In the concrete case of Arch Linux, we want to get the pam_u2f package from the AUR.

The actual dependencies that will need to be installed depend on the package requirements and on what is already present on your system. In my case, I needed to install the following:

  • libu2f-host
  • check, gengetopt and help2man as dependencies of the AUR libu2f-server package
  • the libu2f-server AUR package itself
  • asciidoc as a dependency for the AUR pam_u2f package
  • the pam_u2f AUR package itself

libu2f-server and pam_u2f are AUR packages; everything else can be found on the standard repo.

The U2F public credential file

We now need to obtain a U2F public credential and store it in a place where it can be found by the U2F PAM module.

As I am the only user on my PC, I decided to keep things simple and go for the per-user file approach.

So put the Yubikey in, generate the public credential with the pamu2fcfg tool and dump it to the appropriate location:

mkdir ~/.config/Yubico

pamu2fcfg -u$USER > ~/.config/Yubico/u2f_keys

Modifying the PAM chain

It's up to you to decide for what exactly you want to use your Yubikey: for every authentication, just for su, just for specific things like ssh and to know if you want to make it mandatory or optional.

In my case, I want to be able to use it for every authentication of my account, but not impose it. In other words: if the Yubikey is plugged in, I want to use just the Yubikey (because I like to). But if it's not plugged, I don't want to impose it and use the good old password, instead.

This translates to making it sufficient before the standard authentication modules.

On my system, the PAM files are broken up into several "includes", and the right include fragment seemed to be /etc/pam.d/system-auth. Thus:

#%PAM-1.0

# added for Yubikey
auth      sufficient pam_u2f.so

# unchanged
auth      required  pam_unix.so     try_first_pass nullok
...

Testing

This setup works quite nicely. On my graphical desktop (display manager: LXDM), I can log in and tap the Yubikey instead of typing the password. For some reason, I need to tap it twice: once it enters the U2F response as a "fake password", then blocks and needs another tap to proceed. It's weird, but I don't currently feel like spending days digging into why it's doing that.

On a text console, I'm authenticated with just a single tap on the Yubikey.

And if the Yubikey is not inserted, I can just use passwords as before.