zfsbootmenu/void-install.md

7.3 KiB

Void full disk encryption install process

Download the latest hrmpf, write it to USB drive and boot your system in EFI mode. You can confirm you've booted in EFI mode by running efibootmgr.

For this guide, the following assumptions are made:

  • /dev/sda is the drive dedicated for the ZFS pool
  • /dev/sdb is the USB drive dedicated for the EFI partition
  • You're mildly comfortable with ZFS, EFI and discovering system facts on your own (lsblk, dmesg, gdisk, ...)

ZFS prep work

  • Build and load ZFS modules
xbps-reconfigure -a
modprobe zfs
  • Generate /etc/hostid
zgenhostid
  • Store your pool passphrase in a key file
echo "SomeKeyphrase" > /etc/zfs/zroot.key
chmod 000 /etc/zfs/zroot.key

ZFS pool creation

  • Create the 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/sda

It's out of the scope of this guide to cover all of the pool creation options used - feel free to tailor them to suit your system. However, the following options need to be addressed:

  • encryption=aes-256-gcm - You can adjust the algorithm as you see fit, but this will likely be the most performant on modern x86_64 hardware.

  • keylocation=file:///etc/zfs/zroot.key - This sets our pool encryption passphrase to the file /etc/zfs/zroot.key, which we created in a previous step. This file will live inside your initramfs stored ON the ZFS boot environment.

  • keyformat=passphrase - By setting the format to passphrase, we can now force a prompt for this in zfsbootmenu. It's critical that your passphrase be something you can type on your keyboard, since you will need to type it in to unlock the pool on boot.

  • Create our initial file systems

zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ zroot/ROOT/void.$( date +%Y.%m.%d )
zfs create -o mountpoint=/home zroot/home
  • Export, then reimport with a temporary mountpoint of /mnt
zpool export zroot
zpool import -l -R /mnt zroot
  • Verify that everything is mounted correctly
# mount | grep mnt
zroot/ROOT/void.2020.01.30 on /mnt type zfs (rw,relatime,xattr,posixacl)
zroot/home on /mnt/home type zfs (rw,relatime,xattr,posixacl)

Install Void

  • Adjust the mirror / libc / package selection as you see fit
xbps-install -S -R https://mirrors.servercentral.com/voidlinux/current -r /mnt base-system zfs vim efibootmgr gptfdisk
  • Copy our pool key, hostid and resolv.conf into the new install
cp /etc/hostid /mnt/etc
cp /etc/resolv.conf /mnt/etc/
cp /etc/zfs/zroot.key /mnt/etc/zfs
  • Chroot into the new OS
mount -t proc proc /mnt/proc
mount -t sysfs sys /mnt/sys
mount -B /dev /mnt/dev
mount -t devpts pts /mnt/dev/pts
chroot /mnt

Basic Void configuration

  • Set the keymap, timezone and hardware clock
cat << EOF >> /etc/rc.conf
KEYMAP="us"
TIMEZONE="America/Chicago"
HARDWARECLOCK="UTC"
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

  • To more quickly discover and import pools on boot, we need to set a pool cachefile
zpool set cachefile=/etc/zfs/zpool.cache zroot
  • Configure our default boot environment
zpool set bootfs=zroot/ROOT/void.$( date +%Y.%m.%d ) zroot
  • Configure Dracut to load ZFS support
cat << EOF > /etc/dracut.conf.d/zol.conf
nofsck="yes"
add_dracutmodules+=" zfs "
omit_dracutmodules+=" btrfs "
install_items+=" /etc/zfs/zroot.key "
EOF
  • Rebuild the initramfs
xbps-reconfigure -f linux5.4

Install and configure ZFSBootMenu

  • 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="spl_hostid=$( hostid ) ro quiet" zroot/ROOT
  • Create an EFI partition on /dev/sdb
bash-5.0# gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.4

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): o
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): y

Command (? for help): p
Disk /dev/sdb: 62656641 sectors, 29.9 GiB
Model: Flash Drive FIT 
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 0803CB07-D712-4839-BA5D-FB52EF4E88BB
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 62656607
Partitions will be aligned on 2048-sector boundaries
Total free space is 62656574 sectors (29.9 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name

Command (? for help): n
Partition number (1-128, default 1): 1
First sector (34-62656607, default = 2048) or {+-}size{KMGTP}: 
Last sector (2048-62656607, default = 62656607) or {+-}size{KMGTP}: +512M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): EF00
Changed type of partition to 'EFI System'

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.
  • Create a vfat filesystem
mkfs.vfat -F32 /dev/sdb1
  • Create an fstab entry and mount
cat << EOF >> /etc/fstab
$( blkid | grep /dev/sdb1 | cut -d ' ' -f 2 ) /boot/efi vfat defaults,noauto 0 0
EOF
mkdir /boot/efi
mount /boot/efi
  • Install rEFInd

This should find /boot/efi as your EFI partition and install itself accordingly.

xbps-install -S
xbps-install -Rs refind
refind-install
rm /boot/refind_linux.conf
  • Install the bootmenu package
xbps-install -Rs zfsbootmenu
  • Enable zfsbootmenu image creation Edit /etc/zfsbootmenu/config.ini and set:
  • ManageImages=1 under [Global] section
  • Copies=3 under [Components] section
  • See Configuration options for more details.
[Global]
ManageImages=1
DracutConfDir=/etc/zfsbootmenu/dracut.conf.d
BootMountPoint=/boot/efi

[Kernel]
CommandLine=ro quiet loglevel=0

[Components]
ImageDir=/boot/efi/EFI/void
Versioned=1
Copies=3

[EFI]
ImageDir=/boot/efi/EFI/void
Versioned=1
Copies=0

[syslinux]
CreateConfig=0
Config=/boot/efi/syslinux/syslinux.cfg
  • Generate the initial bootmenu initramfs
xbps-reconfigure -f zfsbootmenu
zfsbootmenu: configuring ...
Creating ZFS Boot Menu 0.8.1_1, with vmlinuz 5.4.15_1
Found 0 existing images, allowed to have a total of 3
Created /boot/efi/EFI/void/vmlinuz-0.8.1_1, /boot/efi/EFI/void/initramfs-0.8.1_1.img
  • Create /boot/efi/EFI/void/refind_linux.conf
cat << EOF > /boot/efi/EFI/void/refind_linux.conf
"Boot default"  "zfsbootmenu:ROOT=zroot spl_hostid=$( hostid ) timeout=0 ro quiet loglevel=0"
"Boot to menu"  "zfsbootmenu:ROOT=zroot spl_hostid=$( hostid ) timeout=-1 ro quiet loglevel=0"
EOF
  • Exit the chroot, unmount everything
exit
umount -n /mnt/{dev/pts,dev,sys,proc}
umount /mnt/boot/efi
  • Export the zpool and reboot
zpool export zroot
reboot