TFA: Basic Two-Factor Authentication Using Yubico’s Yubikey

The Yubico Yubikey is an authentication token which supports a wide variety of authentication standards and allows one to add a second authentication factor to RHEL/Fedora logins. For this example, I’ll be implementing 2FA on sudo sessions using the Yubikey supported, Universal 2nd Factor (U2F) authentication standard. Once I’m comfortable with this I’ll be expanding 2FA to other session authenticators such as my desktop and lock-screen logins, and will update this post with additional instructions.

This initial setup was performed on a Fedora 38 instance but should be portable to RHEL versions 7-9. A note of caution since we will be manipulating Pluggable Authentication Module (PAM) configuration files. A misstep with a PAM file can lead to an unreachable machine. Tests should always be performed on a non-production system. It’s also a great help to keep a virtual-console open and logged in as root so that you can easily back out any erroneous changes that suddenly make logging in as a regular, non-root user impossible.

First, install the prerequisites. U2F on Fedora requires the following 2 packages:

  • pam-u2f
  • pamu2fcfg

Next, log in as a non-root user and create a directory to hold the authfile which maps your user’s name to the key Handles and user keys that your yubikey uses at authentication-time. The default location for this file is in $HOME/.config/Yubico/.

You will want to do this for each user who will be using 2FA to authenticate with this machine:

mkdir -p /home/username/.config/Yubico/

Next, insert the Yubikey into a USB port and run the following to generate the authfile:

pamu2fcfg > /home/username/.config/Yubico/u2f_keys

After issuing this command you should see the LED blinking on the Yubikey you inserted. Touch the metal contact on the body of the key to complete this process.

Now would also be a good time to create an extra backup-key to be stored in a safe place in case your primary key is lost or damaged. Remove the previously inserted Yubikey, and insert a backup and run the command:

pamu2fcfg --nouser >> /home/username/.config/Yubico/u2f_keys

Finally, here comes the dicey part, editing PAM files. It’s honestly not that bad but special care should be taken any time you edit your PAM configuration. One careless move could ruin your whole day.

I’m starting with requiring 2FA before escalating to root with the sudo command. This is a safe place to start since I can always login directly as root to fix things should they go wrong. Authentications involving sudo are controlled by the configuration stored at /etc/pam.d/sudo. A baseline, Fedora38 installation should look like this:

$ cat /etc/pam.d/sudo
%PAM-1.0

auth include system-auth
account include system-auth
password include system-auth
session optional pam_keyinit.so revoke
session required pam_limits.so
session include system-auth

We’re going to change auth include system-auth to auth substack system-auth and insert a line underneath it that says, auth required pam_u2f.so cue [cue_prompt=Touch your Yubikey]

So after edits, your /etc/pam.d/sudo file should look like this:

$ cat /etc/pam.d/sudo

%PAM-1.0

auth substack system-auth
auth required pam_u2f.so cue [cue_prompt=Touch your Yubikey]
account include system-auth
password include system-auth
session optional pam_keyinit.so revoke
session required pam_limits.so
session include system-auth

If you’re still with me, congrats, the hard part is over. The next step will be to switch over to an unused virtual-console with Ctrl-Alt-F{1..8}, login as the user you created the authfile for and attempt to do something with sudo. The interaction should look something like this:

[dan@tfatesting ~]$ sudo echo "Hello 2FA!"
[sudo] password for dan:
Touch your Yubikey
Hello 2FA!

Note that you will still have to give your password and then touch the metal contact on the Yubikey when prompted. This is because we’re using two factor authentication to complete this ‘sudo echo’ command. The two factors at play here are “Something you know”: your password and “Something you have”: your Yubikey. Touching your key is Yubikey’s way of being certain that a physical token is present and isn’t being spoofed by a bad actor.

A note about the [cue_prompt=] directive in our /etc/pam.d/sudo configuration file. The man page for pam_u2f points out that the prompt could help “an attacker […] determine that pam_u2f is part of the authentication stack” so there is a UX vs. security determination to be made here. If you are the paranoid type then it would probably be a good idea to set this prompt to something that doesn’t specifically mention the type of authenticator being used, or to an empty string if that doesn’t break your UX altogether. That will come down to how well educated your users are. The default that you get if you leave out the cue_prompt directive is “Please touch the device” which is something I could envision leaving several users with funny looks on their faces.

dcd

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.