In one of my custom linux distors I use a read-only version of the Ubuntu operating system. So, a normal install was copied and compressed into a squashfs image and then dd
-ed onto the partition.
It's possible to verify the integrity of that image very quickly during boot with verity.
Verity
Before we start, here's an important note that may change your objective and you may not need to all the future steps with altering the initramfs.
Note: dm-verity is possible without initramfs if the kernel supports it. (Reference. Check it with
grep CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG .config
# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set
And now, let's proceed with integrating the verity check
- Install
cryptsetup
package (includesveritysetup
) on the host system
sudo apt update
sudo apt install cryptsetup-bin
- Add
dm-verity
kernel module to /etc/initramfs-tools/modules
dm-verity
- Tell
initramfs-tools
to packveritysetup
into the image. Create a file /etc/initramfs-tools/hooks/veritysetup
# !/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
# Include veritysetup
copy_exec /sbin/veritysetup /sbin
exit 0
- When a kernel with the appropriate modules will be loaded, the
init
script start executing scripts. Let's define our script that is going to verify the intergrity of the OS. We will use the open operation for in-kernel verification.
mkdir -p /etc/initramfs-tools/scripts
nano /etc/initramfs-tools/scripts/local-top/verity
chmod +x /etc/initramfs-tools/scripts/local-top/verity
/etc/initramfs-tools/scripts/local-top/verity
# !/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
. /scripts/functions
# Open the root partition with veritysetup
ROOT_DEV=""
VERITY_DEV=""
VERITY_HASH=""
for x in $(cat /proc/cmdline); do
case ${x} in
systemd.verity_root_data=*)
value=${x#*=}
ROOT_DEV=/dev/disk/by-uuid/${value#UUID=}
;;
systemd.verity_root_hash=*)
value=${x#*=}
VERITY_DEV=/dev/disk/by-uuid/${value#UUID=}
;;
roothash=*)
VERITY_HASH=${x#*=}
;;
esac
done
[ -b "$ROOT_DEV" ] || panic "Unable to determine root device."
[ -b "$VERITY_DEV" ] || panic "Unable to find verity device."
[ -n "$VERITY_HASH" ] || panic "No verity hash."
veritysetup open "$ROOT_DEV" rootfs "$VERITY_DEV" "$VERITY_HASH"
[ -b /dev/mapper/rootfs ] || panic "Verity did not map rootfs."
exit 0
Be carefull and pay attention that veritysetup
!= systemd-veritysetup
. systemd version uses the attach command (man
- Now we are ready to repack the image
update-initramfs -k $(uname -r) -u
Reference
- A tutorial for Ubuntu 18.04
- Add programs to init fs
- Add programs #2 - cryptsetup
dm-verity
- Verified boot specification by Chromium project
- dm-verity on Arch wiki
- cryptsetup FAQ on gitlab
- veritytab manpage