The Linux Unified Key Setup (LUKS) is a platform-independent specification for hard disk encryption. In this tutorial, we use the challenge-response feature of a YubiKey to add two-factor authentication (2FA) to an existing LUKS-protected device.
Always stay in the loop!
Subscribe to our RSS/Atom feeds.
The goal of this tutorial
We add two-factor authentication to an existing LUKS-protected device. 2FA can improve its security if you set strong passwords and enter them in trustworthy environments. After the setup, an attacker needs to either insert your YubiKey and enter a password or enter a backup password.
Technically, you enter a password that is sent as a challenge to the YubiKey. The YubiKey sends a response that unlocks your LUKS-protected device.
Please note that LUKS doesn’t offer ultimate protection against every kind of attacker. An attacker could learn about the password for the YubiKey or your backup password to decrypt your hard disk. It is even possible to back up the LUKS header and the key slot areas. If an attacker gets the LUKS header and any LUKS password, the attacker can decrypt your hard disk – even if you change all of your LUKS passwords. This isn’t a limitation of the YubiKey, but a limitation of LUKS. Therefore, protect your passwords, your YubiKey, and your Linux device accordingly.
For this tutorial, you need:
- root access to a local Linux device that already uses LUKS-based full-disk encryption with a passphrase. Setting up LUKS is typically achieved during the initial setup of your operating system.
- one free LUKS key slot.
- the package “yubikey-luks 0.5.1.” This package is included in the standard repositories of Debian 10, Ubuntu (16.04 to 19.10), and Kali Linux 2019.4. For Arch, there is another tool called “yubikey-full-disk-encryption” (see our external links below) that uses a very similar setup.
- a YubiKey with an unused second slot (or a similar security token that supports challenge-response authentication).
Step 1: Prepare everything
Step 1a: Identify your encrypted partition
For the following tutorial, identify the name of the encrypted partition. You can enter
sudo fdisk -l to list all partitions. On some systems, names look like “/dev/sda3”; newer systems that use NVM Express have names similar to “/dev/nvme0n1p3.” For instance, the output of
sudo fdisk -l shows “Disk /dev/mapper/nvme0n1p3_crypt.” Then, the partition name is likely “/dev/nvme0n1p3.”
Step 1b: Identify a free LUKS key slot
LUKS offers 8 key slots, allowing you to set up 8 different passwords (or keys in files).
sudo cryptsetup luksDump /dev/[partition] (change the partition name according to step 1a). The output lists all 8 key slots. Key slots are either in use (ENABLED) or free (DISABLED). Note down one of the free key slot numbers for your YubiKey.
Step 1c: Generate a new, strong challenge password
Additionally, you need a new password for the YubiKey. This password is technically a challenge sent to the YubiKey. The YubiKey answers with a response that is used to decrypt your hard disk. In the following, we name it the challenge password. Use a strong password.
Besides, there is still your previous password. Your old LUKS password is used for emergency access (e.g., after losing your YubiKey). Of course, this should also be a strong password, so an attacker can’t use brute force to guess it. We name your old password backup password in the following steps.
Step 2: Install the necessary packages
sudo apt update && sudo apt install yubikey-luks to refresh your local package list, and to install yubikey-luks and yubikey-personalization.
Step 3: Configure your YubiKey
After installing the necessary packages, you need to configure your YubiKey.
ykpersonalize -2 -ochal-resp -ochal-hmac -ohmac-lt64 -oserial-api-visible. The single options of this command are:
-2: Use the second slot of the YubiKey. Alternatively, you can enter
-1to use the first slot that is typically preconfigured for Yubico OTP.
-ochal-resp: Set the ticket flag CHAL_RESP.
-ochal-hmac: Set the configuration flag CHAL_HMAC.
-ohmac-lt64: Set the configuration flag HMAC_LT64.
-oserial-api-visible: Set the extended flag SERIAL_API_VISIBLE.
After entering this command, you see the “Configuration data to be written to key configuration 2” on screen.
Check the output and press
y to write the configuration to slot 2 of your YubiKey.
Step 4: Customize the configuration file of yubikey-luks
sudo nano /etc/ykluks.cfg to see the configuration of yubikey-luks.
In the file, you can set three different values:
WELCOME_TEXT=: This is the text visible on the screen when you have to insert your YubiKey and provide your challenge password (or backup password). It is only useful for humans.
CONCATENATE=: This option changes the key written to the LUKS key slot.
0(default): If you set it to 0, only the response of the YubiKey is written to the LUKS key slot. For instance, “0123456789ABCDEF.”
1: If you set it to 1, your challenge password + the YubiKey response are written to the LUKS key slot. For instance, “challengepassword0123456789ABCDEF.”
HASH=: This option changes whether your cleartext password or its hash value is used as a challenge for the YubiKey.
0(default): The challenge is your challenge password in cleartext.
1: The challenge is the hash value (SHA-256) of your challenge password.
Change values if needed, and save the file.
Step 5: Write your configuration to a free LUKS key slot, and set your passwords
In step 1b, you identified a free LUKS key slot. To write your configuration to the LUKS key slot, enter
sudo yubikey-luks-enroll -d /dev/[partition] -s [free-key-slot]. The single options of this command are:
-d /dev/[partition]: Use the specified partition.
-s [free-key-slot]: Use the specified LUKS key slot on the specified partition.
For instance, LUKS key slot 6 is free and our LUKS partition is
/dev/nvme0n1p3, then the full command is
sudo yubikey-luks-enroll -d /dev/nvme0n1p3 -s 6.
After entering the command, the tool needs two passwords:
- Enter your challenge password twice. The challenge password is the challenge sent to your YubiKey each time.
- Finally, enter an existing LUKS password once. Typically, this is your previously-used LUKS passphrase (the backup password).
If you want to reconfigure a key slot that is already in use, append the option
sudo yubikey-luks-enroll -d /dev/nvme0n1p3 -s 6 -c. This command clears the LUKS key slot before setting up the new YubiKey configuration. It asks, “Enter any remaining LUKS passphrase.” Just enter your previously-used LUKS passphrase (the backup password).
Step 6: Modify your /etc/crypttab file to use the YubiKey
We need to modify the crypttab file. Enter
sudo nano /etc/crypttab, and add
keyscript=/usr/share/yubikey-luks/ykluks-keyscript as described below.
Look for a line similar to:
Change it to:
Afterward, save the file and close your editor. Then, enter
update-initramfs -u. The output is similar to “update-initramfs: Generating /boot/initrd.img-5.3.0-kali3-amd64.” You can ignore any warnings. They are also shown during regular kernel updates.
Step 7: Reboot your device and test your passwords
Finally, reboot your system. Your screen should look similar to the following screenshot:
You should be able to either:
- enter any passphrase that already existed before you configured your YubiKey (e.g., your backup password), or
- enter your challenge password to get a response from the connected YubiKey.
Try all possibilities to ensure that everything works as expected.
Optional step 1: Enable and start the module yubikey-luks-suspend
Additionally, you can enable and start “yubikey-luks-suspend.” It automatically locks your LUKS partitions and wipes keys from memory on suspend. If you want this, enter
sudo systemctl enable yubikey-luks-suspend and
sudo systemctl start yubikey-luks-suspend.
Optional step 2: Set or modify other LUKS keys
Optionally, you can add, modify, or remove other LUKS keys.
Add a LUKS key
sudo cryptsetup luksAddKey /dev/[partition] -s [free-key-slot]. The tool needs a current LUKS key, and sets another LUKS key.
Modify a LUKS key
sudo cryptsetup luksChangeKey /dev/[partition] -s [key-slot-in-use]. You will be asked for the old and a new passphrase.
Remove a LUKS key
There are three different ways to achieve this:
sudo cryptsetup luksRemoveKey /dev/[partition]: This command asks for a passphrase to be removed. If you set the same passphrase multiple times, it only removes the first appearance. Repeating the same command removes the next appearance.
sudo cryptsetup luksKillSlot /dev/[partition] [key-slot-in-use]: This command removes the specified key slot.
For more commands, enter
man cryptsetup on your device.
Follow us on Mastodon:
By implementing this tutorial, LUKS encrypted partitions are protected using two-factor authentication (you own the YubiKey and know the challenge password). Keep in mind that your other LUKS keys must also be strong to protect your system, and understand the above-mentioned limitations of LUKS.
We successfully tested this tutorial on Kali Linux 2019.4.
- yubikey-luks (Debian, Ubuntu, Kali Linux)external link
- yubikey-full-disk-encryption (Arch)external link