From Gentoo Wiki
Jump to:navigation Jump to:search

Many YubiKeys can be configured to provide FIDO/U2F authentication. This can be configured with the pam_u2f.so module in PAM.


YubiKeys provide several interfaces which can be used to authentication or encryption. The U2F/FIDO module can be used to provide authentication for both SSH and PAM, and is commonly used with web services.

PAM is used to provide centralized authentication on Linux systems, using pluggable modules. It is typically used as the backend for TTY authentication as well as most local services which require authentication, such as the login manager, screensavers/lockscreens, and privilege escalation tools such as doas or sudo. Using PAM control directives, the required authentication factors can be adjusted depending on what type of service is attempting authentication.

When a username and password are used for authentication, PAM typically uses a combination of the /etc/passwd and /etc/shadow files to map users to their passwords. In order to use a YubiKey with PAM, a file which maps users to their YubiKeys is needed. This can be a central file such as /etc/u2f_mappings or a per-user file such as ~/.config/Yubico/u2f_keys.



Support for raw USB HID devices is required in the kernel for the YubiKey to function.

KERNEL Enable support for raw HID devices
Device Drivers  --->
  HID support  --->
    -*- HID bus support
    [*]   /dev/hidraw raw HID device support
    USB HID support  --->
      [*] /dev/hiddev raw HID device support

USE flags

USE flags for sys-auth/pam_u2f PAM module for FIDO2 and U2F keys

debug Enable debug messages using the pam logging macros.


PAM, is modular by design, and adding modules is straightforward. sys-auth/pam_u2f [1] is required to use a YubiKey with PAM. This package provides the PAM module as well as tools to assist in the confutation of this module.

root #emerge --ask sys-auth/pam_u2f


plugdev group

When udev is being used, /lib/udev/rules.d/70-libfido2-u2f.rules defines rules that change the ownership of the YubiKey or other fido2/U2F compliant device's associated /dev/hidraw{n} to be owned by the plugdev group with the 0660 mode. In order for non-root users to access this, which is required to use pamu2fcfg, users must be added to the plugdev group.

To check the current user's groups, run:

user $groups
tty wheel audio video kvm users user

If plugdev is not listed, the user can be added to the group by running:

root #usermod -a -G plugdev user

The user needs to log out and log back in for the group membership to take effect.

Users don't need to be member of the plugdev group to be able to login with a YubiKey!

Mapping user-tokens

In order to authenticate with PAM using pam_u2f, a key token must be mapped to a user - unless the nouserok module argument is specified. By default, these mappings are read from ~/.config/Yubico/u2f_keys.

A central mapping file such as /etc/u2f_mappings can be configured using the authfile module argument.

Creating user-token mapping (per-user file)

To create a per-user mapping, insert the YubiKey and run pamu2fcfg to create a u2f key mapping for the current user:

user $mkdir -p ~/.config/Yubico
user $pamu2fcfg > ~/.config/Yubico/u2f_keys

Enter the u2f pin and tap the presence detection pad once it starts blinking.

The -u parameter can be used with pamu2fcfg to specify the user.
Mapping additional keys

To map an additional key to the current user, replace the YubiKey with the next one and run:

user $pamu2fcfg -n >> ~/.config/Yubico/u2f_keys

Touch the YubiKey when it starts blinking.

Ensure there is no newline at the end of the file, all key values should be on the first line.

Creating user-token mapping (central file)

Any user that can edit the central mapping file can control the authentication of other users. Ensure that this file is writable only by root or other administrative accounts.

To create a central mapping file, insert the YubiKey and run (replacing user with the appropriate username):

root #pamu2fcfg -uuser >> /etc/u2f_mappings

Touch the YubiKey when it starts blinking.

Mapping additional keys

A little more care is needed when mapping an additional key to a user if a central file is used. It is possible to directly concatenate the output of pamu2fcfg if a second mapping is created right after the first one. Each user is represented by a single line with colon-delimited entries corresponding to a YubiKey:

