use single image for squashfs and dmverity

This commit is contained in:
Harald Hoyer 2018-09-11 16:47:20 +02:00
parent 7e93df54b4
commit 1dc7a0fae6
11 changed files with 149 additions and 88 deletions

13
10verity/module-setup.sh Executable file
View file

@ -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"
}

78
10verity/verity-generator Executable file
View file

@ -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=( $(</proc/cmdline) )
# Usage: cmdline_arg name default_value
cmdline_arg() {
local name="$1" value="$2"
for arg in "${cmdline[@]}"; do
if [[ "${arg%%=*}" == "${name}" ]]; then
value="${arg#*=}"
fi
done
echo "${value}"
}
UNIT_DIR="${1:-/tmp}"
root=$(cmdline_arg verity.root)
roothash=$(cmdline_arg verity.roothash)
hashoffset=$(cmdline_arg verity.hashoffset)
case "${root}" in
LABEL=*)
root="$(echo $root | sed 's,/,\\x2f,g')"
root="/dev/disk/by-label/${root#LABEL=}"
;;
UUID=*)
root="${root#UUID=}"
root="/dev/disk/by-uuid/${root,,}"
;;
PARTUUID=*)
root="${root#PARTUUID=}"
root="/dev/disk/by-partuuid/${root,,}"
;;
PARTLABEL=*)
root="/dev/disk/by-partlabel/${root#PARTLABEL=}"
;;
esac
# Only proceed if the source is a path.
if [[ "${root}" != /* ]]; then
exit 0
fi
# Only generate the service if we have sufficient parameters.
if [[ -n "${root}" && -n "${roothash}" ]]; then
device=$(systemd-escape --suffix=device --path "${root}")
cat >"${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

View file

@ -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

View file

@ -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

View file

@ -2,7 +2,6 @@
JSON="$(realpath -e $1)"
BASEDIR="${JSON%/*}"
IMAGE="${BASEDIR}/$(jq -r '.name' ${JSON})-$(jq -r '.version' ${JSON})"
(

View file

@ -76,6 +76,9 @@ libvirt-daemon-config-network
libvirt-daemon-kvm
squashfs-tools
mc
veritysetup
rsync
pesign
nss-tools
gnu-efi-devel
sbsigntools

View file

@ -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

View file

@ -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" \
@ -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" <<EOF
{
"roothash": "$ROOT_HASH",
"name" : "${NAME}",
"rootsize": "$ROOT_SIZE",
"name" : "${NAME}",
"version" : "${VERSION_ID}"
}
EOF

View file

@ -39,9 +39,11 @@ sed -i -e 's#/etc/.pwdXXXXXX#/var/.pwdXXXXXX#g' "$sysroot"/usr/lib64/security/pa
sed -i -e 's#/etc/passwd#/var/passwd#g;s#/etc/shadow#/var/shadow#g;s#/etc/gshadow#/var/gshadow#g;s#/etc/group#/var/group#g;s#/etc/subuid#/var/subuid#g;s#/etc/subgid#/var/subgid#g' "$sysroot"/usr/sbin/user{add,mod,del} "$sysroot"/usr/sbin/group{add,mod,del}
sed -i -e 's#/etc/.pwd.lock#/var/.pwd.lock#g' \
"$sysroot"/lib*/libc.so.* \
"$sysroot"/usr/lib*/librpmostree-1.so.1 \
"$sysroot"/usr/lib/systemd/libsystemd-shared*.so
[[ -e "$sysroot"/usr/lib*/librpmostree-1.so.1 ]] \
&& sed -i -e 's#/etc/.pwd.lock#/var/.pwd.lock#g' \
"$sysroot"/usr/lib*/librpmostree-1.so.1
mkdir -p "$sysroot"/usr/share/factory/home
cp -avxr "$sysroot"/etc/skel "$sysroot"/usr/share/factory/home/admin

View file

@ -31,7 +31,9 @@ getuint () {
squashfs_size() {
size=$(for i in {1..20}; do getword >/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

View file

@ -68,14 +68,11 @@ 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
if ! [[ $NEW_ROOT_NUM ]]; then
@ -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