Introduction

Hello everyone,

I recently bought a new laptop. While unboxing it, two things came to mind:

  1. I should try out a new distro—NixOS is slowly pissing me off.
  2. 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.