Image from Wikimedia Commons.

In this tutorial, we will create an Arch Linux installation whose root partition is encrypted with YubiKey HMAC-SHA1 challenge-response module. The final result looks like this:

  • You will be asked to have a correct YubiKey inserted into a USB port and enter the password to unlock the root partition at boot time (2FA), or
  • A correct YubiKey must be present in a USB port at boot time in order to unlock the root partition, no password needed (1FA).

The core component we are using, YubiKey Full Disk Encryption, is basically some bash scripts that concatenate the challenge (hashed password) and the response as the encryption key of our root partition.

Prerequisites

  • A computer with
    • x86-64 CPU
    • Ethernet connection with Arch Linux Repository access
    • USB ports
    • An SSD or HDD for boot and root partitions
    • A BIOS with UEFI support
  • A YubiKey with HMAC-SHA1 challenge response support. Ideally two of them for backup.
  • A USB stick with Arch Linux Installation Live-CD

Configure HMAC-SHA1 Challenge-Response slot in YubiKey

Install and launch YubiKey Personalization Tools, click Challenge-Response -> HMAC-SHA1, insert your YubiKey, select an available slot, generate a secret key and write the configuration to your YubiKey. You can check "Program Multiple YubiKeys" and select "Same Secret for all Keys" to make a backup with another YubiKey. You can also check "Require user input (button press)" for additional cumber security.

YubiKey Personalization Tools. You can use the same slot to secure your KeePassXC password database.

Create an Encrypted Root Partition

After booting from the Live-CD (UEFI mode) and entered the root shell, bring your favorite Arch Linux Repository to the first line of /etc/pacman.d/mirrorlist:

# vim /etc/pacman.d/mirrorlist

My favorite mirror is from TUNA, so my keystrokes after launching vim is:

/tuna<enter>ddggPZZ

Update the package database and install some packages:

# pacman -Sy
# pacman -S make git yubikey-personalization cryptsetup udisks2 expect

Clone the yubikey-full-disk-encryption repository and install:

# git clone https://github.com/agherzan/yubikey-full-disk-encryption.git
# cd yubikey-full-disk-encryption
# make install

Assuming your target disk is /dev/sda, edit the disk interactively with fdisk:

# fdisk /dev/sda

Create A GPT partition table on your disk (DATA LOST WARNING!) with g and two partitions with n:

  • /dev/sda1: Boot partition with a size of 512MB by setting the last sector to +512M, the partition type must be EFI System. Use t to change partition type, select partition 1, then select partition type 1.
  • /dev/sda2: Root partition occupying remaining disk space, the partition type is Linux File System

Type w to write the changes to the disk and quit.

Get the UUID of /dev/sda2:

# partprobe
# ls -l /dev/disk/by-uuid/ | grep sda2

Edit /etc/ykfde.conf. For example, if 2 factor authentication:

### Configuration for 'yubikey-full-disk-encryption'.
### Remove hash (#) symbol and set non-empty ("") value for chosen options to
### enable them.

### *REQUIRED* ###

# Set to non-empty value to use 'Automatic mode with stored challenge (1FA)'.
YKFDE_CHALLENGE="some_password_you_like"

# Use 'Manual mode with secret challenge (2FA)'.
YKFDE_CHALLENGE_PASSWORD_NEEDED="1"

# YubiKey slot configured for 'HMAC-SHA1 Challenge-Response' mode.
# Possible values are "1" or "2". Defaults to "2".
YKFDE_CHALLENGE_SLOT="2"

### OPTIONAL ###

# UUID of device to unlock with 'cryptsetup'.
# Leave empty to use 'cryptdevice' boot parameter.
YKFDE_DISK_UUID="UUID_of_/dev/sda2"

# LUKS encrypted volume name after unlocking.
# Leave empty to use 'cryptdevice' boot parameter.
YKFDE_LUKS_NAME="root"

Insert your YubiKey, encrypt the root partition with ykfde-format:

# ykfde-format --cipher aes-xts-plain64 --key-size 512 --hash sha512 /dev/sda2

Unlock the encrypted partition with ykfde-open:

# ykfde-open -d /dev/sda2 -n root

Now the decrypted partition is at /dev/mapper/root.

Format the boot partition as FAT32 and the root partition as ext4:

# mkfs.fat -F32 /dev/sda1
# mkfs.ext4 /dev/mapper/root

Mount the partitions in your target disk:

# mount /dev/mapper/root /mnt
# mkdir /mnt/boot
# mount /dev/sda1 /mnt/boot

Check other pre-installation steps you might want to do at ArchWiki.

Install and Configure Arch Linux

Install the base package group to your disk:

# pacstrap /mnt base

Generate the /etc/fstab:

# genfstab -U /mnt >> /mnt/etc/fstab

Copy the ykfde.conf for later use:

# cp /etc/ykfde.conf /mnt/

Change root into the new system:

# arch-chroot /mnt

Set time zone, localization and hostname according to ArchWiki.

Now repeat the YubiKey Full Disk Encryption installation process on your disk:

# pacman -S make git yubikey-personalization cryptsetup udisks2 expect
# cd /root
# git clone https://github.com/agherzan/yubikey-full-disk-encryption.git
# cd yubikey-full-disk-encryption
# make install

Cover the default ykfde.conf with your own:

# mv /ykfde.conf /etc/

Add the ykfde hook to your /etc/mkinitcpio.conf. The line should look like this:

HOOKS=(base udev autodetect modconf block ykfde filesystems keyboard fsck)

Generate initramfs again:

# mkinitcpio -P

Set a root password for later login. It is advised to prevent any remote login as root after post-installation steps.

# passwd

You may want to install Intel Microcode update if you are using an Intel CPU:

# pacman -S intel-ucode

We are using systemd-boot bootloader here. Install the bootloader to your boot partition:

# bootctl --path=/boot install

Create a loader entry /boot/loader/entries/arch.conf of your Arch Linux installation:

title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img # only if you are using an Intel CPU
initrd /initramfs-linux.img
options root=/dev/mapper/root

Edit /boot/loader/loader.conf so that it looks like this:

default arch
timeout 4
console-mode max
editor no

Now leave the chroot environment, unmount all media and reboot:

# exit
# umount -R /mnt
# reboot

Ensure that you are booting from the target hard disk, not your Live-CD USB stick. You should be able to unlock the root partition with YubiKey at the initramfs stage of the boot process. After login, conduct necessary post-installation steps described in ArchWiki. Since we didn't use a swap partition due to security consideration, you can use a swap file.

References

agherzan/yubikey-full-disk-encryption: Use YubiKey to unlock a LUKS partition

Installation guide - ArchWiki

EFI system partition - ArchWiki

dm-crypt/System configuration - ArchWiki