From 1090e918674a3f0296dc158067530b6d440a0bea Mon Sep 17 00:00:00 2001 From: Luc Date: Fri, 8 Aug 2025 20:17:24 +0200 Subject: [PATCH] docs/zlevis/implementation.md: add dracut implementation --- docs/zlevis/implementation.md | 65 +++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/docs/zlevis/implementation.md b/docs/zlevis/implementation.md index e83a2a4..a2a6a8a 100644 --- a/docs/zlevis/implementation.md +++ b/docs/zlevis/implementation.md @@ -1,6 +1,6 @@ ## Mkinitfs -[Mkinitfs](https://gitlab.alpinelinux.org/alpine/mkinitfs) is the `initramfs` generator of [Alpine Linux](https://alpinelinux.org/). Among the usual operations to setup `zlevis`, i.e. writing the encryption key of the ZFS root pool to the TPM after the creation of the ZFS root pool, enabling the `zlevis-hook` in `mkinitfs.conf` and installing `zlevis` on the host system, we require to make an adaptation to the `initramfs-init` script of `mkinitfs`. +[Mkinitfs](https://gitlab.alpinelinux.org/alpine/mkinitfs) is the `initramfs` generator of [Alpine Linux](https://alpinelinux.org/). Among the usual operations to setup `zlevis`, i.e. writing the encryption key of the `ZFS` root pool to the TPM after the creation of the `ZFS` root pool, enabling the `zlevis-hook` in `mkinitfs.conf` and installing `zlevis` on the host system, we require to make an adaptation to the `initramfs-init` script of `mkinitfs`. Particularly, in the `prepare_zfs_root()` function we need to add the option `zlevis decrypt "$_root_pool" | zfs load-key -L prompt "$_root_pool"`: @@ -50,4 +50,65 @@ kernel/drivers/char/tpm* ## Dracut -Work in progress. \ No newline at end of file +[Dracut](https://dracut-ng.github.io/dracut-ng) is the default `initramfs` generator of [Gentoo Linux](https://www.gentoo.org/) and [Void Linux](https://voidlinux.org/). Among the usual operations to setup `zlevis`, i.e. writing the encryption key of the `ZFS` root pool to the TPM after the creation of the `ZFS` root pool, enabling the `zlevis` module in `/etc/dracut.conf.d` and installing `zlevis` on the host system, we require to add the `zlevis` module in `/usr/lib/dracut/modules.d`. + +Create the **executable** module setup of the `zlevis-dracut` module: + +``` shell title="/usr/lib/dracut/modules.d/85zlevis/module-setup.sh" +#!/bin/bash + +# Exit immediately if a command exits with a non-zero status +set -e + +# Depend on udev-rules and zfs +depends() { + echo udev-rules zfs + return 0 +} + +install() { + # Install the appropriate binaries and libraries + inst_multiple /usr/bin /usr/bin/zlevis /usr/bin/zlevis-decrypt /usr/bin/jose /usr/bin/tpm2* + inst_multiple /usr/lib /usr/lib/libtss2-tcti* + + # Run the zlevis decryption hook before the 90zfs hook + inst_hook pre-mount 85 "${moddir}/zlevis.sh" + inst_simple "${moddir}/zlevis.sh" "/sbin/zlevis.sh" +} + +# Exit with the status of the last command +exit $? +``` + +and create the **executable** module script of the `zlevis-dracut` module: + +``` shell title="/usr/lib/dracut/modules.d/85zlevis/zlevis.sh" +#!/bin/sh + +# Exit immediately if a command exits with a non-zero status +set -e + +# Load the ZFS kernel module +modprobe zfs 2>/dev/null +udevadm settle + +# Search for encrypted pool's by means of the cmdline root atribute +local _root_vol="${root}" +local _root_pool="${_root_vol%%/*}" + +# Import the root pool +zpool import -N -d /dev $_root_pool + +# If the pool is encrypted run `zlevis decrypt` to obtain the key stored in the TPM and load the key +if [ $(zpool list -H -o feature@encryption $_root_pool) = "active" ]; then + local _encryption_root=$(zfs get -H -o value encryptionroot $_root_vol) + if [ "$_encryption_root" != "-" ]; then + zlevis decrypt $_root_pool | zfs load-key -L prompt "$_root_pool" || echo "Failed to unlock $_root_pool with TPM" + fi +fi + +# Exit with the status of the last command +exit $? +``` + +Now `dracut` will recognise the `zlevis` module, and if enabled will be added to the `initramfs` to be executed before the `90zfs` hook. \ No newline at end of file