brandsimon / verity-squash-root

Build signed efi binaries which mount a dm-verity verified squashfs image as rootfs on boot.
MIT License
23 stars 4 forks source link
dm-verity secure-boot security squashfs

verity-squash-root

Build signed efi binaries which mount a dm-verity verified squashfs image as rootfs on boot.

Install - Configuration - Usage - Development

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.

What happens on boot?

Install

Updates

Using custom keys

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

Configuration

The config file is located at /etc/verity_squash_root/config.ini. These config options are available:

Section DEFAULT

Section 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.

Supported setups

Currently Arch Linux and Debian are supported with mkinitcpio and dracut. Mkinitcpio is only supported, if it is used with systemd-hooks.

Considerations / Recommendations

Usage

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.

Files

The following files will be used on your root-partition:

Images with verity info:

Overlayfs directories:

Development

Dependencies

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

Development

python-pyflakes
python-pycodestyle

Setup

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

Related resources