From 97efe01f71bdff74592b814264d4230d6536d80c Mon Sep 17 00:00:00 2001 From: alexhulbert Date: Tue, 7 Jul 2026 02:15:27 -0400 Subject: [PATCH] Add module to run rootfs on disk thru dm verity --- flake.nix | 1 + mkosi.profiles/azure/mkosi.postoutput | 14 ++++++++++++ mkosi.profiles/gcp/mkosi.postoutput | 22 ++++++++++++++----- .../kernel/config.d/50-verity-root | 8 +++++++ modules/verity-root/mkosi.conf | 18 +++++++++++++++ modules/verity-root/repart.d/00-esp.conf | 8 +++++++ modules/verity-root/repart.d/10-root.conf | 12 ++++++++++ .../verity-root/repart.d/20-root-verity.conf | 6 +++++ shared/mkosi.finalize.d/90-debloat.sh | 11 ++++++++++ 9 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 modules/verity-root/kernel/config.d/50-verity-root create mode 100644 modules/verity-root/mkosi.conf create mode 100644 modules/verity-root/repart.d/00-esp.conf create mode 100644 modules/verity-root/repart.d/10-root.conf create mode 100644 modules/verity-root/repart.d/20-root-verity.conf diff --git a/flake.nix b/flake.nix index 5f699e32..b56f7f56 100644 --- a/flake.nix +++ b/flake.nix @@ -58,6 +58,7 @@ debootstrap dosfstools e2fsprogs + erofs-utils mtools gptfdisk util-linux diff --git a/mkosi.profiles/azure/mkosi.postoutput b/mkosi.profiles/azure/mkosi.postoutput index 6df59ec6..58d99c23 100755 --- a/mkosi.profiles/azure/mkosi.postoutput +++ b/mkosi.profiles/azure/mkosi.postoutput @@ -5,6 +5,20 @@ EFI_FILE="${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.efi" VHD_FILE="${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.vhd" WORK_DIR="${OUTPUTDIR}/azure-tmp" +# In verity-root mode, use existing mkosi disk image +if [ "$(jq -r .Format "$MKOSI_CONFIG")" = "disk" ]; then + mkdir -p "$WORK_DIR" + raw="$WORK_DIR/azure_image.raw" + cp --sparse=always "${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.raw" "$raw" + sgdisk --disk-guid "12345678-1234-5678-1234-567812345678" "$raw" + truncate -s %1MiB "$raw" + echo write | sfdisk --no-reread "$raw" + qemu-img convert -O vpc -o subformat=fixed,force_size "$raw" "$VHD_FILE" + rm -rf "$WORK_DIR" + echo "Successfully created VHD: $VHD_FILE" + exit 0 +fi + if [ ! -f "$EFI_FILE" ]; then echo "Error: EFI file not found at $EFI_FILE" exit 1 diff --git a/mkosi.profiles/gcp/mkosi.postoutput b/mkosi.profiles/gcp/mkosi.postoutput index a7f9ba48..dfdca1f4 100755 --- a/mkosi.profiles/gcp/mkosi.postoutput +++ b/mkosi.profiles/gcp/mkosi.postoutput @@ -3,7 +3,22 @@ set -eu -o pipefail export SOURCE_DATE_EPOCH=0 # not propagated from the main config, needed for mkfs.vfat -export SYSTEMD_REPART_MKFS_OPTIONS_VFAT="-i 12345678 --invariant" +export SYSTEMD_REPART_MKFS_OPTIONS_VFAT="--invariant" + +package_raw_as_tar() { + cd ${OUTPUTDIR} + ln -sf ${IMAGE_ID}_${IMAGE_VERSION}.raw disk.raw + tar --mtime="@${SOURCE_DATE_EPOCH}" --dereference --format=oldgnu -Sczf ${IMAGE_ID}_${IMAGE_VERSION}.tar.gz disk.raw + unlink disk.raw +} + +# In verity-root mode, use existing mkosi disk image +if [ "$(jq -r .Format "$MKOSI_CONFIG")" = "disk" ]; then + sgdisk --disk-guid "12345678-1234-5678-1234-567812345678" ${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.raw + package_raw_as_tar + exit 0 +fi + mkdir -p ${OUTPUTDIR}/esp/EFI/BOOT cp ${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.efi ${OUTPUTDIR}/esp/EFI/BOOT/BOOTX64.EFI # Set fixed timestamps for reproducibility (FAT uses file mtime for directory entries) @@ -33,8 +48,5 @@ sgdisk --disk-guid "12345678-1234-5678-1234-567812345678" ${OUTPUTDIR}/${IMAGE_I rm -rf ${OUTPUTDIR}/esp -cd ${OUTPUTDIR} -ln -sf ${IMAGE_ID}_${IMAGE_VERSION}.raw disk.raw -tar --mtime="@${SOURCE_DATE_EPOCH}" --dereference --format=oldgnu -Sczf ${IMAGE_ID}_${IMAGE_VERSION}.tar.gz disk.raw -unlink disk.raw +package_raw_as_tar rm -f ${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.raw diff --git a/modules/verity-root/kernel/config.d/50-verity-root b/modules/verity-root/kernel/config.d/50-verity-root new file mode 100644 index 00000000..985e9c7c --- /dev/null +++ b/modules/verity-root/kernel/config.d/50-verity-root @@ -0,0 +1,8 @@ +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_VERITY=y +CONFIG_CRYPTO_SHA256=y +CONFIG_EROFS_FS=y +CONFIG_EROFS_FS_XATTR=y +CONFIG_EROFS_FS_POSIX_ACL=y +CONFIG_OVERLAY_FS=y diff --git a/modules/verity-root/mkosi.conf b/modules/verity-root/mkosi.conf new file mode 100644 index 00000000..631be49b --- /dev/null +++ b/modules/verity-root/mkosi.conf @@ -0,0 +1,18 @@ +[Build] +Environment=KERNEL_CONFIG_SNIPPETS_VERITY=modules/verity-root/kernel/config.d + SYSTEMD_REPART_MKFS_OPTIONS_VFAT=--invariant + # Debloated after finalize hook since mkosi looks in this directory for the kernel + SKIP_DEBLOAT_PATHS_VERITY=/usr/lib/modules + +[Output] +Format=disk +RepartDirectories=modules/verity-root/repart.d +SplitArtifacts=uki + +[Content] +Bootable=yes +Bootloader=uki +KernelModulesInitrd=no +KernelCommandLine=systemd.volatile=overlay +# Init contains a hack that's only needed when initramfs is the rootfs +RemoveFiles=/init diff --git a/modules/verity-root/repart.d/00-esp.conf b/modules/verity-root/repart.d/00-esp.conf new file mode 100644 index 00000000..2f0cf956 --- /dev/null +++ b/modules/verity-root/repart.d/00-esp.conf @@ -0,0 +1,8 @@ +[Partition] +Type=esp +Format=vfat +UUID=87654321-4321-8765-4321-876543218765 +Label=ESP +CopyFiles=/efi:/ +SizeMinBytes=260M +SizeMaxBytes=260M diff --git a/modules/verity-root/repart.d/10-root.conf b/modules/verity-root/repart.d/10-root.conf new file mode 100644 index 00000000..366d90b6 --- /dev/null +++ b/modules/verity-root/repart.d/10-root.conf @@ -0,0 +1,12 @@ +[Partition] +Type=root +Format=erofs +CopyFiles=/ +ExcludeFiles=/boot +ExcludeFiles=/efi +# mkosi looks for the kernel here after .finalize hooks run +ExcludeFiles=/usr/lib/modules +Label=root +Verity=data +VerityMatchKey=root +Minimize=best diff --git a/modules/verity-root/repart.d/20-root-verity.conf b/modules/verity-root/repart.d/20-root-verity.conf new file mode 100644 index 00000000..ff806893 --- /dev/null +++ b/modules/verity-root/repart.d/20-root-verity.conf @@ -0,0 +1,6 @@ +[Partition] +Type=root-verity +Label=root-verity +Verity=hash +VerityMatchKey=root +Minimize=best diff --git a/shared/mkosi.finalize.d/90-debloat.sh b/shared/mkosi.finalize.d/90-debloat.sh index 966a9124..21c0a54f 100755 --- a/shared/mkosi.finalize.d/90-debloat.sh +++ b/shared/mkosi.finalize.d/90-debloat.sh @@ -52,7 +52,18 @@ if [[ ! "${PROFILES:-}" == *"devtools"* ]]; then ) fi +# Modules can skip debloat paths via SKIP_DEBLOAT_PATHS_* env vars (space-separated) +skip_paths=() +for var in "${!SKIP_DEBLOAT_PATHS@}"; do + skip_paths+=(${!var}) +done +skip=" ${skip_paths[*]} " + for p in "${debloat_paths[@]}"; do + if [[ "$skip" == *" $p "* ]]; then + echo "Skipping $p" + continue + fi echo "Debloating $p" rm -rf $BUILDROOT$p done