Overview

WARNING
Please have a root privileged shell open before you start, its very possible to break your sudo configuration.
WARNING

This guide documents how to use U2F for sudo access.
Methods supported are U2F only, with password fall back(1FA) or with required password authentication (2FA).
This is part of an upcoming range of posts on using U2F on Linux.

Requirements

  • U2F security key(s) (I am using Yubikeys)
  • Yubico's pam-u2f
  • Working existing sudo setup

Steps

Install required software

The most preferred way to install pam-u2f is via your distributions package manager.
For Gentoo users this is as simple as emerge -a sys-auth/pam_u2f, this will pull in any needed dependences. Out of interest the current dependence tree for Gentoo looks like this :

* dependency graph for sys-auth/pam_u2f-1.0.8
`--  sys-auth/pam_u2f-1.0.8  amd64
  `--  app-crypt/libu2f-host-1.1.10  (app-crypt/libu2f-host) amd64
  `--  app-crypt/libu2f-server-1.1.0  (app-crypt/libu2f-server) amd64
  `--  sys-libs/pam-1.3.1_p20200128-r1  (sys-libs/pam) amd64
  `--  virtual/pkgconfig-2  (virtual/pkgconfig) amd64
  `--  app-portage/elt-patches-20170815  (>=app-portage/elt-patches-20170815) amd64
  `--  sys-devel/automake-1.16.1-r1  (>=sys-devel/automake-1.16.1) amd64
  `--  sys-devel/automake-1.15.1-r2  (>=sys-devel/automake-1.15.1) amd64
  `--  sys-devel/autoconf-2.69-r4  (>=sys-devel/autoconf-2.69) amd64
  `--  sys-devel/libtool-2.4.6-r6  (>=sys-devel/libtool-2.4) amd64

NOTE For Gentoo users you might want to merge this package with the debug USE option, at least until you have a working setup. Otherwise you won't ever get any debug logs.

Create a mapping file

Now we need to create a mapping file that maps security keys to user names on the system.
This file can be created in two ways :

  • Per user, sorted in the users home directory
  • System wide, stored under /etc

I prefer the system wide method. As I know /etc will be available very early on in the boot process, where as /home can come much later. However both have upsides and downsides so please read the documentation first.

If your machines host-name is static and not set via DHCP you can create a simple mapping file.
However if your machine's host-name is set via DHCP you need to make use of the -o option for pamu2fcfg. This sets a static host-name in the mapping file.
I don't need this so the following example assumes you have a static host-name.
Host-name is discovered via pam://hostname method in pam-u2f. This in tern usues the pam_get_item() function call to get the underlying information.

The following steps should be done as your everyday user account with a U2F key plugged in.

To map out first U2F key issue the following command :

pamu2fcfg > /tmp/u2f_mappings

You will need to press the button on your U2F device.
I always have a backup security key, after all if you lose this key you can't run sudo anymore.

To add an additional key we use the -n option, this prints only the registration details and not the user details. insert your second U2F device and run the following command :

pamu2fcfg -n >> /tmp/u2f_mappings

If you have more then one user and U2F keys, repeat the same process, but add the new user on the next line in the same file.

If your interested the format of this file is :

<username1>:<KeyHandle>,<UserKey>:<KeyHandle1>,<UserKey1>
<username2>:<KeyHandle>,<UserKey>:<KeyHandle1>,<UserKey1>

As you can see we don't repeat the section and everything must be on one line. You don't need to worry too much about the format if you use the pamu2fcfg tool to create the initial contents and to append keys.

Configure PAM for password and U2F 2FA

WARNING
Please have a root privileged shell open before you start, its very possible to break your sudo configuration.
WARNING

In another root privileged shell move the /tmp/u2f_mapping file to /etc/u2f_mapping.
Then open up the file /etc/pam.d/sudo.
We then need to add the following line :

auth	required	pam_u2f.so	 cue authfile=/etc/u2f_mappings

This line breaks down as follows :

  • Auth required, this method must succeed otherwise sudo access is denied
  • Use the pam-u2f.so module to interface with out U2F security key
  • cue, issue a prompt to tap your security device after you enter the sudo command
  • authfile, the system wide mapping file we created in the previous step

This will ensure we need to tap our U2F key and enter our user password for sudo access.
The sudo prompt will look similar to this :

$ sudo uname
Please touch the device.
Password:
Linux
$

Configure PAM for U2F only with password fall back

WARNING
Please have a root privileged shell open before you start, its very possible to break your sudo configuration.
WARNING

In another root privileged shell move the /tmp/u2f_mapping file to /etc/u2f_mapping.
Then open up the file /etc/pam.d/sudo.
We then need to add the following line :

auth	sufficient	pam_u2f.so	 cue authfile=/etc/u2f_mappings

This line breaks down as follows :

  • Auth sufficient, this method can be used as a single factor login, when not present it will fall back to password authentication.
  • Use the pam-u2f.so module to interface with out U2F security key
  • cue, issue a prompt to tap your security device after you enter the sudo command
  • authfile, the system wide mapping file we created in the previous step

When the Yubikey is plugged in, you will not be required to enter your password, you will only need to tap the device.
When the Yubikey is not present, this method will fall-back to password auth.
The sudo prompt will look similar to this :

$ sudo uname
Please touch the device.
Linux
$

Debugging

If you need to debug what is occurring you have two options :

  • debug logs sent to console during use
  • debug logs sent to file

I prefer the second method as I find it cleaner/easer to search.
If you need to debug issues, edit the /etc/pam.d/sudo to look like this :

auth	required	pam_u2f.so	 cue authfile=/etc/u2f_mappings debug_file=/tmp/u2f_debug

You must create the file, PAM will not do this for you.
This log is verbose enough that you should be able to spot any simple misconfiguration.

References