Passwordless or MFA with Yubikey
I use Ubuntu and Yubikeys but this works for other security keys and Linux OSes as well.
Prerequisites
Install required software.
sudo apt install libpam-u2f
Add your Yubikeys to the system
Create the directory.
mkdir -p ~/.config/Yubico
Add your first Yubikey (we will add additional keys later).
pamu2fcfg > ~/.config/Yubico/u2f_keys
Press they key when it's flashing.
To add additional keys (highly recommended).
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys
And again, press they key when it's flashing.
Authentication possibilities
You can pick and chose how you want to use your Yubikeys.
Add the cue option to display "Please touch the device." message.
MFA
The MFA method - this will require a password and then the Yubikey.
@include common-auth
auth required pam_u2f.so cue
Passwordless
The passwordless method - this will require the Yubikey only.
#@include common-auth
auth required pam_u2f.so cue
Fallback
The fallback method - this will prompt for Yubikey but if it's not found it will fallback to password.
auth sufficient pam_u2f.so cue
@include common-auth
Where to implement
Login
For Ubuntu 17.10 and newer
sudo nano /etc/pam.d/gdm-password
Ubuntu 17.04 and older
sudo nano /etc/pam.d/lightdm
sudo
sudo nano /etc/pam.d/sudo
GNOME Authentication popup
sudo nano /etc/pam.d/polkit-1
TTY
sudo nano /etc/pam.d/login
Additional security
sudo timeout
If you want the sudo authentication prompt every time you run sudo.
sudo visudo
Apply ,timestamp_timeout=0 to the end of Defaults env_reset
Meaning that you will replace
Defaults env_reset
with
Defaults env_reset,timestamp_timeout=0
Lock the computer when the Yubikey is removed
Get the vendor and model ID of your Yubikey. Connect your Yubikey and run
udevadm monitor --environment --udev | grep 'ID_VENDOR_ID\|ID_MODEL_ID'
Now disconect your key and you should see something like this
ID_VENDOR_ID=1050
ID_MODEL_ID=0407
Create udev rules
sudo nano /etc/udev/rules.d/85-yubikey.rules
Paste this and replace the vendor and model ID with the ones you got in the previous step.
# Yubikey Udev Rule: running a bash script in case your Yubikey is removed
ACTION=="remove", ENV{ID_VENDOR_ID}=="1050", ENV{ID_MODEL_ID}=="0407", RUN+="/usr/local/bin/gnome-screensaver-lock"
Now create a new file
sudo nano /usr/local/bin/gnome-screensaver-lock
And add this. Replace USERNAME with your actual username.
#!/bin/bash
# Double checking if the Yubikey is actually removed
if [ -z "$(lsusb | grep Yubico)" ]
then
logger "YubiKey Removed or Changed"
sessionids=`/bin/loginctl list-sessions | grep USERNAME | awk '{print $1}'`
for id in $sessionids
do
logger "Locking session id:" $id
/bin/loginctl lock-session $id
done
fi
Make the script executable
sudo chmod +x /usr/local/bin/gnome-screensaver-lock
Reload the udev rules
sudo udevadm control --reload-rules
sudo service udev reload
Access to the u2f_keys file
To secure this even further we can move the u2f_keys file to a part of the filesystem where you can't access it without root.
Create the directory.
sudo mkdir /etc/Yubico
Move the config.
sudo mv ~/.config/Yubico/u2f_keys /etc/Yubico/u2f_keys
NOTE: After this is done you can't modify the file without your key. If you lose your key you're locked out. Always use two or more Yubikeys to prevent lockout.
This is also a bad idea if you have an encrypted /home directory since root wound be able to read it.
Add authfile=/etc/Yubico/u2f_keys to the end of every pam_u2f.so line.
Meaning that you will replace
auth required pam_u2f.so cue
with
auth required pam_u2f.so authfile=/etc/Yubico/u2f_keys cue
LUKS
You can use your Yubikey to unlock LUKS at boot. This requires you to already have an encrypted disk which you unlock with a password when your computer starts.
Install Yubikey LUKS
sudo apt install yubikey-luks
Backing up your LUKS headers
Before we start, let's backup the LUKS headers. Make sure to change the path to something that exists and copy the backup to an USB stick or anywhere else that's not the encrypted drive.
sudo cryptsetup luksHeaderBackup /dev/nvme0n1p3 --header-backup-file /path/to/backup/${HOSTNAME}-LUKS-header.backup-$(date -u +%Y-%m-%d_%H-%M-%S)
Find the name of your encrypted partition.
lsblk | grep crypt
nvme0n1p3_crypt so we will use /dev/nvme0n1p3
Now we want to use an unused key slot for the Yubikeys. If you only use a single password to unlock your disk it will probably use just slot 0.
sudo cryptsetup luksDump /dev/nvme0n1p3