The goal of this project is to reduce the harm a successful attacker can do to a system. It prevents an attacker of persistently modifying the root-filesystem. This gets accomplished via building a chain-of-trust based on UEFI secure boot. The system-firmware verifies the signature of the UKI (unified-kernel-image). The UKI verifies the squashfs-rootfs via dm-verity. On boot you can choose to boot the squashfs with a tmpfs overlay. You start with the system you signed the last time and changes are discarded on power off. So if you reboot in the tmpfs variant, the system is in a state you signed before and the modifications in the time between by an attacker are gone. You can also boot in persistent mode, which loads changes from disk and saves them to the disk.
This project also provides A/B-style update support. The current booted files (GKI and squashfs) won't be overridden on updates, so you can boot an old known-good image if there are problems). The squashfs images are stored on the configured root-partition, so they will still be encrypted, if encryption of the root image is configured.
verity-squash-root --ignore-warnings create-keys
/etc/fstab
./mnt/root
./mnt/root
and configure it in fstab file.EXCLUDE_DIRS
)/mnt/root/...
verity-squash-root --ignore-warnings setup systemd
verity-squash-root --ignore-warnings build
/etc/verity_squash_root/public_keys.tar
.verity-squash-root build
Make yourself familiar with the process of creating, installing and using custom Secure Boot keys. See:
After you have generated your custom keys:
cd to/your/keys/directory
tar cf keys.tar db.key db.crt
age -p -e -o keys.tar.age keys.tar
mv keys.tar.age /etc/verity_squash_root/
rm keys.tar
The config file is located at /etc/verity_squash_root/config.ini
.
These config options are available:
DEFAULT
CMDLINE
: configures kernel cmdline, if not configured,
fallback to /etc/kernel/cmdline
.EFI_STUB
: path to efi stub, default is the one provided by systemd.DECRYPT_SECURE_BOOT_KEYS_CMD
: Command to decrypt your secure-boot keys
tarfile, {} will be replaced with the output tar file. db.key
and db.crt
in the tarfile are used to sign the efi binaries.EXCLUDE_DIRS
: These directories are not included in the squashfs image.
EFI_PARTITION
and ROOT_MOUNT
are excluded automatically.EFI_PARTITION
: Path to your efi partition. Efi binaries and systemd-boot
configuration files are stored there.ROOT_MOUNT
: Path to your "original" root partition.IGNORE_KERNEL_EFIS
: Which efi binaries are not built. You can use the
list
parameter to show which can exist and which are excluded already.EXTRA_SIGN
You can specify files to be signed when running with the sign_extra_files
command. The format is:
NAME = SOURCE_PATH => DESTINATION_PATH
e.g. to sign the systemd-boot efi files:
[EXTRA_SIGN]
systemd-boot = /usr/lib/systemd/boot/efi/systemd-bootx64.efi => /boot/efi/EFI/systemd/systemd-bootx64.efi
Be careful to not specify files from untrusted sources, e.g. the ESP partition. An attacker could exchange these files.
Currently Arch Linux and Debian are supported with mkinitcpio and dracut. Mkinitcpio is only supported, if it is used with systemd-hooks.
To list all efi images, which will be created or ignored via
IGNORE_KERNEL_EFIS
:
verity-squash-root list
To install systemd-boot and create a UEFI Boot Manager entry for it:
verity-squash-root setup systemd
To add efi files to the UEFI Boot Manager with /dev/sda1 as EFI partition:
verity-squash-root setup uefi /dev/sda 1
To build a new squashfs image and efi files:
verity-squash-root build
If you are not yet booted in a verified image, you need --ignore-warnings
,
since there will be a warning if the root image is not fully verified.
The following files will be used on your root-partition:
Images with verity info:
image_a.squashfs
, image_a.squashfs.verity
,image_b.squashfs
image_b.squashfs.verity
Overlayfs directories:
overlay
workdir
age (only when used for decryption of secure-boot keys)
binutils
cryptsetup-bin
efitools
python
sbsigntool
squashfs-tools
systemd-boot-efi (only when no other efi-stub is configured)
tar
python-pyflakes
python-pycodestyle
Setup a python3 virtual environment:
git clone git@github.com:brandsimon/verity-squash-root.git
python3 -m venv .venv
.venv/bin/pip install -e . --no-deps
Run unit tests:
sudo mkdir -p /etc/mkinitcpio.d # Otherwise mkinitcpio test will fail
.venv/bin/python -m unittest tests/unit/tests.py