From 6514891c644c81dcf0e19bfaf73988dbaa030c7e Mon Sep 17 00:00:00 2001 From: Justine Smithies Date: Wed, 3 Jan 2024 17:41:58 +0000 Subject: Installing Void Linux with encrypted Root on ZFS --- void-linux-with-encrypted-root-on-zfs.md | 286 +++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 void-linux-with-encrypted-root-on-zfs.md diff --git a/void-linux-with-encrypted-root-on-zfs.md b/void-linux-with-encrypted-root-on-zfs.md new file mode 100644 index 0000000..763916a --- /dev/null +++ b/void-linux-with-encrypted-root-on-zfs.md @@ -0,0 +1,286 @@ +# Installing Void Linux with encrypted Root on ZFS +#### This guide is how I install Void Linux onto a single disk with with encrypted Root on ZFS and a seperate encrypted swap partition. + +It assumes the following: + +Your system uses UEFI to boot + +Your system is x86_64 + +You will use glibc as your system libc. + +You're mildly comfortable with ZFS, EFI and discovering system facts on your own (lsblk, dmesg, gdisk, ...) + +ZFSBootMenu does not require glibc and is not restricted to x86_64. If you are comfortable installing Void Linux on other architectures or with the musl libc, you can adapt the instructions here to your desired configuration. + +### Please note that I have used information from the sources listed below: + +> ZFS BootMenu Docs +https://docs.zfsbootmenu.org/en/v2.3.x/guides/void-linux/uefi.html + +> Void Linux ZFS Docs +https://docs.voidlinux.org/installation/guides/zfs.html + +> Chain's computar projects +https://forum.level1techs.com/t/chains-computar-projects/190001 + +> Daniel Wayne Armstrong Blog +https://www.dwarmstrong.org/encrypt-swap/ +# To start +Download the latest hrmpf image from: +> https://github.com/leahneukirchen/hrmpf + +Write it to USB drive and boot your system in EFI mode. + +Confirm EFI support: + +``` +# dmesg | grep -i efivars +[ 0.301784] Registered efivars operations +``` + +# Configure Live Environment +## Source /etc/os-release +The file /etc/os-release defines variables that describe the running distribution. In particular, the $ID variable defined within can be used as a short name for the filesystem that will hold this installation. + +``` +source /etc/os-release +export ID +``` + +## Generate /etc/hostid + +``` +zgenhostid -f 0x00bab10c +``` + +# Disk preparation + +Verify your target disk devices with lsblk. `/dev/sda`, `/dev/sdb` and `/dev/nvme0n1`. +
+On my laptop I,ll be using a single drive on `/dev/nvme0n1` with three paritions as follows: + +**1 - EFI boot** +**2 - Swap** ( I'm using 64Gb but you can adjust to suit your needs or just not create swap and number the zpool parition 2 ) +**3 - Zpool** ( This partition uses the remaining disk space ) + +**Note you will need to adjust below when wiping partitions if you use seperate disks** +## Wipe partitions + +``` +zpool labelclear -f "/dev/nvme0n1" + +wipefs -a "/dev/nvme0n1" + +sgdisk --zap-all "/dev/nvme0n1" +``` + +## Create EFI boot partition +``` +sgdisk -n "1:1m:+512m" -t "1:ef00" "/dev/nvme0n1" +``` + +## Create swap partition +``` +sgdisk -n "2::64Gb" -t "2:8200" "/dev/nvme0n1" -c "2:cryptswap" "/dev/nvme0n1" +``` + +## Create zpool partition +``` +sgdisk -n "3:0:-10m" -t "3:bf00" "/dev/nvme0n1" +``` + +# ZFS pool creation +## Store the pool passphrase in a key file +``` +echo 'SomeKeyphrase' > /etc/zfs/zroot.key +chmod 000 /etc/zfs/zroot.key +``` +## Create the encrypted zpool +``` +zpool create -f -o ashift=12 \ + -O compression=lz4 \ + -O acltype=posixacl \ + -O xattr=sa \ + -O relatime=on \ + -O encryption=aes-256-gcm \ + -O keylocation=file:///etc/zfs/zroot.key \ + -O keyformat=passphrase \ + -o autotrim=on \ + -m none zroot "/dev/disk/by-id/wwn-0x5000c500deadbeef-part3" + ``` + Adjust the pool (-o) and filesystem (-O) options as desired, and replace the partition identifier `wwn-0x5000c500deadbeef-part3` with that of the actual partition to be used. +You can find this out by typing `ls /dev/disk/by-id/` and they will be listed in the output. + +When adding disks or partitions to ZFS pools, it is generally advisable to refer to them by the symbolic links created in /dev/disk/by-id or (on UEFI systems) /dev/disk/by-partuuid so that ZFS will identify the right partitions even if disk naming should change at some point. Using traditional device nodes like /dev/sda3 may cause intermittent import failures. +## Create initial file systems +``` +zfs create -o mountpoint=none zroot/ROOT +zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/${ID} +zfs create -o mountpoint=/home zroot/home + +zpool set bootfs=zroot/ROOT/${ID} zroot +``` +> **Note** +It is important to set the property `canmount=noauto` on any file systems with `mountpoint=/` (that is, on any additional boot environments you create). Without this property, the OS will attempt to automount all ZFS file systems and fail when multiple file systems attempt to mount at `/`; this will prevent your system from booting. Automatic mounting of `/` is not required because the root file system is explicitly mounted in the boot process. +Also note that, unlike many ZFS properties, `canmount` is not inheritable. Therefore, setting `canmount=noauto` on `zroot/ROOT` is not sufficient, as any subsequent boot environments you create will default to `canmount=on`. It is necessary to explicitly set the `canmount=noauto` on every boot environment you create. + +## Export, then re-import with a temporary mountpoint of `/mnt` +``` +zpool export zroot +zpool import -N -R /mnt zroot +zfs load-key -L prompt zroot +``` +``` +zfs mount zroot/ROOT/${ID} +zfs mount zroot/home +``` +## Verify that everything is mounted correctly +``` +# mount | grep mnt +zroot/ROOT/void on /mnt type zfs (rw,relatime,xattr,posixacl) +zroot/home on /mnt/home type zfs (rw,relatime,xattr,posixacl) +``` +## Update device symlinks +``` +udevadm trigger +``` +## Install Void +Adjust the mirror, libc, and package selection as you see fit. +``` +XBPS_ARCH=x86_64 xbps-install \ + -S -R https://mirrors.servercentral.com/voidlinux/current \ + -r /mnt base-system +``` +## Copy our files into the new install +``` +cp /etc/hostid /mnt/etc +mkdir /mnt/etc/zfs +cp /etc/zfs/zroot.key /mnt/etc/zfs +``` +## Chroot into the new OS +``` +xchroot /mnt +``` +## Basic Void configuration +### Set the keymap, timezone and hardware clock +``` +cat << EOF >> /etc/rc.conf +KEYMAP="us" +HARDWARECLOCK="UTC" +TIMEZONE="Europe/London" +EOF +``` +## Configure your glibc locale +``` +cat << EOF >> /etc/default/libc-locales +en_US.UTF-8 UTF-8 +en_US ISO-8859-1 +EOF +xbps-reconfigure -f glibc-locales +``` +## Set a root password +``` +passwd +``` +# ZFS Configuration +## Configure Dracut to load ZFS support +``` +cat << EOF > /etc/dracut.conf.d/zol.conf +nofsck="yes" +add_dracutmodules+=" zfs " +omit_dracutmodules+=" btrfs resume " +install_items+=" /etc/zfs/zroot.key " +EOF +``` +## Install ZFS and Cryptsetup +``` +xbps-install -S zfs cryptsetup +``` +## To quickly discover and import pools on boot, we need to set a pool cachefile +``` +zpool set cachefile=/etc/zfs/zpool.cache zroot +``` +# Install and configure ZFSBootMenu +## Set ZFSBootMenu properties on datasets +Assign command-line arguments to be used when booting the final kernel. Because ZFS properties are inherited, assign the common properties to the ROOT dataset so all children will inherit common arguments by default. +``` +zfs set org.zfsbootmenu:commandline="quiet loglevel=4" zroot/ROOT +``` +Setup key caching in ZFSBootMenu. +``` +zfs set org.zfsbootmenu:keysource="zroot/ROOT/${ID}" zroot +``` +## Create `vfat` and encrypted `swap` filesystems +``` +mkfs.vfat -F32 /dev/nvme0n1p1 +``` +``` +cat << EOF >> /etc/crypttab +cryptswap /dev/disk/by-partlabel/cryptswap /dev/urandom swap,offset=2048,cipher=aes-xts-plain64,size=512 +EOF +``` +# Create fstab entries and mount the efi partition +``` +cat << EOF >> /etc/fstab +$( blkid | grep /dev/nvme0n1p1 | cut -d ' ' -f 2 ) /boot/efi vfat defaults 0 0 +/dev/mapper/cryptswap none swap defaults 0 0 +EOF +mkdir -p /boot/efi +mount /boot/efi +``` +## Install ZFSBootMenu +``` +xbps-install -S zfsbootmenu gummiboot-efistub +``` +Configure generate-zbm(5) by ensuring that the following keys appear in /etc/zfsbootmenu/config.yaml: +``` +Global: + ManageImages: true + BootMountPoint: /boot/efi +Components: + Enabled: false +EFI: + ImageDir: /boot/efi/EFI/zbm + Versions: false + Enabled: true +Kernel: + CommandLine: quiet loglevel=0 +``` + +My `CommandLine:` will be as follows as I don't want ZFSBootMenu automatically resizing the fonts according to the display size. +``` +CommandLine: quiet loglevel=0 zbm.skip_hooks=20-console-autosize.sh +``` +## Create a ZFSBootMenu image: +``` +generate-zbm +``` +## Configure EFI boot entries +``` +xbps-install efibootmgr +``` +``` +efibootmgr -c -d "/dev/nvme0n1" -p "1" \ + -L "ZFSBootMenu (Backup)" \ + -l '\EFI\ZBM\VMLINUZ-BACKUP.EFI' + +efibootmgr -c -d "/dev/nvme0n1" -p "1" \ + -L "ZFSBootMenu" \ + -l '\EFI\ZBM\VMLINUZ.EFI' +``` +# Prepare for first boot +## Exit the chroot, unmount everything +``` +exit +``` +``` +umount -n -R /mnt +``` +## Export the zpool and reboot +``` +zpool export zroot +``` +``` +reboot +``` -- cgit v1.2.3