From 1dc7a0fae663f1f9a022630876eaa8afc5b92f3f Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Tue, 11 Sep 2018 16:47:20 +0200 Subject: [PATCH] use single image for squashfs and dmverity --- 10verity/module-setup.sh | 13 +++++++ 10verity/verity-generator | 78 +++++++++++++++++++++++++++++++++++++++ clonedisk.sh | 14 +++---- mkimage.sh | 15 ++------ mkrelease.sh | 1 - pkglist.txt | 5 ++- pre-pivot.sh | 59 ++++++++++------------------- prepare-root.sh | 24 +++++++----- quirks/nss.sh | 4 +- squashfs-size.sh | 4 +- update.sh | 20 +++------- 11 files changed, 149 insertions(+), 88 deletions(-) create mode 100755 10verity/module-setup.sh create mode 100755 10verity/verity-generator diff --git a/10verity/module-setup.sh b/10verity/module-setup.sh new file mode 100755 index 0000000..f3279fe --- /dev/null +++ b/10verity/module-setup.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +depends() { + echo systemd dm +} + +install() { + inst_multiple veritysetup systemd-escape + inst_simple "$moddir/verity-generator" \ + "$systemdutildir/system-generators/verity-generator" +} diff --git a/10verity/verity-generator b/10verity/verity-generator new file mode 100755 index 0000000..bf9ff4a --- /dev/null +++ b/10verity/verity-generator @@ -0,0 +1,78 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +# This script generates a service that manages a dm-verity device for the chosen ROOT partition + + +set -e + +cmdline=( $("${UNIT_DIR}/verity-setup.service" <<-EOF + # Automatically generated by verity-generator + + [Unit] + Description=Verity Setup for /dev/mapper/root + SourcePath=/proc/cmdline + DefaultDependencies=no + IgnoreOnIsolate=true + BindsTo=dev-mapper-root.device + BindsTo=${device} + After=${device} + + [Service] + Type=oneshot + RemainAfterExit=yes + ExecStart=/bin/sh -c '/sbin/veritysetup create root ${hashoffset:+--hash-offset="${hashoffset}"} "${root}" "${root}" "${roothash}"' + ExecStop=/sbin/veritysetup remove root +EOF + + requires_dir="${UNIT_DIR}/dev-mapper-root.device.requires" + mkdir -p "${requires_dir}" + ln -sf "../verity-setup.service" "${requires_dir}/verity-setup.service" +fi diff --git a/clonedisk.sh b/clonedisk.sh index a129481..aca3dbb 100755 --- a/clonedisk.sh +++ b/clonedisk.sh @@ -116,9 +116,7 @@ if ! [[ $UPDATE ]]; then sfdisk -W always -w always "$OUT" << EOF label: gpt size=512MiB, type=c12a7328-f81f-11d2-ba4b-00a0c93ec93b, name="ESP System Partition" - size=64M, type=2c7357ed-ebd2-46d9-aec1-23d437ec2bf5, name="ver1", uuid=$(blkid -o value -s PARTUUID ${IN}2) size=4GiB, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, name="root1", uuid=$(blkid -o value -s PARTUUID ${IN}3) - size=64M, type=2c7357ed-ebd2-46d9-aec1-23d437ec2bf5, name="ver2" size=4GiB, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, name="root2" size=${mem}GiB, type=0657fd6d-a4ab-43c4-84e5-0933c84b4f4e, name="swap" type=3b8f8425-20e0-4f3b-907f-1a25a76f98e9, name="data" @@ -135,7 +133,7 @@ if [[ ${OUT#/dev/nvme} != $OUT ]]; then OUT="${OUT}p" fi -for i in 1 2 3; do +for i in 1 2; do dd if=${IN}${i} of=${OUT}${i} status=progress sfdisk --part-uuid ${OUT_DEV} $i $(blkid -o value -s PARTUUID ${IN}${i}) done @@ -145,15 +143,15 @@ if ! [[ $UPDATE ]]; then # ------------------------------------------------------------------------------ # swap echo -n "zero key" \ - | cryptsetup luksFormat --type luks2 ${OUT}6 /dev/stdin - + | cryptsetup luksFormat --type luks2 ${OUT}4 /dev/stdin + # ------------------------------------------------------------------------------ # data echo -n "zero key" \ - | cryptsetup luksFormat --type luks2 ${OUT}7 /dev/stdin + | cryptsetup luksFormat --type luks2 ${OUT}5 /dev/stdin else - mkswap ${OUT}6 - mkfs.xfs -L data ${OUT}7 + mkswap ${OUT}4 + mkfs.xfs -L data ${OUT}5 fi fi diff --git a/mkimage.sh b/mkimage.sh index 046a610..fb714da 100755 --- a/mkimage.sh +++ b/mkimage.sh @@ -106,8 +106,6 @@ trap 'exit 1;' SIGINT ROOT_HASH=$(<"$SOURCE"/root-hash.txt) ROOT_UUID=${ROOT_HASH:32:8}-${ROOT_HASH:40:4}-${ROOT_HASH:44:4}-${ROOT_HASH:48:4}-${ROOT_HASH:52:12} -HASH_UUID=${ROOT_HASH:0:8}-${ROOT_HASH:8:4}-${ROOT_HASH:12:4}-${ROOT_HASH:16:4}-${ROOT_HASH:20:12} - # ------------------------------------------------------------------------------ # Testdisk @@ -137,18 +135,16 @@ if ! [[ $UPDATE ]]; then sfdisk "${DEV}" << EOF label: gpt size=512MiB, type=c12a7328-f81f-11d2-ba4b-00a0c93ec93b, name="ESP System Partition" - size=64MiB, type=2c7357ed-ebd2-46d9-aec1-23d437ec2bf5, name="ver1", uuid=$HASH_UUID size=4GiB, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, name="root1", uuid=$ROOT_UUID type=3b8f8425-20e0-4f3b-907f-1a25a76f98e9, name="data" EOF udevadm settle - for i in 1 2 3 4; do + for i in 1 2 3; do wipefs --force --all ${DEV_PART}${i} done udevadm settle else - sfdisk --part-uuid ${DEV} 2 ${HASH_UUID} sfdisk --part-uuid ${DEV} 3 ${ROOT_UUID} fi @@ -164,18 +160,14 @@ mkdir -p "$MY_TMPDIR"/boot/EFI/Boot cp "$SOURCE"/bootx64.efi "$MY_TMPDIR"/boot/EFI/Boot/bootx64.efi umount "$MY_TMPDIR"/boot -# ------------------------------------------------------------------------------ -# ver1 -dd if="$SOURCE"/root.verity.img of=${DEV_PART}2 status=progress - # ------------------------------------------------------------------------------ # root1 -dd if="$SOURCE"/root.squashfs.img of=${DEV_PART}3 status=progress +dd if="$SOURCE"/root.img of=${DEV_PART}2 status=progress # ------------------------------------------------------------------------------ # data if ! [[ $UPDATE ]]; then - mkfs.xfs -L data ${DEV_PART}4 + mkfs.xfs -L data ${DEV_PART}3 fi # ------------------------------------------------------------------------------ # DONE @@ -184,4 +176,3 @@ sync losetup -d $DEV || : eject "$DEV" || : sync - diff --git a/mkrelease.sh b/mkrelease.sh index 7ad9f31..7fae1fc 100755 --- a/mkrelease.sh +++ b/mkrelease.sh @@ -2,7 +2,6 @@ JSON="$(realpath -e $1)" BASEDIR="${JSON%/*}" - IMAGE="${BASEDIR}/$(jq -r '.name' ${JSON})-$(jq -r '.version' ${JSON})" ( diff --git a/pkglist.txt b/pkglist.txt index 1526c29..0b0be6e 100644 --- a/pkglist.txt +++ b/pkglist.txt @@ -76,6 +76,9 @@ libvirt-daemon-config-network libvirt-daemon-kvm squashfs-tools mc -veritysetup rsync pesign +nss-tools +gnu-efi-devel +sbsigntools + diff --git a/pre-pivot.sh b/pre-pivot.sh index 7a0b38b..70e7c28 100644 --- a/pre-pivot.sh +++ b/pre-pivot.sh @@ -1,46 +1,27 @@ #!/bin/bash -root=$(getarg systemd.verity_root_hash) +bootdisk() { + UUID=$({ read -r -n 1 -d '' _; read -n 72 uuid; echo -n ${uuid,,}; } < /sys/firmware/efi/efivars/LoaderDevicePartUUID-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f) -case "$root" in - block:LABEL=*|LABEL=*) - root="${root#block:}" - root="$(echo $root | sed 's,/,\\x2f,g')" - root="/dev/disk/by-label/${root#LABEL=}" - rootok=1 ;; - block:UUID=*|UUID=*) - root="${root#block:}" - root="${root#UUID=}" - root="$(echo $root | tr "[:upper:]" "[:lower:]")" - root="/dev/disk/by-uuid/${root#UUID=}" - rootok=1 ;; - block:PARTUUID=*|PARTUUID=*) - root="${root#block:}" - root="${root#PARTUUID=}" - root="$(echo $root | tr "[:upper:]" "[:lower:]")" - root="/dev/disk/by-partuuid/${root}" - rootok=1 ;; - block:PARTLABEL=*|PARTLABEL=*) - root="${root#block:}" - root="/dev/disk/by-partlabel/${root#PARTLABEL=}" - rootok=1 ;; - /dev/*) - rootok=1 ;; -esac + [[ $UUID ]] || return 1 + echo "/dev/disk/by-partuuid/$UUID" + return 0 +} + +get_disk() { + for dev in /dev/disk/by-path/*; do + [[ $dev -ef $1 ]] || continue + echo ${dev%-part*} + return 0 + done + return 1 +} + +BOOTDISK=$(get_disk $(bootdisk)) +[[ $BOOTDISK ]] || die "No boot disk found" unset FOUND -for d in /dev/disk/by-path/*; do - [[ $d -ef $root ]] || continue - FOUND=1 - break -done - -[[ $FOUND ]] || die "No boot disk found" - -disk=${d%-part*} - -unset FOUND -for swapdev in $disk*; do +for swapdev in $BOOTDISK-part*; do [[ $(blkid -o value -s PARTLABEL "$swapdev") == "swap" ]] || continue FOUND=1 break @@ -83,7 +64,7 @@ fi unset FOUND -for datadev in $disk*; do +for datadev in $BOOTDISK-part*; do [[ $(blkid -o value -s PARTLABEL "$datadev") == "data" ]] || continue FOUND=1 break diff --git a/prepare-root.sh b/prepare-root.sh index 0a3b0b8..2202146 100755 --- a/prepare-root.sh +++ b/prepare-root.sh @@ -219,6 +219,7 @@ dnf -v --nogpgcheck \ efibootmgr \ jq \ gnupg2 \ + veritysetup \ $PKGLIST for i in passwd shadow group gshadow subuid subgid; do @@ -251,6 +252,7 @@ rpm --root "$sysroot" -qa | sort > "$sysroot"/usr/rpm-list.txt mkdir -p "$sysroot"/overlay/efi cp "${BASEDIR}"/pre-pivot.sh "$sysroot"/pre-pivot.sh +cp -avr "${BASEDIR}"/10verity "$sysroot"/usr/lib/dracut/modules.d/ chmod 0755 "$sysroot"/pre-pivot.sh KVER=$(cd "$sysroot"/lib/modules/; ls -1d ??* | tail -1) @@ -265,9 +267,7 @@ chroot "$sysroot" \ dracut -N --kver $KVER --force \ --filesystems "squashfs vfat xfs" \ --add-drivers "=drivers/char/tpm" \ - -m "bash systemd systemd-initrd modsign crypt dm kernel-modules qemu rootfs-block udev-rules dracut-systemd base fs-lib shutdown terminfo resume" \ - --install /usr/lib/systemd/systemd-veritysetup \ - --install /usr/lib/systemd/system-generators/systemd-veritysetup-generator \ + -m "bash systemd systemd-initrd modsign crypt dm kernel-modules qemu rootfs-block udev-rules dracut-systemd base fs-lib shutdown terminfo resume verity" \ --install "clonedisk wipefs sfdisk dd mkfs.xfs mkswap chroot mountpoint mkdir stat openssl" \ --install "clevis clevis-luks-bind jose clevis-encrypt-tpm2 clevis-decrypt clevis-luks-unlock clevis-decrypt-tpm2" \ --install "cryptsetup tail sort pwmake mktemp swapon" \ @@ -303,7 +303,7 @@ fi . "${BASEDIR}"/quirks/nss.sh -for q in "${QUIRKS[@]}"; do +for q in "${QUIRKS[@]}"; do . "${BASEDIR}"/quirks/"$q".sh done @@ -469,7 +469,7 @@ mv -v "$sysroot"/lib/modules/*/vmlinuz "$MY_TMPDIR"/linux rm -fr "$sysroot"/{boot,root} ln -sfnr "$sysroot"/data/root "$sysroot"/root mkdir -p "$sysroot"/usr/etc -mv "$sysroot"/etc/yum.repos.d "$sysroot"/usr/etc/yum.repos.d +mv "$sysroot"/etc/yum.repos.d "$sysroot"/usr/etc/yum.repos.d mkdir "$sysroot"/efi rm -fr "$sysroot"/var/* rm -fr "$sysroot"/home/* @@ -493,11 +493,15 @@ ROOT_HASH=$(veritysetup format "$MY_TMPDIR"/root.squashfs.img "$MY_TMPDIR"/root. echo "$ROOT_HASH" > "$MY_TMPDIR"/root-hash.txt ROOT_UUID=${ROOT_HASH:32:8}-${ROOT_HASH:40:4}-${ROOT_HASH:44:4}-${ROOT_HASH:48:4}-${ROOT_HASH:52:12} -HASH_UUID=${ROOT_HASH:0:8}-${ROOT_HASH:8:4}-${ROOT_HASH:12:4}-${ROOT_HASH:16:4}-${ROOT_HASH:20:12} +ROOT_SIZE=$(stat --printf '%s' "$MY_TMPDIR"/root.squashfs.img) +HASH_SIZE=$(stat --printf '%s' "$MY_TMPDIR"/root.verity.img) +cat "$MY_TMPDIR"/root.verity.img >> "$MY_TMPDIR"/root.squashfs.img +mv "$MY_TMPDIR"/root.squashfs.img "$MY_TMPDIR"/root.img +IMAGE_SIZE=$(stat --printf '%s' "$MY_TMPDIR"/root.img) # ------------------------------------------------------------------------------ # make bootx64.efi -echo -n "rd.shell=0 quiet video=efifb:nobgrt audit=0 selinux=0 roothash=$ROOT_HASH systemd.verity_root_data=PARTUUID=$ROOT_UUID systemd.verity_root_hash=PARTUUID=$HASH_UUID raid=noautodetect" > "$MY_TMPDIR"/options.txt +echo -n "quiet rd.shell=0 video=efifb:nobgrt audit=0 selinux=0 verity.imagesize=$IMAGE_SIZE verity.roothash=$ROOT_HASH verity.root=PARTUUID=$ROOT_UUID verity.hashoffset=$ROOT_SIZE raid=noautodetect root=/dev/mapper/root" > "$MY_TMPDIR"/options.txt echo -n "${NAME}-${VERSION_ID}" > "$MY_TMPDIR"/release.txt objcopy \ --add-section .release="$MY_TMPDIR"/release.txt --change-section-vma .release=0x20000 \ @@ -511,8 +515,7 @@ objcopy \ mkdir -p "$OUTDIR" mv "$MY_TMPDIR"/root-hash.txt \ "$MY_TMPDIR"/bootx64.efi \ - "$MY_TMPDIR"/root.squashfs.img \ - "$MY_TMPDIR"/root.verity.img \ + "$MY_TMPDIR"/root.img \ "$MY_TMPDIR"/release.txt \ "$MY_TMPDIR"/options.txt \ "$MY_TMPDIR"/linux \ @@ -524,7 +527,8 @@ chown -R "$USER" "$OUTDIR" cat > "${OUTDIR%/*}/${NAME}-latest.json" </dev/null; done; getuint) - echo $(((size+4095)/4096*4096)) + # super block is 96 bytes + # pad to 4096 + echo $(((size+96+4095)/4096*4096)) } squashfs_size diff --git a/update.sh b/update.sh index c95ddd3..0b7f21b 100755 --- a/update.sh +++ b/update.sh @@ -68,15 +68,12 @@ CURRENT_ROOT_HASH=${CURRENT_ROOT_HASH#*roothash=} CURRENT_ROOT_HASH=${CURRENT_ROOT_HASH%% *} CURRENT_ROOT_UUID=${CURRENT_ROOT_HASH:32:8}-${CURRENT_ROOT_HASH:40:4}-${CURRENT_ROOT_HASH:44:4}-${CURRENT_ROOT_HASH:48:4}-${CURRENT_ROOT_HASH:52:12} -CURRENT_HASH_UUID=${CURRENT_ROOT_HASH:0:8}-${CURRENT_ROOT_HASH:8:4}-${CURRENT_ROOT_HASH:12:4}-${CURRENT_ROOT_HASH:16:4}-${CURRENT_ROOT_HASH:20:12} [[ /dev/disk/by-partlabel/root1 -ef /dev/disk/by-partuuid/${CURRENT_ROOT_UUID} ]] \ - && [[ /dev/disk/by-partlabel/ver1 -ef /dev/disk/by-partuuid/${CURRENT_HASH_UUID} ]] \ && NEW_ROOT_NUM=2 && OLD_ROOT_NUM=1 [[ /dev/disk/by-partlabel/root2 -ef /dev/disk/by-partuuid/${CURRENT_ROOT_UUID} ]] \ - && [[ /dev/disk/by-partlabel/ver2 -ef /dev/disk/by-partuuid/${CURRENT_HASH_UUID} ]] \ - && NEW_ROOT_NUM=1 && OLD_ROOT_NUM=2 + && NEW_ROOT_NUM=1 && OLD_ROOT_NUM=2 if ! [[ $NEW_ROOT_NUM ]]; then echo "Current partitions booted from not found!" @@ -85,18 +82,14 @@ fi ## find base device and partition number for dev in /dev/disk/by-path/*; do - if ! [[ $VER_PARTNO ]] && [[ /dev/disk/by-partlabel/ver${NEW_ROOT_NUM} -ef $dev ]]; then - VER_PARTNO=${dev##*-part} - ROOT_DEV=${dev%-part*} - fi if ! [[ $ROOT_PARTNO ]] && [[ /dev/disk/by-partlabel/root${NEW_ROOT_NUM} -ef $dev ]]; then ROOT_PARTNO=${dev##*-part} ROOT_DEV=${dev%-part*} fi - [[ $ROOT_PARTNO ]] && [[ $VER_PARTNO ]] && break + [[ $ROOT_PARTNO ]] && break done -if ! [[ $ROOT_PARTNO ]] || ! [[ $VER_PARTNO ]] || ! [[ $ROOT_DEV ]]; then +if ! [[ $ROOT_PARTNO ]] || ! [[ $ROOT_DEV ]]; then echo "Couldn't find partition numbers" exit 1 fi @@ -136,14 +129,11 @@ if ! [[ $NO_CHECK ]]; then sha512sum -c sha512sum.txt fi -dd status=progress if=root.verity.img of=/dev/disk/by-partlabel/ver${NEW_ROOT_NUM} -dd status=progress if=root.squashfs.img of=/dev/disk/by-partlabel/root${NEW_ROOT_NUM} +dd status=progress if=root.img of=/dev/disk/by-partlabel/root${NEW_ROOT_NUM} # set the new partition uuids ROOT_UUID=${ROOT_HASH:32:8}-${ROOT_HASH:40:4}-${ROOT_HASH:44:4}-${ROOT_HASH:48:4}-${ROOT_HASH:52:12} -HASH_UUID=${ROOT_HASH:0:8}-${ROOT_HASH:8:4}-${ROOT_HASH:12:4}-${ROOT_HASH:16:4}-${ROOT_HASH:20:12} - -sfdisk --part-uuid ${ROOT_DEV} ${VER_PARTNO} ${HASH_UUID} + sfdisk --part-uuid ${ROOT_DEV} ${ROOT_PARTNO} ${ROOT_UUID} # install to /efi