Skip to content

Instantly share code, notes, and snippets.

@tobi-wan-kenobi
Last active April 17, 2024 06:57
Show Gist options
  • Save tobi-wan-kenobi/bff3af81eac27e210e1dc88ba660596e to your computer and use it in GitHub Desktop.
Save tobi-wan-kenobi/bff3af81eac27e210e1dc88ba660596e to your computer and use it in GitHub Desktop.
Void Linux installation (NVMe, btrfs, LVM, full disk encryption using LUKS, 2FA-ish, SSD TRIM)

Void Linux installation (NVMe, btrfs, LVM, full disk encryption using LUKS, 2FA-ish, SSD TRIM)

Here's a record of my experiences when setting up Void Linux for the first time, maybe it contains useful information for somebody :-)

Basics

  • Laptop: Lenovo IdeaPad S340
  • Void Linux installer version: 20191109 (x86_64 musl)

Features

This guide explains how to set up Void Linux:

  • On an NVMe disk
  • Using full disk encryption - including /boot, with LUKS + LVM
  • Uses btrfs as filesystem
  • Offers a poor-man's 2FA using Yubikey's static password feature

Important notes

  • SSD/NVMe trimming only works if it is enabled on all intermediate layers, which in this case means LUKS, LVM and btrfs
  • What I call "2FA" is not really 2FA, but rather a simplistic way to get "something you know" (a passphrase) and "something you have" (a Yubikey token, in my case). Yubikey has a feature to emit a static password upon pressing a button on the token. This is modeled as a USB keyboard, so it supports a wide range of hardware. The approach is to make the LUKS passphrase composed of two pieces: First, a password you have to remember, followed directly by the passphrase generated by the token.

The process

Pre-chroot

# boot Void live system and log in using root:voidlinux

loadkeys de

cp /etc/wpa_supplicant/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant-<interface>.conf
wpa_passphrase <SSID> <password> >> /etc/wpa_supplicant/wpa_supplicant-<interface>.conf
wpa_supplicant -B -i <interface> -c /etc/wpa_supplicant/wpa_supplicant-<interface>.conf

fdisk /dev/nvme0n1
# g to create a new GTP partition ta
# n new partition with +200M
# t 1 to set partition type to EFI
# n new partition with remaining space

# set up encryption
# here's the 2FA "trick":
# prepare a YubiKey that emits a *static* passphrase
# when pressing its touch button (best use the maximum
# passphrase length offered - 64 characters at the time
# of writing).
# when asked for the passphrase, *first* enter a
# password you need to *know*, then press the button
# on the Yubikey - voila, you have a passphrase requiring
# something you know and something to have
# not sufficient for government-grade security, maybe, but
# for my humble home laptop, it's OK
cryptsetup luksFormat --type=luks1 /dev/nvme0n1p2
cryptsetup open /dev/nvme0n1p2 crypt

# prepare LVM
vgcreate vg0 /dev/mapper/crypt
lvcreate --name swap -L 25G vg0
lvcreate --name void -l +100%FREE vg0

# filesystems
mkfs.vfat -n BOOT -F 32 /dev/nvme0n1p1
mkswap /dev/mapper/vg0-swap
mkfs.btrfs -L void /dev/mapper/vg0-void

mount -o rw,noatime,ssd,compress=lzo,space_cache,commit=60 /dev/mapper/vg0-void /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@snapshots
umount /mnt
mount -o rw,noatime,ssd,compress=lzo,space_cache,commit=60,subvol=@ /dev/mapper/vg0-void /mnt
mkdir /mnt/home
mkdir /mnt/.snapshots
mount -o rw,noatime,ssd,compress=lzo,space_cache,commit=60,subvol=@home /dev/mapper/vg0-void /mnt/home/
mount -o rw,noatime,ssd,compress=lzo,space_cache,commit=60,subvol=@snapshots /dev/mapper/vg0-void /mnt/.snapshots/
mkdir -p /mnt/boot/efi
mount -o rw,noatime /dev/nvme0n1p1 /mnt/boot/efi/
mkdir -p /mnt/var/cache
btrfs subvolume create /mnt/var/cache/xbps
btrfs subvolume create /mnt/var/tmp
btrfs subvolume create /mnt/srv
export XBPS_ARCH=x86_64-musl
xbps-install -Sy -R https://alpha.de.repo.voidlinux.org/current/musl -r /mnt base-system btrfs-progs cryptsetup grub-x86_64-efi lvm2
mount -t proc proc /mnt/proc/
mount -t sysfs sys /mnt/sys/
mount -o bind /dev /mnt/dev
mount -t devpts pts /mnt/dev/pts
cp -L /etc/resolv.conf /mnt/etc/
cp -L /etc/wpa_supplicant/wpa_supplicant-<interface>.conf /mnt/etc/wpa_supplicant/
chroot /mnt /bin/bash