FILE /etc/u2f_mappingsFormat of the YubiKey mapping file
# <user name>:<keyHandle1>,<public_key1>:<keyHandle2>,<public_key2>:...

Manually copy/pasting the output of the following command onto the end of the relevant user's line in the mapping file is recommended in order to maintain its integrity:

root #pamu2fcfg -n

Touch the YubiKey when it starts blinking. Repeat for any remaining YubiKeys.


Global system authentication is configured through /etc/pam.d/system-auth. Taking a backup of the current PAM configuration will make it easy to revert changes if needed.

A broken PAM configuration can result in every user (including root) being locked out of the system. Leaving a spare root login open (such as in a TTY) while editing the configuration files will save having to boot from a live USB or through single-user mode to fix PAM.
Additional configuration may be needed for successful authentication over SSH if both password and YubiKey are required.

PAM options

While configuring PAM service files in /etc/pam.d/ to work with a YubiKey or other U2F compliant device, several options can be used:

Option Type Description
required control value The given PAM module must succeed in order for the entire management group type (such as auth) to succeed. If the PAM module fails, other PAM modules are still executed (even though it is already certain that the service itself will be denied).
sufficient control value If the given PAM module succeeds, authentication succeeds and the other PAM modules are not executed. If the PAM module fails, then the failure is ignored and PAM continues with the next module.
[value1=action1 value2=action2 ...] control values Advanced combinations using one or many values, validating the return code of the value against the respective action, can be used instead of standard control values.
nouserok module argument Specific to the pam_u2f.so module, allowing for successful authentication in the event that the user is missing an authorization mapping or it is invalid. Without this, any users missing a mapping will fail authentication.
cue module argument Specific to the pam_u2f.so module, prompts Please touch the device. when attempting authentication. If not set, the YubiKey will flash as a prompt, but there may be no on-screen indication.
authfile=/etc/u2f_mappings module argument Specific to the pam_u2f.so module, sets the path for a central mapping file. If this is not set, ~/.config/Yubico/u2f_keys is used by default.
A complete list of options for pam_u2f.so is available here.

Testing PAM with a YubiKey

In order to test that everything works, temporarily configure PAM to use a YubiKey without locking the user out if pam_u2f fails by adding the following line to the top of /etc/pam.d/system-auth:

FILE /etc/pam.d/system-auth
auth        sufficient                  pam_u2f.so      cue

Attempting to log in as a user with a YubiKey mapped should now prompt for it. Providing a correct YubiKey should result in a successful login.

The following examples assume a per-user mapping file is used. If instead a central mapping file is used, it must be included in the PAM configuration:
FILE /etc/pam.d/system-auth
auth        sufficient                  pam_u2f.so      cue authfile=/etc/u2f_mappings
Modifying the examples appropriately is left as an exercise to the reader.
Once the file is saved, changes can be tested by switching to another TTY and attempting to log in.

Requiring a YubiKey

To require a YubiKey to authenticate with PAM, replace sufficient with required:

FILE /etc/pam.d/system-auth
auth        required                    pam_u2f.so      cue

Requiring a password and a YubiKey

To require both a password and a YubiKey to authenticate with PAM, modify the file to include the following:

FILE /etc/pam.d/system-auth
auth        [success=1 default=ignore]  pam_unix.so     nullok try_first_pass
auth        [default=die]               pam_faillock.so authfail
auth        required                    pam_u2f.so      nouserok cue

success=1 means PAM will skip over one module if the current one succeeds. In this case it will jump to the pam_u2f module if the correct password is given.

nouserok is included here so that users without a mapping configured are able to authenticate as well. Leave this out to require all users to provide both a password and a YubiKey.

Requiring a password or a YubiKey

To require either a password or a YubiKey to authenticate with PAM (but preferring the YubiKey), modify the file to include the following:

FILE /etc/pam.d/system-auth
auth        sufficient                  pam_u2f.so      cue
auth        [success=1 default=ignore]  pam_unix.so     nullok try_first_pass
auth        [default=die]               pam_faillock.so authfail

