Skip to content

I recently picked up a Yubico YubiKey 5C NFC, a small yet powerful security key that adds an extra layer of protection to my logins. This versatile device supports various security protocols, including FIDO2, U2F, OTP (One-Time Password), and smart card (PIV). Major tech companies like AWS, GitHub, Twitter, Google, Microsoft, and Apple all support security keys for their login processes, highlighting their importance in modern cybersecurity.

One of the standout features of the YubiKey is its adherence to open standards, making it easy to integrate with various products and services. Inspired by its capabilities, I decided to set up LUKS (Linux Unified Key Setup) encryption on my Linux drive to utilize my YubiKey for unlocking it.

Background: Security Keys and Challenge-Response Authentication

Supported YubiKeys

The following YubiKeys support challenge-response authentication, which is essential for integrating with LUKS:

  • YubiKey 5 Series: Includes the YubiKey 5C NFC, YubiKey 5Ci, YubiKey 5 NFC, and YubiKey 5 Nano.
  • YubiKey 4 Series: Includes the YubiKey 4, YubiKey 4C, and YubiKey 4 Nano.
  • YubiKey NEO and NEO-n: Also support challenge-response functionality.

These YubiKeys can be used for a variety of security purposes, including two-factor authentication, passwordless login, and encryption key management.

What is LUKS?

LUKS, or Linux Unified Key Setup, is a disk encryption specification created for securing data on Linux systems. It provides a standard format for disk encryption that is not only secure but also highly flexible. LUKS uses a combination of symmetric encryption (AES) and a key derivation function (PBKDF2) to protect data. It supports multiple passphrases (keys) and integrates seamlessly with various authentication mechanisms, including hardware security keys.

Setting Up LUKS Decryption with YubiKey

Prerequisites

  • A Linux system with LUKS set up
  • A YubiKey 5C NFC or another compatible YubiKey (see above)

Step 0: Locate the drive that LUKS is set up on

Run lsblk to verify that you have a LUKS drive to use.

1
lsblk -f | grep LUKS

if you see an output identifying a drive with a filesystem crypto_LUKS, you have a LUKS drive. In my case, that’s at /dev/sda3. If you don’t see anything, you don’t, and should fix that pretty quickly. Double-verify that you’re working with the right drive by running the following command (modified to match your drive from the previous command).

1
sudo cryptsetup luksDump /dev/sda3

If you see information about your LUKS drive, congrats, you’ve got one set up.

Step 1: Install Required Packages

First, ensure that you have the necessary tools installed on your Linux system. You can do this by running the following commands:

1
2
sudo apt update && sudo apt upgrade -y
sudo apt install yubikey-luks yubikey-personalization

Step 2: Prepare Your YubiKey

Next, configure your YubiKey to work with LUKS. This involves setting up a YubiKey slot to store the challenge-response secrets used by LUKS. Insert your YubiKey and run:

1
ykpersonalize -2 -ochal-resp -o -serial-api-visible

This adds an HMAC challenge-response process onto the second slot of the key, so it shouldn’t interrupt anything in the primary process. Challenge-response authentication involves a system presenting a challenge (usually a random string) to the user or device, which must then generate and return a valid response using a pre-shared secret or cryptographic algorithm. This process ensures that the party generating the response possesses the necessary credentials without directly transmitting sensitive information, thereby enhancing security. Test your setup on the second slot with the following command.

1
ykchalresp -2 YOUR_LOGIN_PASSWORD_HERE

If everything is working, your YubiKey should start slowly blinking until you tap it with your finger. Once you do, the console should spit out the challenge response result. Keep that and use that in the following step.

Why do all this? Basically, think of what we have going on as putting a SHA1 hash on the second slot of our key. When you’re logging in to Google with a security key, you need your username and the PIN-protected security key. If we were to only ask for the presence of the security key , then we would allow anyone with physical control of the key the ability to unlock a LUKS-encrypted drive, which is a lot of work and a decent amount of money to make it arguably EASIER to log in to your computer. As such, doing this challenge-response will require someone to not just have the YubiKey but also know an unlock password that you should probably make wholly unique to this process.

