Skip to main content

% 16k.es

Configuring RHEL 8 for YubiKey

Table of Contents

An alternative to Google Authenticator.

yubico logo

According to Wikipedia, The YubiKey is a hardware authentication device manufactured by Yubico to protect access to computers, networks, and online services that supports one-time passwords (OTP), public-key cryptography, and authentication, and the Universal 2nd Factor (U2F) and FIDO2 protocols developed by the FIDO Alliance.

To make it work we will need to install some packages from the EPEL repository:

yum -y install pam_yubico ykclient ykpers

(Note: man pages are not nearly as complete as the documentation in the yubico developers page Take a look at it if you need more information).

Insert your YubiKey and run:

ykpersonalize -2 -ochal-resp -ochal-hmac -ohmac-lt64 -oserial-api-visible

Optionally add -ochal-btn-trig and the device will require a button touch; this is hardly a security improvement if you leave your YubiKey plugged in. I guess this is solved with the new Bio Series YubiKeys that will recognize your fingerprint but they are way too expensive.

You should get a similar output to this:

[user@host ~]$ ykpersonalize -2 -ochal-resp -ochal-hmac -ohmac-lt64 -oserial-api-visible
Firmware version 3.4.3 Touch level 1551 Program sequence 3

Configuration data to be written to key configuration 2:

fixed: m:
uid: n/a
key: h:b4...blablahbla...d0
acc_code: h:000000000000
OATH IMF: h:0
ticket_flags: CHAL_RESP
config_flags: CHAL_HMAC|HMAC_LT64
extended_flags: SERIAL_API_VISIBLE

Commit? (y/n) [n]: y
[user@host ~]$

The Yubikey has to be associated to a user. So, logged in as the desired user, run:

[user@host ~]$ ykpamcfg -2
Stored initial challenge and expected response in '/home/user/.yubico/challenge-<serial>'.

At this point you may have to touch the YubiKey button depending on your configuration.

We are almost done!

# Testing

In order to test minimizing the risk of being locked out, make sure you can run sudo. In my case I have a file /etc/sudoers.d/user containing user ALL=(ALL) ALL.

Modify /etc/pam.d/sudo and add this line before auth include system-auth:

auth       required   pam_yubico.so mode=challenge-response

In my case this is the resulting file:

#%PAM-1.0
auth       required   pam_yubico.so mode=challenge-response
auth       include      system-auth
account    include      system-auth
password   include      system-auth
session    include      system-auth

Disconnect the YubiKey and try to run this command:

[user@host ~]$ sudo echo test
[sudo] password for user: 
Sorry, try again.
[sudo] password for user: 
sudo: 1 incorrect password attempt

The sudo command failed, as expected. Now try again after connecting the YubiKey:

[user@host ~]$ sudo echo test
[sudo] password for user: 
test

It works! Now the serious stuff. Want to require the 2FA to log in? Update /etc/pam.d/gdm-password by adding auth required pam_yubico.so mode=challenge-response before auth substack password-auth. This should be the result on a standard RHEL 8 system:

auth     [success=done ignore=ignore default=bad] pam_selinux_permit.so
auth        required      pam_yubico.so mode=challenge-response
auth        substack      password-auth
auth        optional      pam_gnome_keyring.so
auth        include       postlogin
[...]

Save the file. Lock the screen. Make sure your YubiKey is connected. Fingers crossed. Try to unlock.

If you are still reading this, it has worked. And SELinux is still in enforcing mode! 😂

# Moving the challenge file

In some cases you may want to move the challenge file to a path only readable and writable by root. You can do it this way:

sudo mkdir /var/yubico
sudo chown root.root /var/yubico
sudo chmod 700 /var/yubico
ykpamcfg -2 -v
...
Stored initial challenge and expected response in '$HOME/.yubico/challenge-123456'.
sudo mv ~/.yubico/challenge-123456 /var/yubico/<username>-123456
sudo chown root.root /var/yubico/<username>-123456
sudo chmod 600 /var/yubico/<username>-123456

Where <username> is the name of the user that has to be authenticated with the YubiKey. Then you have to add the right path as an option to the PAM module in the PAM file configuration. In our exmaple, the line in /etc/pam.d/gdp-password will read:

auth   required        pam_yubico.so mode=challenge-response chalresp_path=/var/yubico

## 2FA for ssh

There are several methods:

  • OTP via PAM module (pam_yubico). Requires a validation server.
  • U2F via pam-u2f.
  • With OpenSSH 8.2 or higher, FIDO/U2F is natively supported. See OpenSSH 8.2 release notes

maybe addressed in another post.

## Conclusion

Advantages:

  • Easy to configure
  • Usually easier than typing a 6-digit code
  • More convenient than Google Authenticator for frequent use
  • Works offline (or not, but you can choose)
  • No SELinux hassle! It is well supported and you have your booleans if you ever need them:
user@host$ getsebool -a | grep -i yubikey
authlogin_yubikey --> off

Disadvantages:

  • Expensive
  • Even more expensive if you need a backup (recommended)
  • Forget your YubiKey connected and you are screwed
  • Lose your YubiKey and you are (even more) screwed

## References