nouserok is not included here because it would result in successful authentication without prompting for a password from users without a mapping configured.

Requiring a YubiKey for Sudo authentication

By default, /etc/pam.d/sudo contains auth substack system-auth, this means it will use whatever is in /etc/pam.d/system-auth for authentication. If system-auth has already been configured to use the YubiKey as desired, and the behavior of system-auth and sudo authentication should be identical, no additional changes are required.

If for some reason, it's desirable to only require YubiKey authentication for sudo, but not system-auth, the following configuration can be used:

FILE /etc/pam.d/sudoRequire YubiKey auth in addition to system-auth
auth    required                pam_u2f.so      cue
auth    substack                system-auth
Additional information on control values such as substack is available in man pam.conf


If no user is able to authenticate after completing the above, then a broken PAM configuration is the likely culprit. Even if no active root login is available, the system can still be fixed and authentication mechanisms restored by either live booting or booting into single-user mode.

Fixing PAM through live boot

These instructions assume a bootable medium with a live ISO, such as a USB, is already created and ready.
Once the filesystem is mounted, make sure to prefix all paths with /mnt to edit the on-disk configurations and not the live ISO's temporary files.

First, completely power off the machine. Insert the bootable medium and boot from it through the machine's firmware boot menu. There are no universal instructions since this process can vary greatly from machine to machine, so consult the relevant documentation if unfamiliar with how to do this.

Open up a root shell when booted, locate the block device corresponding to your root filesystem, and mount it (making sure to specify any required mount options):

root #fdisk -l
root #mount [-o options] device /mnt

Next, either restore a backup PAM configuration or manually edit /mnt/etc/pam.d/system-auth to undo any changes. To non-destructively undo changes, comment out the necessary entries by prepending a # and add any new entries if needed.

Once done, commit the changes to disk, unmount your root filesystem, and reboot:

root #sync
root #umount /mnt
root #reboot

Authentication should be fully restored.

Once successful authentication is confirmed, SELinux users must re-label their filesystem as described here.

Fixing PAM through single-user mode

These instructions assume the machine uses GRUB as the bootloader. Additionally, these instructions assume GRUB doesn't directly load and boot the kernel without displaying the GRUB menu. If another bootloader is used, consult the respective documentation for instructions on achieving a similar result. Alternatively, use the live boot method above.

To enter single-user mode first reboot the machine. When the GRUB menu appears, press E to bring up the menu entry editor. Any edits made in here are temporary and do not edit the on-disk GRUB configuration.

Locate the line which loads the kernel and append init=/bin/sh to it. The actual content and number of kernel command line arguments is likely to differ from system to system, but the end result should look similar to the following:

CODE GRUB menu entry snippet
linux /vmlinuz-5.4.80-gentoo-r1 root=[omitted] ro init=/bin/sh

Press F10 to boot using the present command list.

Once the sh prompt appears, the root filesystem will need to be re-mounted as read/write:

sh#mount -o remount,rw /

Only specifying / will instruct mount to read the entries in /etc/fstab to find the correct block device and to apply the mount options specified therein.

Next, either restore a backup PAM configuration or manually edit /etc/pam.d/system-auth to undo any changes. To non-destructively undo changes, comment out the necessary entries by prepending a # and add any new entries if needed.

PATH will not be set to the usual value, so specifying the full path to an editor may be necessary if manually editing the PAM configuration. If the location of the desired editor is not known, a standard location to check for installed programs is /usr/bin.

Once done, commit the changes to disk, re-mount the root filesystem as read-only, and exit:

sh#mount -o remount,ro /

This will not be a clean exit and the kernel will panic with the message Kernel panic - not syncing: Attempted to kill init!. This is fine because all the filesystem changes were manually sync-ed.

Finally, reboot the system. Authentication should be fully restored.

See also

  • PAM — allows (third party) services to provide an authentication module for their service which can then be used on PAM enabled systems.
  • PAM securetty — restricting root authentication with PAM.
  • Google Authenticator — describes an easy way to setup two-factor authentication on Gentoo.

External resources