## Intro
For the full primer please read [Here](primerspiel.html).
This is a document outlining my modifications to the parent doc directly from ZFSbootmenu for installing a Debian Bookworm on ZFS root partition found [Here](https://docs.zfsbootmenu.org/en/v2.2.x/guides/debian/bookworm-uefi.html)
The modifications I have made are choosing to boot first from a USB drive, and setting up some symlink magic to lay the groundwork for eventually using the USB to also decrypt the root partition. Once I have that working I will update this document.
So with out further ado
What Works?
- Pretty much everything.
What Doesnt?
- auto-unlock with external keyfile. I'm actively working on this.
---
## Hardware
I'm using a Razer Blade 2023, yes I know I agree. But I'm an aesthetics and composition girly and their hardware for their laptops is CLEAN. So that said: moving on.
## Software
- Windows 11
- https://support.microsoft.com/en-us/windows/create-installation-media-for-windows-99a58364-8c02-206f-aa6f-40c3b507420d
- Debian Bookworm Live
- https://www.debian.org/CD/live/
- ZFSbootmenu
- https://docs.zfsbootmenu.org/en/v2.2.x/guides/debian/bookworm-uefi.html#zfs-pool-creation
- AND assuming you do not have access to a CLI to `dd` an image, RUFUS
- https://rufus.ie/en/
---
My modified method derived from the aforementioned ZFSbootmenu doc are as follows.
## Before Starting
#### Windows
Boot into Windows, launch disk management and defrag your C:\ . Then attempt to decrease its size as much as possible. Note it's size to identify it later. Take a backup if you're wise, or don't if you live on the edge.
Create your Debian Live CD, and in case you bork something, your Windows 11 Media
#### Bios
Disable secure boot in the bios. I know. I'm Sorry.
---
## Configure Live Environment
### Switch to a root shell
```bash
sudo -i
```
Confirm EFI support:
```bash
# **dmesg | grep -i efivars**
[ 0.301784] Registered efivars operations
```
### Export ID
```bash
source /etc/os-release
export ID
```
This will be used to name a dataset later on your root zpool.
### Configure and update APT
```bash
cat < /etc/apt/sources.list
deb http://deb.debian.org/debian bookworm main contrib
deb-src http://deb.debian.org/debian bookworm main contrib
EOF
apt update
```
### Install Helpers
```bash
apt install debootstrap gdisk dkms linux-headers-$(uname -r)
apt install zfsutils-linux
```
### Generate Host ID
```bash
zgenhostid -f 0x00bab10c
```
---
## Disk Preparation
### Install gparted
```bash
apt install gparted
```
### Separate Boot Drive
#### Define Boot Drive Variables
We want to do this so we don't make mistakes. Here we're combining 2 parts of the docs, that they assume are not used at the same time.
note: I will not include real names here so you cannot accidentally bork your system by copy pasting something not tailored to your system.
```bash
export BOOT_DISK="/dev/"
export BOOT_PART=""
export BOOT_DEVICE="${BOOT_DISK}${BOOT_PART}"
```
#### Format Disk
```bash
wipefs -a "$BOOT_DISK"
sgdisk --zap-all "$BOOT_DISK"
sgdisk -n "${BOOT_PART}:1m:+512m" -t "${BOOT_PART}:ef00" "$BOOT_DISK"
sgdisk -n "${BOOT_PART}:1m:+512m" -t "${BOOT_PART}:ef00" "$BOOT_DISK"
```
### KeyDrive
We would also like the decryption keyfile to be placedon the removable drive for security reasons.
Use gparted to create a partition of type 'unformatted' on the boot key.
note its partition number and run the following
```bash
zpool create -f -o ashift=12 \
-O compression=lz4 \
-O acltype=posixacl \
-O xattr=sa \
-O relatime=on \
-O encryption=aes-256-gcm \
-o autotrim=on \
-o compatibility=openzfs-2.1-linux \
-m none zdrive
```
Now tell it to mount where we want our key to be located.
```bash
zfs set mountpoint=/etc/zfs zdrive
```
### Root Partition on NVME drive
Take note of which partition your C:\ holds.
```bash
#lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 1 57.8G 0 disk
├─sda1 8:1 1 512M 0 part /boot/efi
├─sda2 8:2 1 31.4G 0 part
└─sda3 8:3 1 25.9G 0 part
nvme0n1 259:0 0 1.9T 0 disk
├─nvme0n1p1 259:1 0 512.2G 0 part
├─nvme0n1p2 259:2 0 100M 0 part
├─nvme0n1p3 259:3 0 16M 0 part
├─nvme0n1p4 259:4 0 1.3T 0 part
└─nvme0n1p5 259:5 0 1000M 0 part
```
for me it's `/dev/nvme0n1p4`. Do Not Touch It.
I cheat here. To ensure my placement is correct with the dual boot I opt not to use `CLI` here and instead use gparted. you will want to (again) try downsizing your C:\ partition if you weren't able to create enough space before. and create a new partition where you need it of type 'unformatted'
somehow this became `/dev/nvme0n1p1` for me
### Define Variables
```bash
export POOL_DISK="/dev/"
export POOL_PART=""
export POOL_DEVICE="${POOL_DISK}p${POOL_PART}"
```
---
## Create zpool
We wanna use ZFS's native encryption (because it's neat) so do as follows to create a key
```bash
echo 'SomeKeyphrase' > /etc/zfs/zroot.key
chmod 000 /etc/zfs/zroot.key
```
then create the pool
```bash
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 \
-o compatibility=openzfs-2.1-linux \
-m none zroot "$POOL_DEVICE"
```
### Create initial file systems
```bash
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
```
### Export, then re-import with a temporary mountpoint of `/mnt`
```bash
zpool export zroot
zpool import -N -R /mnt zroot
zfs load-key -L prompt zroot
```
```bash
zfs mount zroot/ROOT/${ID}
zfs mount zroot/home
```
### Verify that everything is mounted correctly
```bash
mount | grep mnt
zroot/ROOT/debian on /mnt type zfs (rw,relatime,xattr,posixacl)
zroot/home on /mnt/home type zfs (rw,relatime,xattr,posixacl)
```
### Update device symlinks
```bash
udevadm trigger
```
---
## Install Debian!
```bash
debootstrap bookworm /mnt
```
when finished I did the following.
https://simpleit.rocks/linux/replicate-installed-package-selections-from-one-ubuntu-system-to-another/ This will ensure I can populate our minimal install with many of the things we'll need.
```bash
apt-mark showauto > pkgs_auto.lst
apt-mark showmanual > pkgs_manual.lst
```
### Copy files into the new install
```bash
cp /etc/hostid /mnt/etc/hostid
cp /etc/resolv.conf /mnt/etc/
cp pkgs_auto.lst /mnt/root
cp pkgs_manual.lst /mnt/root
mkdir /mnt/etc/zfs
```
### Chroot into the new Install!
```bash
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 /bin/bash
```
## Basic Debian Configuration
### Set Hostname
```bash
echo 'VCR' > /etc/hostname
echo -e '127.0.1.1\VCR' >> /etc/hosts
```
### Set a root password
```bash
passwd
```
### Configure APT
The documentation uses the following
```bash
cat < /etc/apt/sources.list
deb http://deb.debian.org/debian bookworm main contrib
deb-src http://deb.debian.org/debian bookworm main contrib
deb http://deb.debian.org/debian-security bookworm-security main contrib
deb-src http://deb.debian.org/debian-security/ bookworm-security main contrib
deb http://deb.debian.org/debian bookworm-updates main contrib
deb-src http://deb.debian.org/debian bookworm-updates main contrib
deb http://deb.debian.org/debian bookworm-backports main contrib
deb-src http://deb.debian.org/debian bookworm-backports main contrib
EOF
```
however I add `non-free non-free-firmware` to every line because my laptop requires me to have these or i will be missing things.
Additionally the page here https://www.debian.org/releases/bookworm/ says
"Contrary to our wishes, there may be some problems that exist in the release, even though it is declared _stable_. We've made [a list of the major known problems](https://www.debian.org/releases/bookworm/errata),"
Following that link, I add the following to my `sources.list` as well
```bash
deb http://security.debian.org/ bookworm-security main contrib non-free non-free-firmware
```
now run
```bash
apt update
```
### Install additional base packages
```bash
apt install locales keyboard-configuration console-setup
```
### Configure packages to customize local and console properties
```bash
dpkg-reconfigure locales tzdata keyboard-configuration console-setup
```
### Install your Goodies!
Install the packages we're grabbing from the live image to make sure our minimal install has all we need.
```bash
apt install $(cat /root/pkgs_auto.lst)
apt install $(cat /root/pkgs_manual.lst)
```
As with everything I install the following list as well.
System/Tools/Daemons. do NOT forget to enable `ntpd.service` or especially `iwd.service` or you will have to boot back into your live USB, redo the environment config steps and the mounting/chroot steps to do this. Ask me how I know.
- ntpd
- iwd
- NetworkManager
- firmware-linux
User Software
- xfce4
- xfce4-goodies
- libreoffice
- vim
- zsh
- sudo
- neofetch
-
---
## ZFS Configuration
### Install required packages
```bash
apt install linux-headers-amd64 linux-image-amd64 zfs-initramfs dosfstools
echo "REMAKE_INITRD=yes" > /etc/dkms/zfs.conf
```
### Enable systemd ZFS services
```bash
systemctl enable zfs.target
systemctl enable zfs-import-cache
systemctl enable zfs-mount
systemctl enable zfs-import.target
```
### Make ZFS root encryption key available
Now chrooted into our system, we will import our drive and link it's location to where ZFSbootmenu will expect to find it.
```bash
zpool import zdrive
```
briefly exit our chroot
```bash
exit
```
and copy the key into place and croot back in.
```bash
cp /etc/zfs/zroot.key /mnt/etc/zfs/zdrive
chroot /mnt /bin/bash
```
At import, our zpool named zdrive should have automatically mounted to `/etc/zfs/zdrive` where we can create a symlink.
```bash
ln -s /etc/zfs/zdrive/zroot.key /etc/zfs/zroot.key
```
now ZFS should cache the fact that this zpool and dataset are imported and it should remain accessible through reboots.
### Configure `initramfs-tools`
```bash
echo "UMASK=0077" > /etc/initramfs-tools/conf.d/umask.conf
```
Note: Because the encryption key is stored in `/etc/zfs` directory, it will automatically be copied into the system initramfs. There ARE security concerns to this.
TODO: zroot.KEY SEC CONCERNS
https://github.com/zbm-dev/zfsbootmenu/blob/master/docs/general/native-encryption.rst
### Rebuild the initramfs
```bash
update-initramfs -c -k all
```
---
## Install and configure ZFSBootMenu
### Set ZFSBootMenu properties on datasets
```bash
zfs set org.zfsbootmenu:commandline="quiet loglevel=4" zroot/ROOT
```
Setup key caching in ZFSBootMenu.
```bash
zfs set org.zfsbootmenu:keysource="zroot/ROOT/${ID}" zroot
```
### Create a `vfat` filesystem
```bash
mkfs.vfat -F32 "$BOOT_DEVICE"
```
### Create an fstab entry and mount
```bash
cat << EOF >> /etc/fstab
$( blkid | grep "$BOOT_DEVICE" | cut -d ' ' -f 2 ) /boot/efi vfat defaults 0 0
EOF
mkdir -p /boot/efi
mount /boot/efi
```
### Install ZFSBootMenu
Fetch a prebuilt ZFSBootMenu EFI executable, saving it to the EFI system partition:
```bash
apt install curl
```
```bash
mkdir -p /boot/efi/EFI/ZBM
curl -o /boot/efi/EFI/ZBM/VMLINUZ.EFI -L https://get.zfsbootmenu.org/efi
cp /boot/efi/EFI/ZBM/VMLINUZ.EFI /boot/efi/EFI/ZBM/VMLINUZ-BACKUP.EFI
```
### Configure EFI boot entries
```bash
apt install efibootmgr
```
```bash
efibootmgr -c -d "$BOOT_DISK" -p "$BOOT_PART" \
-L "ZFSBootMenu (Backup)" \
-l '\EFI\ZBM\VMLINUZ-BACKUP.EFI'
efibootmgr -c -d "$BOOT_DISK" -p "$BOOT_PART" \
-L "ZFSBootMenu" \
-l '\EFI\ZBM\VMLINUZ.EFI'
```
---
## Prepare for first boot
### Exit the chroot, unmount everything
```bash
exit
```
then from outside
```bash
umount -n -R /mnt
```
### Export the zpool and reboot
```bash
zpool export zroot
reboot
```
Now leave that USB in, and Yaldabaoth and the Archons willing, provided you made the appropriate prerequisite blood sacrifices, you will have a working system.
---
## But Wait! Aren't we Dual Booting??
Yes! the funny thing about dual boot is, it's a sleeper. Without this removable USB key the system just boots into windows.
But when it's plugged in at boot we are met with the ZFSbootmenu and can enter our Debian install no questions asked.
I did not have to configure this manually. Creating an EFI boot partition on my USB and installing ZFSbootmenu and efibootmgr seemed to do this for me. If this is not the case then you would go to the BIOS and set a boot order preference. See documentation on your hardware on how to do this, but for me it's mashing either `F1` or `del` at boot time.
---
## Why are we prompted for a decryption key?
Good question. This is a work in progress but here's what I'm working with. I've configured the earlier doc to be set up such that the properties on the root partition look to the following for a key.
```bash
zroot org.zfsbootmenu:keysource zdrive local
zroot keylocation file:///etc/zfs/zroot.key local
```
If I understood the documentation and the following correctly, ZFSbootmenu SHOULD be able to read a key from a partition on an external device and pull the key off.
- https://github.com/zbm-dev/zfsbootmenu/blob/master/docs/general/native-encryption.rst
- https://www.reddit.com/r/zfs/comments/lkd10u/still_confused_as_to_how_zfsbootmenu_handles/
- https://github.com/zbm-dev/zfsbootmenu/issues/215
I'm still ironing this one out. Some sources indicate that I will need to write an init script. This is possible. Will address shortly.
## initramrd and Key Security
From https://docs.zfsbootmenu.org/en/v3.0.x/general/native-encryption.html
> When adding encryption keys to initramfs images, always ensure that the resulting images are not readable by any user other than root. Recent versions of dracut and mkinitcpio ensure this by default with umask of 0077. Users with read access to your initramfs image will be able to read your ZFS key file even if it has mode 000 in the image; always confirm for your self that the initramfs is protected!
I confirmed this with
```bash
┌──(eli@VCR)-[~]
└─$ ls -lah /boot
total 103M
drwxr-xr-x 3 root root 7 Mar 27 19:29 .
drwxr-xr-x 18 root root 26 Mar 26 05:28 ..
-rw-r--r-- 1 root root 254K Mar 5 22:21 config-6.1.0-32-amd64
drwxr-xr-x 3 root root 4.0K Dec 31 1969 efi
-rw------- 1 root root 95M Mar 26 13:54 initrd.img-6.1.0-32-amd64
-rw-r--r-- 1 root root 83 Mar 5 22:21 System.map-6.1.0-32-amd64
-rw-r--r-- 1 root root 7.9M Mar 5 22:21 vmlinuz-6.1.0-32-amd64
┌──(eli@VCR)-[~]
└─$ cp /boot/initrd.img-6.1.0-32-amd64 .
cp: cannot open '/boot/initrd.img-6.1.0-32-amd64' for reading: Permission denied
```
But I wanted to demonstrate what that would look like were the file able to be grabbed.
I found a couple of writups about unpacking initram files
- https://www.baeldung.com/linux/initrd-vs-initramfs
- https://trendoceans.com/how-to-unpack-initrd-initramfs-to-view-content-in-linux/
but as usual what worked was a stack overflow article
- https://serverfault.com/questions/999033/how-do-i-unpack-initrd-of-ubuntu-18-04-and-then-pack-it-back
> For Ubuntu, at least newer versions, you could use the commands `lsinitramfs ` to inspect and `unmkinitramfs ` to extract.
---
Other Articles In This Series