diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..37e842f --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.zst +*.gz +src +pkg diff --git a/README.md b/README.md index 7d12362..6bb2a94 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,19 @@ Requirements - efibootmgr - grub (grub-efi on Debian based distributions) +On Arch Linux, there is a [AUR package cryptboot](https://aur.archlinux.org/packages/cryptboot). + Installation ------------ +0. Before you enroll your own keys, you can backup the ones which are currently deployed +```bash +efi-readvar -v PK -o old_PK.esl +efi-readvar -v KEK -o old_KEK.esl +efi-readvar -v db -o old_db.esl +efi-readvar -v dbx -o old_dbx.esl +``` + 1. Install your favorite Linux distribution with separate `/boot` partition encrypted with LUKS. Refer to your distributions documentation, there is e.g. guide for Arch Linux: @@ -79,6 +89,7 @@ After installation, usage of `cryptboot` is as simple as running: This will mount `/boot` partition and EFI System partition, properly upgrade your system with distributions package manager, update and sign GRUB boot loader and finally unmount `/boot` partition and EFI System partition. +We hook the call to `grub-install` by putting a simple `grub-install` script into `/usr/local/bin` to call `cryptboot update-grub`. This will prevent failing to boot if someone (or a script) calls `grub-install` without signing the bootloader afterwards. Help @@ -138,8 +149,8 @@ Help # Command run to upgrade system packages PKG_UPGRADE_CMD="pacman -Syu" -Limitations ------------ + +## Limitations - If there is backdoor in your UEFI firmware, you are out of luck. It is *GAME OVER*. @@ -182,3 +193,19 @@ Limitations The question is if this is really needed? If you don't trust UEFI firmware, why should you trust TPM? But nevertheless it would be nice to have double-check against evil maids. + +## Further reading + +- Encrypted boot partition (GRUB) - https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#Encrypted_boot_partition_(GRUB) +- UEFI (Secure_Boot) - https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot +- How to boot Linux using UEFI with Secure Boot? - https://ubs_csse.gitlab.io/secu_os/tutorials/linux_secure_boot.html + +## Fixing: error: verification requested but nobody cares: (cryptouuid/$PARTITION_UUID)/grub/x86_64-efi/normal.mod + +This occurs during boot after upgrading to grub2 2.06. The fix is to add `--modules="tpm" and --disable-shim-lock)` as parameters to `grub-install`. Unfortunately it's not clear why it's needed (as we don't use TPM or shim). Further reading about this topic: + +- https://www.mail-archive.com/bug-grub@gnu.org/msg17008.html +- https://bugs.archlinux.org/task/71382 +- https://bbs.archlinux.org/viewtopic.php?id=267944 +- https://github.com/archlinux/svntogit-packages/commit/4144617d6ee4aa52d27f4b84c977a413f2e860fe#diff-3e341d2d9c67be01819b25b25d5e53ea3cdf3a38d28846cda85a195eb9b7203a +- https://wejn.org/2021/09/fixing-grub-verification-requested-nobody-cares/ diff --git a/PKGBUILD b/contrib/PKGBUILD similarity index 66% rename from PKGBUILD rename to contrib/PKGBUILD index 2d91044..d5858d1 100644 --- a/PKGBUILD +++ b/contrib/PKGBUILD @@ -1,18 +1,21 @@ +# Maintainer: kmille # Maintainer: Michal Krenek (Mikos) pkgname=cryptboot -pkgver=1.1.0 +pkgver=1.2.0 pkgrel=1 pkgdesc="Encrypted boot partition manager with UEFI Secure Boot support" arch=('any') url="https://github.com/xmikos/cryptboot" license=('GPL3') depends=('cryptsetup' 'grub' 'efibootmgr' 'efitools' 'sbsigntools') -source=(https://github.com/xmikos/cryptboot/archive/v$pkgver.tar.gz) +source=(https://github.com/kmille/cryptboot/archive/refs/tags/v$pkgver.tar.gz) +sha256sums=('53863e54be9bcd6bd47ad05b5c0afbcaae139d590106ef098da275adb86f46e6') package() { cd "$srcdir/$pkgname-$pkgver" install -Dm755 cryptboot "$pkgdir/usr/bin/cryptboot" install -Dm755 cryptboot-efikeys "$pkgdir/usr/bin/cryptboot-efikeys" + install -Dm755 grub-install "$pkgdir/usr/local/bin/grub-install" install -Dm644 cryptboot.conf "$pkgdir/etc/cryptboot.conf" } diff --git a/cryptboot b/cryptboot index 977d325..7d9338c 100755 --- a/cryptboot +++ b/cryptboot @@ -1,35 +1,5 @@ #!/bin/bash -# Parse cryptsetup device from /etc/crypttab -find_crypt_dev() { - crypt_name="$1" - while read -r line || [[ -n "$line" ]]; do - line="$(echo "$line" | sed 's/\s\+/\t/g')" - line_crypt_name="$(echo "$line" | cut -f 1)" - line_crypt_dev="$(echo "$line" | cut -f 2)" - if [[ "$line_crypt_name" = "$crypt_name" ]]; then - echo "$line_crypt_dev" - return 0 - fi - done < /etc/crypttab - return 1 -} - -# Remove EFI boot manager entries by label -remove_efi_boot_entry() { - entry_label="$1" - efi_boot_entries="$(efibootmgr)" - while read -r line || [[ -n "$line" ]]; do - if [[ $line =~ ^Boot([0-9A-F]+)\*?[[:blank:]]+(.+)$ ]]; then - line_entry_num="${BASH_REMATCH[1]}" - line_entry_label="${BASH_REMATCH[2]}" - if [[ "$entry_label" = "$line_entry_label" ]]; then - efibootmgr -q -b "$line_entry_num" -B - fi - fi - done <<< "$efi_boot_entries" -} - # Check if user is root if [[ $UID -ne 0 ]]; then echo "Permission denied (you must be root)" @@ -57,12 +27,19 @@ fi # Get path to cryptboot-efikeys executable EFIKEYS_BIN="$(which cryptboot-efikeys 2>/dev/null)" || EFIKEYS_BIN="$SRCDIR/cryptboot-efikeys" -# Check if cryptsetup boot device exists -BOOT_CRYPT_DEV="$(find_crypt_dev "$BOOT_CRYPT_NAME")" -if [[ -z "$BOOT_CRYPT_DEV" ]]; then - echo "Couldn't find cryptsetup device name '$BOOT_CRYPT_NAME', check your /etc/crypttab" - exit 1 -fi +find_crypt_dev() { + crypt_name="$1" + while read -r line || [[ -n "$line" ]]; do + line="$(echo "$line" | sed 's/\s\+/\t/g')" + line_crypt_name="$(echo "$line" | cut -f 1)" + line_crypt_dev="$(echo "$line" | cut -f 2)" + if [[ "$line_crypt_name" = "$crypt_name" ]]; then + echo "$line_crypt_dev" + return 0 + fi + done < /etc/crypttab +} + # Check if /boot mountpoint exists if ! findmnt -sn "$BOOT_DIR" &>/dev/null; then @@ -84,6 +61,12 @@ case "$1" in exit 1 fi + BOOT_CRYPT_DEV="$(find_crypt_dev "$BOOT_CRYPT_NAME")" + if [[ -z "$BOOT_CRYPT_DEV" ]]; then + echo "Couldn't find cryptsetup device name '$BOOT_CRYPT_NAME', check your /etc/crypttab" + exit 1 + fi + echo "Unlocking encrypted boot partition..." cryptsetup open "$BOOT_CRYPT_DEV" "$BOOT_CRYPT_NAME" @@ -113,7 +96,7 @@ case "$1" in grub-mkconfig -o "$BOOT_DIR/grub/grub.cfg" echo "Reinstalling GRUB to EFI System partition..." - grub-install --target=x86_64-efi --boot-directory="$BOOT_DIR" --efi-directory="$EFI_DIR" --bootloader-id="$EFI_ID_GRUB" + /usr/bin/grub-install --target=x86_64-efi --boot-directory="$BOOT_DIR" --efi-directory="$EFI_DIR" --bootloader-id="$EFI_ID_GRUB" --modules="tpm" --disable-shim-lock echo "Signing GRUB with UEFI Secure Boot keys..." "$EFIKEYS_BIN" sign "$EFI_DIR/$EFI_PATH_GRUB" diff --git a/grub-install b/grub-install new file mode 100755 index 0000000..20cfb5c --- /dev/null +++ b/grub-install @@ -0,0 +1,8 @@ +#!/bin/bash +set -eu + +# this will +# 1) call grub-mkconfig +# 2) call grub-install +# 3) sign the bootloader +cryptboot update-grub