Introduction
Hello everyone,
I recently bought a new laptop. While unboxing it, two things came to mind:
- I should try out a new distro—NixOS is slowly pissing me off.
- I want to take security more seriously.
So, off to the races it was. I installed Void Linux with LUKS disk encryption. A few months later, I also bought a YubiKey. I now want to show you all the steps I took to set it up.
Installation of Basic Packages
I first installed some packages that seemed to be related:
xbps-install u2f-hidraw-policy gnupg2-scdaemon ykpers yubikey-manager pcsc-ccid pcsclite
After that, I enabled the pcscd service:
ln -sv /etc/sv/pcscd /var/service
PAM
This is the easiest part. Configuring PAM allows you to use sudo, swaylock, (insert your favourite greeter here), and a lot of other programs that normally want your password.
I mostly followed the Gentoo Wiki here.
First, install pam_u2f:
xbps-install pam-u2f
Then, to use the pam_u2f module, enable it for system-auth by adding the following to the top of /etc/pam.d/system-auth:
auth sufficient pam_u2f.so cue
If you want to require a YubiKey, replace sufficient with required.
Adding the YubiKey
First create the directory and then generate the key file:
mkdir -p ~/.config/Yubico
pamu2fcfg > ~/.config/Yubico/u2f_keys
Note that you have to touch the key in the second step!
Most applications should already work by now, but for me, sudo didn’t.
Sudo
For some reason, on Void Linux, sudo does not seem to use the global PAM configuration.
You can change that by replacing the contents of /etc/pam.d/sudo with the following:
#%PAM-1.0
auth substack system-auth
Disk Encryption / LUKS
Warning: This method is a really bad and ugly solution. I do not take any responsibility for any potential loss of data.
This is where I really struggled.
According to the Arch Wiki, I can just use the yubikey-full-disk-encryption package to enroll my key. But of course, that package did not exist in the Void repos.
So I looked at its source code, only to find out that it is pretty Arch-dependent.
Later, I stumbled upon Clevis Extra Pins, which provided a Clevis integration for YubiKeys.
First, I downloaded the two scripts from the repo to /usr/bin and made them executable:
wget -O /usr/bin/clevis-encrypt-yubikey https://github.com/anatol/clevis-extra-pins/raw/refs/heads/main/clevis-encrypt-yubikey
wget -O /usr/bin/clevis-decrypt-yubikey https://github.com/anatol/clevis-extra-pins/raw/refs/heads/main/clevis-decrypt-yubikey
chmod +x /usr/bin/clevis-encrypt-yubikey /usr/bin/clevis-decrypt-yubikey
I then tried to encrypt some data:
clevis encrypt yubikey '{"slot":"2"}' <<< 'hello, world'
But quickly noticed something: I forgot to configure the second slot:
ykpersonalize -2 -ochal-resp -ochal-hmac -ohmal-lt64
Then I ran into another problem:
The sha3-256sum command does not exist on Void Linux, so I replaced it with the normal sha256sum:
sed -i 's/sha3-256sum -x/sha256sum/g' /usr/bin/clevis-encrypt-yubikey
sed -i 's/sha3-256sum -x/sha256sum/g' /usr/bin/clevis-decrypt-yubikey
Now I was able to encrypt data using my YubiKey and Clevis. Yay! So I bound my YubiKey to my LUKS drive:
clevis luks bind -d /dev/sdX yubikey '{"slot":"2"}'
But there was just one problem: the initramfs.
Dracut
Dracut is Void Linux’s default initramfs. It runs early userspace tasks like mounting the root filesystem. I wanted Dracut to decrypt my drive using Clevis.
Thankfully, there already was a Clevis hook for Dracut, so I just had to make one for the YubiKey pin.
I wrote the following to /usr/lib/dracut/modules.d/60clevis-pin-yubikey/module-setup.sh:
#!/bin/bash
depends() {
echo clevis
return 0
}
install() {
inst_multiple ykchalresp xxd sha256sum jose
inst_libdir_file libusb-1.0.so.0
inst clevis-decrypt-yubikey
}
After that, I reconfigured the initramfs and rebooted:
xbps-reconfigure -xf linux
Now it finally worked! I was able to decrypt my drive using my YubiKey.