Step 3: Add the secret key to LUKS

Add this result from the previous command to the proper partition.

1
cryptsetup --key-slot=7 luksAddKey /dev/sda3

Be very careful when doing so! You can remove the key with cryptsetup --key-slot=7 luksKillSlot /dev/sda3 and re-running the command, but it can get annoying and is the most important part of this setup.

Notice how we’re specifying a --key-slot=7? LUKS can contain up to 8 keys, numbered index-style 0-7. These keys are deeply configurable, but that’s not what I’m writing about today. The current password encrypting the LUKS drive is currently stored at --key-slot=0, and what we just did is add the output we’re expecting from the challenge-response to the last slot.

Step 4: Update the login script to ask for LUKS

!!CONTINUE AT YOUR OWN RISK!! Do NOT continue to the following step without being ABSOLUTELY sure you have a recovery kernel, a second kernel installed, some kind of live Linux media, whatever. If you install this script and it doesn’t work, it’s not game over, but it’s going to be a PAIN to fix. If you decided to not heed this warning and are trying to figure out where you went wrong, you’re gonna have to find a way to mount the drive again using your old LUKS password without going through the login prompts using one of the methods I described above.

replace the file at /usr/share/yubikey-luks/ykluks-keyscript with the script from here. What this script does is replace the prompts in the login process to first check if a YubiKey is connected and ask the user for a password, activate the challenge-response authentication on the second slot of the YubiKey, and then attempts to unlock the LUKS drive with the response. I have thoroughly tested this script myself, but please feel free to email me if you have any issues or questions about it.

Once this is done, rebuild your kernel to include this updated script. Figure out which kernel to use like so:

1
2
3
4
ls /boot | grep vmlinuz

vmlinuz-6.6.9-amd64
vmlinuz-6.8.11-amd64

If you have multiple kernels installed and know what that means, you should know which kernel to use. If you have multiple and you don’t know, you’re generally going to be booting into the highest-versioned kernel (in my case, that’s 6.8.11-amd64). If you have only one kernel, re-read my warning above, and then proceed with that kernel.

1
sudo update-initramfs -u -k 6.8.11-amd64

This will rebuild your specified kernel with the script you just added. Note that you shouldn’t include the vmlinuz- part of the kernel name from the previous command’s output.

Step 5: Reboot and test

Run sudo reboot -f. If everything went well, the kernel you specified above should now be asking you for a YubiKey. Plug it in, type the password you used as YOUR_LOGIN_PASSWORD_HERE, and enjoy.

Step 6: Further kernel hardening

Advanced readers may already be noticing the biggest flaw in this setup. While the script forces the use of both a password and a KubiKey, that only applies to the kernel that the script has been applied on. If someone boots into another kernel on the system or even takes the drive to a different PC, the original LUKS key is still in slot 0, so if someone knew the password but didn’t have your key they could still gain access to the drive.

The obvious answer to this might be to delete the key in slot 0, which would absolutely work, but if your YubiKey was ever lost or destroyed or otherwise inaccessible you would have no way of accessing the drive anymore. Some solutions to this would be to get a second YubiKey, repeat these steps and add it to slot 6, a and keep in a safe location only for emergency unlocks. Ideally you should never have only one key installed on a LUKS drive that requires a YubiKey.

Additionally, in these steps we have only secured the primary kernel of your machine. If you have multiple kernels, after you have confirmed that you can log in, run update-initramfs again on those kernels to require them to use your YubiKey as well. Generally from that point forward kernel updates will no longer require you to manually re-generate the kernel, but in some niche updating scenarios that may not be the case.

Conclusion

Incorporating a YubiKey into your security routine, especially for tasks like unlocking an encrypted Linux drive, offers a robust and convenient way to enhance your cybersecurity. The combination of LUKS encryption and YubiKey authentication ensures that your sensitive data remains secure, even if your device falls into the wrong hands. Whether you’re an individual user or managing a team’s security, the YubiKey provides a reliable solution for safeguarding your digital assets.