Slackware on encrypted ZFS root

       1267 words, 6 minutes

My Slackware laptop was doing well with LUKS/LVM/EXT4 but after some Fediverse discussion, I decided using ZFS would be safer for my data. The problem is OpenZFS is not integrated into the Linux kernel and not that well integrated into Linux distribution in general.

That said, Ubuntu offers an integrated option and other distros have documentation about such cases. Those are my notes dedicated to The Slackware Linux Project .

I am not aware of an official documentation that drive you through using OpenZFS on Slackware. Those are documentation I found worth reading to understand how OpenZFS can be integrated in Slackware Linux:

I decided that I would run Slackware-current on the laptop. So I downloaded the lastest slackware64-current-install-dvd.iso from AlienBOB and use it as a base to install Slackware.

After trying booting using eLILO and Grub, I finally went for using ZFSBootMenu . I couldn’t have the system boot using eLILO without modifying initrd-tree and rc.d files. Grub seemed to need a dedicated boot dataset with compatibility / limits in ZFS features. ZFSBootMenu seemed to me as the better option; as it allows booting and running the system without modifying Slackware's internals.

Building the OpenZFS package

The OpenZFS package is not available in the Slackware release. One has to compile it from SlackBuilds .

As OpenZFS depends on the Linux kernel version, because of ZFS modules, I used the same ISO to install Slackware on a VPS and build the OpenZFS package. This package is saved on a shared storage and will be used later on to install Slackware on the final computer.

From a system running Slackware-current, simply build the OpenZFS package using the SlackBuilds system. As this system was temporary, I just installed packages from the A, AP, D, K, L and N sections.

# wget https://slackbuilds.org/slackbuilds/15.0/system/openzfs.tar.gz
# tar xzf openzfs.tar.gz
# cd openzfs
# source openzfs.info
# wget $DOWNLOAD
# ./openzfs.SlackBuild

The /tmp/openzfs-2.4.0_6.12.59-x86_64-1_SBo.tgz package is transferred on a remote storage for later usage and this temporary Slackware installation can be deleted or repurposed.

Installing Slackware on ZFS

Boot using the slackware64-current-install-dvd.iso image that was used previously. Having the same Linux kernel version makes things easier. Select a keyboard map and log in as root.

To be able to do the installation from a remote computer, I enabled SSH. This is not a must have. One can type everything from the computer console.

# dhcpcd eth0
# passwd root
# /etc/rc.d/rc.dropbear start

Once connected to the machine, locally or remotely, using root, setup some environment variables, transfer the openzfs-2.4.0_6.12.59-x86_64-1_SBo.tgz package and install some required packages.

# export ID=slackware
# export DISK="/dev/vda"

# mount /dev/sr0 /cdrom
# installpkg /cdrom/slackware64/a/util-linux-2.41.2-x86_64-1.txz
# installpkg /cdrom/slackware64/l/libunwind-1.8.3-x86_64-1.txz
# installpkg openzfs-2.4.0_6.12.59-x86_64-1_SBo.tgz

The /dev/vda disk and /dev/sr0 device were available from my testings using virt-manager. When booting the installer using Ventoy on a real ThinkPad laptop, I used /dev/nvme0n1 as the disk device and /dev/sr3 as the DVD device. Note that the $DISK references further down have to be modified accordingly.

Make sure the storage is cleaned from previous usage.

# zpool labelclear -f "$DISK"
# wipefs -a "$DISK"
# sgdisk --zap-all "$DISK"

Create the ESP and the OS partition.

# sgdisk -n "1:1m:+512m" -t "1:ef00" \
       -n "2:0:-10m"     -t "2:bf00" \
       "$DISK"

# mkfs.vfat ${DISK}1

Prevent entering the passphrase several time during boot process by storing the passphrase into a local file. The file is stored on the ZFS partition and so, protected with ZFS encryption.

# echo 'change_me' > /etc/zfs/rpool.key
# chmod 000 /etc/zfs/rpool.key

Create the ZFS encrypted pool:

# zpool create -f -o ashift=12            \
 -O compression=lz4                       \
 -O atime=on -O relatime=on               \
 -O encryption=aes-256-gcm                \
 -O keylocation=file:///etc/zfs/rpool.key \
 -O keyformat=passphrase                  \
 -o autotrim=on                           \
 -m none rpool "${DISK}2"

Create and configure ZFS datasets you need.

Note that rpool/home is set to mountpoint=legacy so that it can be configured from /etc/fstab later on. This addresses my need (or at least my wish) to have ZFS datasets mounted early in the boot process without modifying /etc/rc.d/rc.S and /etc/rc.d/rc.6. There is an /etc/rc.d/rc.zfs script available but AFAIK it can only be run in a standard way from /etc/rc.d/rc.local and /etc/rc.d/rc.local_shutdown; this can be too late or too soon when datasets such as /var/log or /usr exist and have to been used by standard daemons. Read Slackware System Init and SlackBook system configuration for more details.

