Authenticating Linux (LUKS) Full-Disk Encryption and System Access with USB Stick
Too stingy to buy a fancy authentication device like a YubiKey? A regular old USB stick you have lying around will do, too*!
Preparing Keyfile and USB stick
Prerequisites are an already configured LUKS setup accessible with an ordinary passphrase. The strategy will be to add a second key to the encrypted partition that will be sufficient to unlock the device. This key will be present as a keyfile and be stored on the USB drive. Then, we'll tell LUKS about this second keyfile and how to access it. But first, we'll generate the keyfile [1]:$ dd if=/dev/urandom bs=1 count=256 > luks_keyfile.binThis will generate a keyfile consisting of 256 random bytes named
luks_keyfile.bin
in the current directory.
Next, identify the encrypted partition:
$ sudo blkid | grep crypto_LUKSFor me, the partition is
/dev/nvme0n1p1
. Next, add the keyfile. You will have to enter the passphrase of any
existing keys in order to complete this operation:
# cryptsetup luksAddKey /dev/nvme0n1p1 luks_keyfile.binNext, mount the USB stick, ensuring it is formatted with some filesystem that can easily be mounted during early boot, for example exfat. Take a look at all block devices known to the system:
$ lsblk ... sdd 8:48 1 57.3G 0 disk └─sdd1 8:49 1 57.3G 0 part ...Mount the USB device using
sudo mount /dev/sdd1 /mnt
. Copy luks_keyfile.bin
somewhere on the stick:
$ sudo cp luks_keyfile.bin /mnt/Finally, take a note of the UUID of the USB stick partition, we'll need it in order to tell LUKS how to identify the device:
$ sudo blkid | grep sdd1 /dev/sdd1: UUID="AB12-2345" BLOCK_SIZE="512" TYPE="exfat" PARTUUID="bdedede-01"With the keyfile on the stick and the key added to the partition, we can move on to tell LUKS about it during boot.
Loading the Keyfile during Boot
We'll need to modify the cmdline of the Linux kernel used by your system, and for this, you need to know the bootloader that executes it. Common choices include bootloaders like GRUB, systemd-boot, or booting Linux directly using your Mainboard's EFI implementation [2].efibootmgr
to modify the entry corresponding to Linux. I currently use systemd-boot
, and the
configuration file for Arch Linux is in /boot/loader/entries/arch.conf:
# cat /boot/loader/entries/arch.conf title Arch Linux linux /vmlinuz-linux initrd /amd-ucode.img initrd /initramfs-linux.img options cryptdevice=UUID=1212-1212:root root=/dev/mapper/root rwHere we see that the
cryptdevice
directive is used to inform LUKS to take the encrypted partition corresponding to the
supplied UUID 1212-1212
and map it to the name root
. Modify the command line with the cryptkey
directive [3]:
options cryptdevice=UUID=1212-1212:root cryptkey=UUID=AB12-2345:exfat:/luks_keyfile.bin root=/dev/mapper/root rwThe UUID corresponds to the UUID of the USB drive partition you identified using
blkid
above. exfat
informs LUKS
of the file system, and after the final colon, the path to the keyfile is expected.
That is all! Now, during boot it will be attempted to mount the USB key and use the keyfile to decrypt the partition. If the USB key is
not present, the system will fall back to using the passphrase.
Using the same USB stick for passwordless login.
We can go further and use the same USB stick to save us from having to enter passwords when it is plugged in by configuring Linux PAM. First, we install the pam_usb module. Then, using an arbitraryDeviceName
and having the USB
stick plugged in, we enroll it:
# pamusb-conf --add-device DeviceNameThe tool will prompt to select the device. Afterwards, add the user for which the stick should authenticate:
# pamusb-conf --add-user georgFinally, we configure PAM and tell it the authentication provided by the
pam_usb
module will be sufficient
to authenticate the user. In /etc/pam.d/system-auth
, add the line:
auth sufficient pam_usb.soThis line should appear after
pam_faillock.so
, if present, as this module takes care of locking the user account in
case of too many invalid password attempts. Putting pam_usb.so
before this module would circumvent this security measure, which
would probably be (minor) security issue. Finally, the line should come before pam_unix.so
, which is the standard unix
authentication module. My file begins like this:
#%PAM-1.0 auth required pam_faillock.so preauth auth sufficient pam_usb.so -auth [success=2 default=ignore] pam_systemd_home.so auth [success=1 default=bad] pam_unix.so nullok ...And that should be all there is to it!
Security Implications
An important security implication is that the key is not only stored on the USB device, but that anyone can retrieve it. This is the primary difference to devices like Yubikey or Solo Keys. These ensure that the key never leaves the device, and authenticate themselves not by transmitting the key, but proving ownership of the key by means of some challenge-response mechanism. The implication is that if you leave the usb stick sitting on your desk, an attacker could simply copy the key and gain access to your system. For me this is a minor concern as the computer I'm using this with is stationary, but for your circumstances, things might look different.If you ever lose the USB stick, or think that the key is compromised, you can simply remove the key using
cryptsetup luksKillSlot
.