Security · July 24, 2021 · 4 min read

Two Factor Authentication on Linux using Yubikey / U2F

Configure pam-u2f for system login, sudo, and su. Individual vs central configuration files, plus passwordless sudo with a Yubikey touch.

U2F security keys are handy little devices that give you a strong second factor for authentication. Google, Microsoft, GitHub, and plenty of others already support them. You can use the same standard to add 2FA to your Linux system for login, sudo, and su.

Prerequisites

This works with any security key that speaks U2F. Yubikeys, Titan keys, doesn’t matter. All Yubikey models support U2F.

Install pam-u2f

The package name varies by distro:

Configure Security Keys for Users

The package comes with pamu2fcfg, a tool that handles key registration. You’ve got two choices for where to store the config.

Individual Configuration File

Each user gets their own config file in their home directory. They can add or remove keys without root. This is the better setup if home directories are accessible at login (no full disk encryption).

Create the config

mkdir ~/.config/Yubico && touch ~/.config/Yubico/u2f_keys

Add your keys

pamu2fcfg -u <USER> -o <ORIGIN ID> -i <APP ID> | tee ~/.config/Yubico/u2f_keys
# e.g. pamu2fcfg -u ashu -opam://ashu.io -ipam://ashu.io | tee ~/.config/Yubico/u2f_keys

For additional keys:

pamu2fcfg -n -u <USER> -o <ORIGIN ID> -i <APP ID> | tee -a ~/.config/Yubico/u2f_keys

Central Configuration File

One config file for all users, stored at /etc/pamu2f.cfg. Only root can modify it, which is a tradeoff. You need this approach if you encrypt home directories, since they only unlock after login.

Create the config

sudo touch /etc/pamu2f.cfg

Don’t give users write permission to this file on multi-user systems. It would expose everyone’s keys.

Add your keys

Plug in the key and run:

echo $(pamu2fcfg -u <USER> -o <ORIGIN ID> -i <APP ID>) | sudo tee -a /etc/pamu2f.cfg
# e.g. echo $(pamu2fcfg -u ashu -opam://ashu.io -ipam://ashu.io) | sudo tee -a /etc/pamu2f.cfg

For additional keys, append with:

pamu2fcfg -n -u <USER> -o <ORIGIN ID> -i <APP ID> | tee -a <Path to config file>

Enable pam_u2f.so in PAM

Add this line to the PAM config of whatever service you want to protect:

auth sufficient pam_u2f.so authfile=<Path to config file> appid=<APP ID> origin=<Origin ID> nouserok cue [cue_prompt=<Prompt to show>]

Real example:

auth sufficient pam_u2f.so authfile=/etc/pamu2f.cfg appid=pam://ashu.io origin=pam://ashu.io nouserok cue [cue_prompt="Please touch your Yubikey to Authenticate"]

Put this as the last line in the auth section of these files under /etc/pam.d/:

File names might differ slightly depending on your distro.

sddm example (BEFORE):

auth include system-login
-auth optional  pam_gnome_keyring.so
-auth optional pam_kwallet5.so
account include system-login
password include system-login
-password optional pam_gnome_keyring.so use_authtok
session optional pam_keyinit.so force revoke
session include system-login
-session optional pam_gnome_keyring.so auto_start
-session optional pam_kwallet5.so auto_start

sddm example (AFTER):

auth include system-login
-auth optional  pam_gnome_keyring.so
-auth optional pam_kwallet5.so
auth sufficient pam_u2f.so authfile=/etc/pamu2f.cfg appid=pam://ashu.io origin=pam://ashu.io nouserok cue [cue_prompt="Please touch your Yubikey to Authenticate"]
account include system-login
password include system-login
...

Keep in mind: some login methods like sddm won’t actually display the prompt asking you to touch your key. It’ll just wait.

Passwordless sudo with U2F

You can set up sudo so that touching your Yubikey is enough. No password needed.

Edit /etc/pam.d/sudo and put this at the very top:

auth sufficient pam_u2f.so authfile=<Path to config file> appid=<APP ID> origin=<Origin ID> cue [cue_prompt=<Prompt>]

Here’s what a passwordless sudo config looks like:

auth sufficient pam_u2f.so authfile=/etc/pamu2f.cfg [cue_prompt=Please Confirm Your Identity.] cue origin=pam://ashu.io appid=pam://ashu.io
auth include system-auth
account include system-auth
session include system-auth

Let me know if I missed anything.

← All posts
Category: Security