# zfs create -o mountpoint=legacy rpool/ROOT
# zfs create -o mountpoint=legacy rpool/home

# zfs create -o mountpoint=/ -o canmount=noauto rpool/ROOT/${ID}

# zpool set bootfs=rpool/ROOT/${ID} rpool

Prepare ZFS storage to be used by setup.

# zpool export rpool
# zpool import -N -R /mnt rpool
# zfs load-key -L prompt rpool

# udevadm trigger

# zfs mount rpool/ROOT/${ID}

# mkdir -p /mnt/home
# mount -t zfs rpool/home /mnt/home

# mkdir -p /mnt/boot/efi
# mount /dev/vda1 /mnt/boot/efi

Then use the classical setup wizard to install the system.

# setup

A message titled NO LINUX PARTITIONS DETECTED is displayed. Acknowledge by using [ OK ].

Select the TARGET option. A message titled EFI SYSTEM PARTITION RECOGNIZED appears. Validate using [ OK ].

The SOURCE MEDIA SELECTION message appears.
Select the 1. Install from a Slackware CD or DVD and [ OK ].

Proceed as usual until the MAKE USB FLASH BOOT is displayed. I choose to Skip and [ OK ].

When the UEFI FIRMWARE DETECTED dialog appear, select Skip installing LILO and [ OK ].

When the INSTALL ELILO dialog box is displayed, select Do not install ELILO and [ OK ].

A SETUP COMPLETE message should appear. Validate with [ OK ].

Back on the Slackware Linux Setup dialog box, select EXIT and [ OK ].

On the Slackware Linux Setup is complete message, select Shell and [ OK ].

Install the OpenZFS package onto the new system and copy some required configuration files.

# installpkg --root /mnt/ openzfs-2.4.0_6.12.59-x86_64-1_SBo.tgz

# mkdir -p /mnt/etc/zfs
# cp -p /etc/zfs/rpool.key /mnt/etc/zfs/

# cp -p /etc/resolv.conf /mnt/etc/

Switch to the installed system to finish its configuration. Then build an initramfs image and install the ZFS Boot Manager.

# chroot /mnt /bin/bash
# source /etc/profile
# source /etc/os-release

# cat << EOF > /etc/dracut.conf.d/zol.conf
nofsck="yes"
add_dracutmodules+=" zfs "
omit_dracutmodules+=" btrfs "
install_items+=" /etc/zfs/rpool.key "
EOF

# dracut --force --regenerate-all

# zfs set org.zfsbootmenu:commandline="quiet rhgb" rpool/ROOT
# zfs set org.zfsbootmenu:keysource="rpool/ROOT/${ID}" rpool

# mkdir -p /boot/efi/EFI/ZBM
# curl -o /boot/efi/EFI/ZBM/VMLINUZ.EFI -L https://get.zfsbootmenu.org/efi
# cp -p /boot/efi/EFI/ZBM/VMLINUZ.EFI /boot/efi/EFI/ZBM/VMLINUZ-BACKUP.EFI

# efibootmgr -c -d "$DISK" -p "1" \
  -L "ZFSBootMenu (Backup)"       \
  -l '\EFI\ZBM\VMLINUZ-BACKUP.EFI'

# efibootmgr -c -d "$DISK" -p "1" \
  -L "ZFSBootMenu"                \
  -l '\EFI\ZBM\VMLINUZ.EFI'

Configure the ZFS dataset to be mounted at boot time.

# sed -i '1s;^;rpool/home /home zfs defaults 0 0\n;' /etc/fstab

Installation is now complete. Exit the chroot environment, unmount everything under /mnt and reboot to the new system.

# exit

# umount /mnt/sys/firmware/efi/efivars /mnt/sys /mnt/proc /mnt/dev
# umount /mnt/sys/firmware/efi/efivars /mnt/sys /mnt/proc /mnt/dev/shm /mnt/dev/pts /mnt/dev
# umount /mnt/boot/efi
# umount /mnt/home
# zpool export rpool

# reboot

The system should boot properly and you may be able to use it as usual for further customization.

Special thanks to Matt Egger for maintaining the SlackBuilds script and sending me information on how he uses OpenZFS on Slackware!

#OneMoreThing: Having no swap does not prevent my laptop to go suspend and resume. This works ok “on my computer”. Hibernation, or suspend-to-disk, doesn’t work. According to documentation, having the hibernation swap file on ZFS will screw everything. One would need another dedicated partition for this usage. And that probably implies LUKS to ensure privacy.