From 47e5e12866af14112452aeb8bc43a66191c6fbc1 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 8 May 2023 16:06:41 +0200 Subject: [PATCH] mkosi: Package a erofs usr partition with signed verity Let's start moving towards a more involved partitioning setup to test our stuff more when using mkosi. The root partition is generated on boot with systemd-repart. CentOS supports neither erofs nor btrfs so we use squashfs and xfs instead. We also enable SecureBoot= locally for additional coverage. This and the use of verity means users need to run `mkosi genkey` once to generate the keys necessary to do secure boot and verity. --- .github/workflows/mkosi.yml | 18 ++++++++++-------- docs/HACKING.md | 8 +++++--- mkosi.conf.d/10-systemd.conf | 7 +++++++ .../00-base/mkosi.conf.d/10-debian-ubuntu.conf | 1 + .../00-base/mkosi.conf.d/10-opensuse.conf | 1 + .../10-initrd/mkosi.conf.d/10-centos.conf | 3 +++ .../10-initrd/mkosi.conf.d/10-default.conf | 3 +++ .../mkosi.conf.d/10-centos-fedora.conf | 1 + .../20-final/mkosi.conf.d/10-centos/mkosi.conf | 4 ++++ .../usr/lib/repart.d/20-root.conf.d/xfs.conf | 5 +++++ .../mkosi.repart/10-usr.conf.d/squashfs.conf | 5 +++++ .../20-final/mkosi.conf.d/10-ubuntu.conf | 4 +++- .../mkosi.extra/usr/lib/repart.d/20-root.conf | 6 ++++++ .../lib/systemd/mkosi-check-and-shutdown.sh | 2 -- .../system/mkosi-check-and-shutdown.service | 6 ++---- .../20-final/mkosi.repart/00-esp.conf | 8 ++++++++ .../20-final/mkosi.repart/10-usr.conf | 9 +++++++++ .../mkosi.repart/10-usr.conf.d/squashfs.conf | 2 ++ .../20-final/mkosi.repart/11-usr-verity.conf | 7 +++++++ .../mkosi.repart/12-usr-verity-sig.conf | 6 ++++++ 20 files changed, 88 insertions(+), 18 deletions(-) create mode 100644 mkosi.presets/20-final/mkosi.conf.d/10-centos/mkosi.conf create mode 100644 mkosi.presets/20-final/mkosi.conf.d/10-centos/mkosi.extra/usr/lib/repart.d/20-root.conf.d/xfs.conf create mode 100644 mkosi.presets/20-final/mkosi.conf.d/10-centos/mkosi.repart/10-usr.conf.d/squashfs.conf create mode 100644 mkosi.presets/20-final/mkosi.extra/usr/lib/repart.d/20-root.conf create mode 100644 mkosi.presets/20-final/mkosi.repart/00-esp.conf create mode 100644 mkosi.presets/20-final/mkosi.repart/10-usr.conf create mode 100644 mkosi.presets/20-final/mkosi.repart/10-usr.conf.d/squashfs.conf create mode 100644 mkosi.presets/20-final/mkosi.repart/11-usr-verity.conf create mode 100644 mkosi.presets/20-final/mkosi.repart/12-usr-verity-sig.conf diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml index 8c71748df8..7d3ef4b186 100644 --- a/.github/workflows/mkosi.yml +++ b/.github/workflows/mkosi.yml @@ -84,11 +84,10 @@ jobs: [Distribution] Distribution=${{ matrix.distro }} Release=${{ matrix.release }} - SecureBoot=yes [Content] Environment=CI_BUILD=1 - DEFAULT_TIMEOUT_SEC=90 + DEFAULT_TIMEOUT_SEC=120 SLOW_TESTS=true [Output] @@ -101,6 +100,15 @@ jobs: ExtraSearchPaths=!* EOF + # For erofs, we have to install linux-modules-extra-azure, but that doesn't match the running kernel + # version, so we can't load the erofs module. squashfs is a builtin module so we use that instead. + + mkdir -p mkosi.presets/20-final/mkosi.repart/10-usr.conf.d + tee mkosi.presets/20-final/mkosi.repart/10-usr.conf.d/squashfs.conf <<- EOF + [Partition] + Format=squashfs + EOF + - name: Generate secure boot key run: mkosi --debug genkey @@ -113,11 +121,5 @@ jobs: - name: Boot ${{ matrix.distro }} systemd-nspawn run: sudo mkosi --debug boot - - name: Check ${{ matrix.distro }} systemd-nspawn - run: sudo mkosi --debug shell bash -c "[[ -e /testok ]] || { cat /failed-services; exit 1; }" - - name: Boot ${{ matrix.distro }} QEMU run: timeout -k 30 10m mkosi --debug qemu - - - name: Check ${{ matrix.distro }} QEMU - run: sudo mkosi --debug shell bash -c "[[ -e /testok ]] || { cat /failed-services; exit 1; }" diff --git a/docs/HACKING.md b/docs/HACKING.md index 3af58f6b27..0aa9233345 100644 --- a/docs/HACKING.md +++ b/docs/HACKING.md @@ -40,9 +40,11 @@ the [GitHub repository](https://github.com/systemd/mkosi). `mkosi` will build an image for the host distro by default. Currently, the latest github commit is required. `mkosi` also requires systemd v253 (unreleased) or newer. If systemd v253 is not available, `mkosi` will automatically use executables from the systemd build -directory if it's executed from the systemd repository root directory. It is -sufficient to type `mkosi` in the systemd project directory to generate a disk image -you can boot either in `systemd-nspawn` or in a UEFI-capable VM: +directory if it's executed from the systemd repository root directory. First, run +`mkosi genkey` to generate a key and certificate to be used for secure boot and +verity signing. After that is done, it is sufficient to type `mkosi` in the systemd +project directory to generate a disk image you can boot either in `systemd-nspawn` +or in a UEFI-capable VM: ```sh $ sudo mkosi boot # nspawn still needs sudo for now diff --git a/mkosi.conf.d/10-systemd.conf b/mkosi.conf.d/10-systemd.conf index 41a8c2e856..ec0f690d4e 100644 --- a/mkosi.conf.d/10-systemd.conf +++ b/mkosi.conf.d/10-systemd.conf @@ -11,6 +11,11 @@ OutputDirectory=mkosi.output BuildDirectory=mkosi.builddir CacheDirectory=mkosi.cache +[Validation] +SecureBoot=yes +# Disabled until systemd-measure can operate without a TPM device. +SignExpectedPcr=no + [Host] QemuMem=2G ExtraSearchPaths=build/ @@ -29,3 +34,5 @@ KernelCommandLineExtra=systemd.crash_shell ip=enp0s1:any # Make sure sulogin works even with a locked root account. SYSTEMD_SULOGIN_FORCE=1 + # Make sure /sysroot is mounted rw in the initrd. + rw diff --git a/mkosi.presets/00-base/mkosi.conf.d/10-debian-ubuntu.conf b/mkosi.presets/00-base/mkosi.conf.d/10-debian-ubuntu.conf index f5c3afbef4..920e50e42b 100644 --- a/mkosi.presets/00-base/mkosi.conf.d/10-debian-ubuntu.conf +++ b/mkosi.presets/00-base/mkosi.conf.d/10-debian-ubuntu.conf @@ -5,6 +5,7 @@ Distribution=debian ubuntu [Content] Packages= + dmsetup libfdisk1 libfido2-1 libglib2.0-0 diff --git a/mkosi.presets/00-base/mkosi.conf.d/10-opensuse.conf b/mkosi.presets/00-base/mkosi.conf.d/10-opensuse.conf index 4ed5f6ff7c..c5c44b8df8 100644 --- a/mkosi.presets/00-base/mkosi.conf.d/10-opensuse.conf +++ b/mkosi.presets/00-base/mkosi.conf.d/10-opensuse.conf @@ -6,6 +6,7 @@ Distribution=opensuse [Content] # We install gawk, gzip, grep, xz here explicitly so that the busybox versions don't get installed instead. Packages= + device-mapper gawk grep gzip diff --git a/mkosi.presets/10-initrd/mkosi.conf.d/10-centos.conf b/mkosi.presets/10-initrd/mkosi.conf.d/10-centos.conf index c25a17a030..89a207dc71 100644 --- a/mkosi.presets/10-initrd/mkosi.conf.d/10-centos.conf +++ b/mkosi.presets/10-initrd/mkosi.conf.d/10-centos.conf @@ -6,3 +6,6 @@ Distribution=centos [Output] # TODO: Switch to zstd once we stop building CentOS Stream 8. CompressOutput=xz + +[Content] +Packages=xfsprogs diff --git a/mkosi.presets/10-initrd/mkosi.conf.d/10-default.conf b/mkosi.presets/10-initrd/mkosi.conf.d/10-default.conf index 98f0b7dffb..a2a9352266 100644 --- a/mkosi.presets/10-initrd/mkosi.conf.d/10-default.conf +++ b/mkosi.presets/10-initrd/mkosi.conf.d/10-default.conf @@ -5,3 +5,6 @@ Distribution=arch debian fedora opensuse ubuntu [Output] CompressOutput=zst + +[Content] +Packages=btrfs-progs diff --git a/mkosi.presets/20-final/mkosi.conf.d/10-centos-fedora.conf b/mkosi.presets/20-final/mkosi.conf.d/10-centos-fedora.conf index d89f827839..02e11d095f 100644 --- a/mkosi.presets/20-final/mkosi.conf.d/10-centos-fedora.conf +++ b/mkosi.presets/20-final/mkosi.conf.d/10-centos-fedora.conf @@ -12,6 +12,7 @@ Packages= iproute iproute-tc kernel-core + kernel-modules # For squashfs support libcap-ng-utils netcat openssh-server diff --git a/mkosi.presets/20-final/mkosi.conf.d/10-centos/mkosi.conf b/mkosi.presets/20-final/mkosi.conf.d/10-centos/mkosi.conf new file mode 100644 index 0000000000..af4862d4b1 --- /dev/null +++ b/mkosi.presets/20-final/mkosi.conf.d/10-centos/mkosi.conf @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +[Match] +Distribution=centos diff --git a/mkosi.presets/20-final/mkosi.conf.d/10-centos/mkosi.extra/usr/lib/repart.d/20-root.conf.d/xfs.conf b/mkosi.presets/20-final/mkosi.conf.d/10-centos/mkosi.extra/usr/lib/repart.d/20-root.conf.d/xfs.conf new file mode 100644 index 0000000000..99b846d3a8 --- /dev/null +++ b/mkosi.presets/20-final/mkosi.conf.d/10-centos/mkosi.extra/usr/lib/repart.d/20-root.conf.d/xfs.conf @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +# CentOS does not support btrfs so we use xfs instead. +[Partition] +Format=xfs diff --git a/mkosi.presets/20-final/mkosi.conf.d/10-centos/mkosi.repart/10-usr.conf.d/squashfs.conf b/mkosi.presets/20-final/mkosi.conf.d/10-centos/mkosi.repart/10-usr.conf.d/squashfs.conf new file mode 100644 index 0000000000..393d5f038c --- /dev/null +++ b/mkosi.presets/20-final/mkosi.conf.d/10-centos/mkosi.repart/10-usr.conf.d/squashfs.conf @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +# CentOS does not support erofs so we use squashfs instead. +[Partition] +Format=squashfs diff --git a/mkosi.presets/20-final/mkosi.conf.d/10-ubuntu.conf b/mkosi.presets/20-final/mkosi.conf.d/10-ubuntu.conf index eb88ca7644..e677797c73 100644 --- a/mkosi.presets/20-final/mkosi.conf.d/10-ubuntu.conf +++ b/mkosi.presets/20-final/mkosi.conf.d/10-ubuntu.conf @@ -5,4 +5,6 @@ Distribution=ubuntu [Content] Packages= - linux-virtual + # We would like to use linux-image-kvm but it does not have support for dm-verity + # See https://bugs.launchpad.net/ubuntu/+source/linux-meta-kvm/+bug/2019040. + linux-image-generic diff --git a/mkosi.presets/20-final/mkosi.extra/usr/lib/repart.d/20-root.conf b/mkosi.presets/20-final/mkosi.extra/usr/lib/repart.d/20-root.conf new file mode 100644 index 0000000000..2f92af248f --- /dev/null +++ b/mkosi.presets/20-final/mkosi.extra/usr/lib/repart.d/20-root.conf @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +[Partition] +Type=root +Format=btrfs +SizeMinBytes=1G diff --git a/mkosi.presets/20-final/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh b/mkosi.presets/20-final/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh index b86d2d3e69..e6259c42db 100755 --- a/mkosi.presets/20-final/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh +++ b/mkosi.presets/20-final/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh @@ -11,5 +11,3 @@ fi # Exit with non-zero EC if the /failed-services file is not empty (we have -e set) [[ ! -s /failed-services ]] - -: >/testok diff --git a/mkosi.presets/20-final/mkosi.extra/usr/lib/systemd/system/mkosi-check-and-shutdown.service b/mkosi.presets/20-final/mkosi.extra/usr/lib/systemd/system/mkosi-check-and-shutdown.service index 6539325108..6e35b6f288 100644 --- a/mkosi.presets/20-final/mkosi.extra/usr/lib/systemd/system/mkosi-check-and-shutdown.service +++ b/mkosi.presets/20-final/mkosi.extra/usr/lib/systemd/system/mkosi-check-and-shutdown.service @@ -4,11 +4,9 @@ Description=Check if any service failed and then shutdown the machine After=multi-user.target network-online.target Requires=multi-user.target Wants=systemd-resolved.service systemd-networkd.service network-online.target -OnFailure=poweroff.target -OnFailureJobMode=replace-irreversibly +SuccessAction=exit +FailureAction=exit [Service] Type=oneshot -ExecStartPre=-rm -f /failed-services ExecStart=/usr/lib/systemd/mkosi-check-and-shutdown.sh -ExecStartPost=systemctl poweroff --no-block diff --git a/mkosi.presets/20-final/mkosi.repart/00-esp.conf b/mkosi.presets/20-final/mkosi.repart/00-esp.conf new file mode 100644 index 0000000000..96b292ecb8 --- /dev/null +++ b/mkosi.presets/20-final/mkosi.repart/00-esp.conf @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +[Partition] +Type=esp +Format=vfat +CopyFiles=/efi:/ +SizeMinBytes=512M +SizeMaxBytes=512M diff --git a/mkosi.presets/20-final/mkosi.repart/10-usr.conf b/mkosi.presets/20-final/mkosi.repart/10-usr.conf new file mode 100644 index 0000000000..343761d097 --- /dev/null +++ b/mkosi.presets/20-final/mkosi.repart/10-usr.conf @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +[Partition] +Type=usr +Format=erofs +CopyFiles=/usr:/ +Verity=data +VerityMatchKey=usr +Minimize=yes diff --git a/mkosi.presets/20-final/mkosi.repart/10-usr.conf.d/squashfs.conf b/mkosi.presets/20-final/mkosi.repart/10-usr.conf.d/squashfs.conf new file mode 100644 index 0000000000..1e54ee19cf --- /dev/null +++ b/mkosi.presets/20-final/mkosi.repart/10-usr.conf.d/squashfs.conf @@ -0,0 +1,2 @@ +[Partition] +Format=squashfs diff --git a/mkosi.presets/20-final/mkosi.repart/11-usr-verity.conf b/mkosi.presets/20-final/mkosi.repart/11-usr-verity.conf new file mode 100644 index 0000000000..b4d45dd7ef --- /dev/null +++ b/mkosi.presets/20-final/mkosi.repart/11-usr-verity.conf @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +[Partition] +Type=usr-verity +Verity=hash +VerityMatchKey=usr +Minimize=yes diff --git a/mkosi.presets/20-final/mkosi.repart/12-usr-verity-sig.conf b/mkosi.presets/20-final/mkosi.repart/12-usr-verity-sig.conf new file mode 100644 index 0000000000..1841d0a6db --- /dev/null +++ b/mkosi.presets/20-final/mkosi.repart/12-usr-verity-sig.conf @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +[Partition] +Type=usr-verity-sig +Verity=signature +VerityMatchKey=usr