pam-u2f, YubiKeys, what the hell?
PAM PAM PAM PAM?
PAM as in Pluggable Authentication Modules is the implementation of a
modular mechanism for authentication in Unix-like operating systems, mostly
GNU/Linux environments. It allows system administrators to define how
authentication, session management, and account policies are enforced,
independently of applications that require authentication.
PAM consists in a set of shared libraries that applications can interact with
to authenticate users. Configuration of these modules is done through
/etc/pam.d/ directory. They can be stacked in order to define security policies.
This is where pam-u2f comes into play.
pam-u2f?
pam-u2f is a PAM module that enables authentication using Universal Second
(2nd) Factor (U2F) security keys (like, oh wait, YubiKeys) as a second factor
for two-factor authentication (usually referred as 2FA), significantly
increasing the system security.
It can also serve as a way to authenticate without typing in a password (passwordless authentication), but in that case one loses the second-factor.
So, in short, pam-u2f has the following main features:
- Two-Factor Authentication: The thing we’ll discuss about here, it requires both a password and physical possession of a U2F key.
- Passwordless Authentication: Can be configured to allow logins solely with a U2F key.
Setting up pam-u2f
To deploy pam-u2f, on a Debian-based system, run:`
sudo apt install libpam-u2f
For U2F to work, each user with a YubiKey need a mapping, happily there is a binary for that. By default, it generates a configuration requiring user presence verification (ie touching the key). This can be disabled (but would be less secure), and other options can be enabled to increase security, eg PIN verification (which we will use there).
Run the following command to generate a U2F mapping:
pamu2fcfg -N > ~/.config/Yubico/u2f_keys
The file path is the default one for pam-u2f to look when a user
authenticates themselves. This can be configured (which might be useful to make
things more secure by enforcing the U2F keys for each user and making them non-configurable).
Just note that the PIN verification might induce problems with screenlockers that do not support them.
Currently under wayland I did not manage to find a screenlocker that works
nicely. The way screenlocking works under wayland is significantly distinct
from the way Xorg was working, and I believe most screenlocker therefore were
worked on in order to actually work. PIN prompt and presence verification are
multi-step conversations with PAM, and only the gnome-shell screenlocker
(there is no longer a dedicated gnome-screensaver app) seems to work well
with that, but it’s not usable on another desktop environment than Gnome.
Therefore if one works under Wayland, except if using Gnome some screenlocker are able to handle presence verification, but not PIN+Presence.
Enabling pam-u2f
Depending on the system on which one wants to use U2F, there are multiple ways
to configure it. I’ll describe some generic usages here, and then the one I use
on my laptops, which essentially is putting the pam-u2f in place at the
common-auth step (which means almost all authentication method will need
U2F to work).
Some interesting options:
authfile=/absolute/path: allows to point to the file with the mappings if one wants to enforce central configurationuserpresence=0|1: force the user to show their precense by touching the key (the default is to use the instructions in the mapping file)pinverification=0|1: force the user to type in their pin (the default is to use whatever is set in the mapping file)cue: prompt to touch the key if needednouserok: makes the module return success if the user doesn’t have a mapping file or is not in the central mapping file.
Global setup
At the end of /etc/pam.d/common-auth, add the line:
auth required pam_u2f.so authfile=/etc/u2f_mappings_file nouserok cue
Mode specific setup
If one doesn’t want to have a global setup, here are examples to put U2F only
on specific tools.
sudo
Adding U2F authentication to sudo ensures an additional layer of security
when executing privileged commands:
sudo ${EDITOR} /etc/pam.d/sudo
Add the following line:
auth required pam_u2f.so
SSH Login
Enhance SSH security by requiring a U2F key for login.
This one is a bit trickier. The idea is to secure SSH logins on a remote
machine. SSH has its own authentication mechanism through
PasswordAuthentication or KbdInteractiveAuthentication. In general distros,
I can’t certify whether or not SSH Daemon relies on PAM. In Debian, by default,
we enable the UsePAM bit.
One therefore needs to make sure it’s properly configured in
/etc/ssh/sshd_config. One also needs to make sure that
ChallengeResponseAuthentication is set to yes.
The YubiKey needs to be in the client machine logging in the SSH server,
and the U2F keys config file must be in the user home on the server.
sudo ${EDITOR} /etc/pam.d/sshd
Add:
auth required pam_u2f.so
Warning
Ensure ChallengeResponseAuthentication yes is enabled in
/etc/ssh/sshd_config.
GDM Login
Let’s say one uses Gnome and wants a second layer at login:
sudo ${EDITOR} /etc/pam.d/gdm-password
Add:
auth required pam_u2f.so
What I would recommend doing
Every person has their own way of working and their own security expectations, I’m no one to tell somebody else how they should do it, except at work, where it’s part of my job. That being said, I can still recommend or underline some things:
- Using
pam-u2fis not hard; - In general, all administration options should rely on a MFA model, so I
really would suggest to rely to either
U2For someTOTPfor sudo runs; - Having some
U2FforSSHaccess might reduce the impact ofMITM1 attacks. Of course one should still be very wary when they seeSSHhost key changes (and try to avoidTOFU2 model when accessingSSHplatforms for the first time).
In the whole, there is little setup, and this is quite reliable.