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. This 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 in the future. It is even possible to backup the LUKS header and the key slot areas. If an attacker is able to do so and learns about any password, the attacker can decrypt your hard disk in the future – even if you change all of your passwords for it. 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. This 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; on newer system that use NVM Express, names are similar to
/dev/nvme0n1p3. For instance, the output of
sudo fdisk -l shows “Disk /dev/mapper/nvme0n1p3_crypt”. Then, the partition name is likely
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 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 will be the text visible on 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 will be written to the LUKS key slot. For instance, “0123456789ABCDEF”.
1: If you set it to 1, your challenge password + the YubiKey response will be written to the LUKS key slot. For instance, “challengepassword0123456789ABCDEF”.
HASH=: This option changes whether your cleartext password or its hash value will be used as a challenge for the YubiKey.
0(default): The challenge is your challenge password in cleartext.
1: The challenge is the hash value of your challenge password (SHA-256 is used).
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, you will be asked for two different passwords:
- Enter your challenge password twice. This 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 prior to setting up the new YubiKey configuration. It will ask for “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:
Afterwards, 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 normal 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]. You will be asked for a passphrase. This will be the 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 will only remove the first appearance. Repeating the same command, will remove 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:
Using this setup, 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 in order 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