Post-chroot

passwd root
chown root:root /
chmod 755 /
echo <hostname> > /etc/hostname
cat <<EOF > /etc/rc.rc.conf
# /etc/rc.conf - system configuration for void

HOSTNAME="<hostname>"
HARDWARECLOCK="UTC"
TIMEZONE="Europe/Amsterdam"
KEYMAP="de"
EOF
echo 'en_US.UTF-8 UTF-8' > /etc/default/libc-locales
echo LANG=en_US.UTF-8 > /etc/locale.conf
export UEFI_UUID=$(blkid -s UUID -o value /dev/nvme0n1p1)
export LUKS_UUID=$(blkid -s UUID -o value /dev/nvme0n1p2)
export ROOT_UUID=$(blkid -s UUID -o value /dev/mapper/vg0-void)
export SWAP_UUID=$(blkid -s UUID -o value /dev/mapper/vg0-swap)
cat <<EOF > /etc/fstab
UUID=$ROOT_UUID / btrfs rw,noatime,ssd,compress=lzo,space_cache,commit=60,subvol=@ 0 1
UUID=$ROOT_UUID /home btrfs rw,noatime,ssd,compress=lzo,space_cache,commit=60,subvol=@home 0 2
UUID=$ROOT_UUID /.snapshots btrfs rw,noatime,ssd,compress=lzo,space_cache,commit=60,subvol=@snapshots 0 2
UUID=$UEFI_UUID /boot/efi vfat defaults,noatime 0 2
UUID=$SWAP_UUID none swap defaults 0 1
tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0
EOF
cat <<EOF >> /etc/default/grub
GRUB_ENABLE_CRYPTODISK=y
EOF
sed -i "/GRUB_CMDLINE_LINUX_DEFAULT=/s/\"$/ rd.auto=1 cryptdevice=UUID=$LUKS_UUID:lvm:allow-discards&/" /etc/default/grub
dd bs=512 count=4 if=/dev/urandom of=/boot/volume.key
cryptsetup luksAddKey /dev/nvme0n1p2 /boot/volume.key
chmod 000 /boot/volume.key
chmod -R g-rwx,o-rwx /boot
cat <<EOF >> /etc/crypttab
crypt /dev/nvme0n1p2 /boot/volume.key luks
EOF
cat <<EOF >> /etc/dracut.conf.d/10-crypt.conf
install_items+=" /boot/volume.key /etc/crypttab "
EOF
echo 'add_dracutmodules+=" crypt btrfs lvm resume "' >> /etc/dracut.conf
echo 'tmpdir=/tmp' >> /etc/dracut.conf
dracut --force --hostonly --kver 5.4.26_1
mkdir /boot/grub
grub-mkconfig -o /boot/grub/grub.cfg
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=void --boot-directory=/boot  --recheck
ln -s /etc/sv/dhcpcd /etc/runit/runsvdir/default
ln -s /etc/sv/wpa_supplicant/ /etc/runit/runsvdir/default
sed -i 's/issue_discards = 0/issue_discards = 1/' /etc/lvm/lvm.conf

References

As per "standing on the shoulders of giants", most of the information in this guide was no discovered by myself, but rather assembled from various existing guides, which I want to list here to give credit where credit is due:

[1] https://gist.github.com/gbrlsnchs/9c9dc55cd0beb26e141ee3ea59f26e21

[2] https://wiki.voidlinux.org/Full_Disk_Encryption_w/Encrypted_Boot

[3] https://gist.github.com/mattiaslundberg/8620837

[4] http://blog.neutrino.es/2013/howto-properly-activate-trim-for-your-ssd-on-linux-fstrim-lvm-and-dmcrypt/

@tobi-wan-kenobi
Copy link
Author

@boki1 @StellarOrbit Sorry, that comment somehow slipped me by.

I seem to remember that for some reason, it worked like that for me, but I will gladly update the configuration :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment