Configuring RHEL 8 for YubiKey
Table of Contents
An alternative to Google Authenticator.
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