Wiki - https://fedoraproject.org/wiki/Changes/Grub2LightForConfidentialComputing Discussion thread - https://discussion.fedoraproject.org/t/f45-change-proposal-grub-efi-for-confidential-computing-self-contained/193574 This is a proposed Change for Fedora Linux. This document represents a proposed Change. As part of the Changes process, proposals are publicly announced in order to receive community feedback. This proposal will only be implemented if approved by the Fedora Engineering Steering Committee. == Summary == An independent separate incarnation (package) of the GRUB bootloader for UEFI only that contains a minimal number of built-in modules, and can quickly boot a Unified Kernel Image (UKI) using Bootloader Specification (BLS) files. It will be built separately from the main GRUB package, and does not replace it for general usage. == Owner == * Name: [[User:lsandova| Leo Sandoval]] | lsandova@redhat.com * Name: [[User:mlewando| Marta Lewandowska]] | mlewando@redhat.com == Detailed Description == There is a need for a smaller, lighter version of the GRUB bootloader on UEFI to support booting sealed bootable container images, such as for Confidential Computing. Since confidential VMs rely on remote attestation, TPM PCR values need to be stable and predictable over long periods of time. Updating the bootloader results in changes to PCRs, and should therefore be avoided if possible. Additionally, Unified Kernel Images (UKIs) have become the preferred choice over the regular signed kernel because the whole payload is bundled and signed for Secure Boot, thus removing the vulnerability of the unsigned initramfs. They are used often in virtual environments, for confidential computing, and by CoreOS. Taken together, the ideal bootloader for these types of environments should be small, light, and not get updated too often. The fewer modules are built-in, the smaller the attack surface, and the less frequent updates need to be. The resulting idea is to create a smaller version of GRUB, the supported bootloader in most Linux environments, for UEFI, which is built as a separate package from the main GRUB build, contains only the modules that are absolutely necessary for VMs, and natively supports UKI loading. This new package is not meant to be a replacement for GRUB for general use; rather it's an additional package for specific applications. A separate rpm that is still a part of the grub2 build is already available for [https://kojipkgs.fedoraproject.org//packages/grub2/2.12/60.fc45/x86_64/grub2-efi-x64-cc-2.12-60.fc45.x86_64.rpm x86_64] and [https://kojipkgs.fedoraproject.org//packages/grub2/2.12/60.fc45/aarch64/grub2-efi-aa64-cc-2.12-60.fc45.aarch64.rpm aarch64] in Fedora Rawhide for testing. It is signed for Secure Boot with the GRUB key. In the future, it is expected to get its own Secure Boot signing key. Work is in progress to add support for this new build of GRUB in bootupd to enable safe bootloader updates on bootable container systems: https://github.com/coreos/bootupd/issues/1080 == Feedback == The original idea was to use systemd-boot for this application, but this was rejected for a number of reasons: * While the systemd team can support sd-boot in its present form, they view any additional features as a no-go * Although sd-boot is a light and trivial bootloader, it has not been widely tested or fuzzed, like GRUB has been * Long term maintenance of more than one bootloader would result in a lack of parity and added technical debt * Potential expansion to other architectures would necessitate a compatible bootloader anyway. The new lighter GRUB build is already being tested by CoreOS, and is generally working as expected. Small changes are still being made, and suggestions for changes are welcome. == Benefit to Fedora == This change will create a minimal UEFI bootloader for virtual environments that can further be tailored for use in those environments. It will natively load UKIs, support Secure Boot, and be a part of a robust and tested bootloader used in many Linux environments. == Scope == * Proposal owners: The bootloader engineering team needs to create a new GRUB package, separate from the core package that includes all the changes mentioned. * Other developers: CoreOS, who will be the main users, at least in the beginning, need to test, provide feedback, and perhaps change some of their workflows as needed. * Release engineering: [https://forge.fedoraproject.org/releng/tickets/issues #Releng issue number] * Policies and guidelines: N/A (not needed for this Change) * Trademark approval: N/A (not needed for this Change) * Alignment with the Fedora Strategy: == Upgrade/compatibility impact == This is a new package, independent of the normal all-purpose GRUB, so unless a user installs it on purpose, there is no compatibility impact. == Early Testing (Optional) == This new package is designed specifically for VMs that run UEFI firmware, so an x86_64 or aarch64 VM is the environment to use. ===Prepare the test environment:=== * Install or create one or more UKIs ** Install `kernel-uki-virt` and add a command line addon using `ukify`, see instructions below ** Use `ukify` to create the UKI from scratch, see instructions below * If booting with Secure Boot enabled, sign your add-on or UKI, and enroll your public key in the MOK, see instructions below.<br> '''If you will not sign your UKI/addon, don't forget to disable Secure Boot.''' * Create the `/boot/efi/loader/entries` directory * Create BLS entries in that directory for each UKI. Specify the path to the UKI using the `efi` keyword, as you normally would use `linux` for the kernel. A minimal BLS file only needs to have a title and the path to the UKI: <pre> # cat /boot/efi/loader/entries/7.0.10-200-UKI.fc45.x86_64.conf title Fedora 45 UKI (7.0.10-200.fc45.x86_64) efi /EFI/Linux/7.0.10-200.fc45.x86_64.efi </pre> === (If you don't feel like doing all of that, you can boot regular kernels instead): === Because this version of GRUB is intended for UKIs, it expects those UKIs to be on the EFI system partition, but it can load a regular kernel too, as long as it's in the correct place. If you copy a kernel and its initrd from `/boot` to `/boot/efi/EFI/Linux` and that kernel's BLS configuration file from `/boot/loader/entries` to `/boot/efi/loader/entries` (and edit it to reflect the correct paths), then it should simply boot as usual. === Test: === * Download the [https://kojipkgs.fedoraproject.org//packages/grub2/2.12/60.fc45/x86_64/grub2-efi-x64-cc-2.12-60.fc45.x86_64.rpm grub2-efi-x64-cc rpm], unpack it, and replace your regular grub efi with it: <pre> # cp ./usr/lib/efi/grub2/1\:2.12-60.fc45/EFI/fedora/cc/grubx64-cc.efi /boot/efi/EFI/fedora/grubx64.efi </pre> * Reboot your machine You should see the GRUB menu with entries for each of the UKIs that you installed. If you press 'e' to edit an entry, you should see something like `chainloader /path/to/UKI` and when you execute any of the entries, they should successfully boot. You can check the size of the efi, and see that it is smaller than the normal grubx64.efi. Use the `tpm2_pcrread` command between reboots of different UKIs to see that the value of PCR8 does not change. ==== How to build your own UKI addon ==== The generic UKI that fedora ships has only `console=tty0 console=ttyS0` on its kernel command line. In order for it to actually boot on your system, it needs more information, like the root filesystem UUID, which you can see if you `# cat /proc/cmdline`. Since the UKI already has the command line bundled, you need to create a command line addon containing the additional information. You can do this using the [https://www.man7.org/linux/man-pages//man1/ukify.1.html ukify] command. First get the generic UKI by installing `kernel-virt-uki` and the command by installing `systemd-ukify`. Then something like this should work: <pre> # ukify build \ -cmdline "$(cat /proc/cmdline | cut -d' ' -f2-6)" \ --output set_root.unsigned.addon.efi </pre> You then need to copy the addon to the UKI's extra.d directory in `/boot/efi/EFI/Linux/` if you want to only apply it to a single UKI, or create `/boot/efi/loader/addons/` and copy it there, if you want it to work for all UKIs. (If you are planning to sign the addon, wait to move it until after you have signed it.) ==== How to build your own UKI ==== You can build your own UKI using kernels and initrds that you already have installed on your system once you have also installed `systemd-ukify`. Building one for the running kernel using the [https://www.man7.org/linux/man-pages//man1/ukify.1.html ukify] command, looks like this: <pre> # ukify build \ --linux /usr/lib/modules/$(uname -r)/vmlinuz \ --initrd /boot/initramfs-$(uname -r).img \ --uname $(uname -r) \ --cmdline "$(cat /proc/cmdline | cut -d' ' -f2-6)" \ --output kernel-$(uname -r | rev | cut -d'.' -f3-6 | rev)-UKI.efi \ --profile "kernel $(uname -r | rev | cut -d'.' -f3-6 | rev) UKI (Fedora $(cat /etc/os-release | grep VERSION_ID | sed -e 's/VERSION_ID=//g'))" </pre> You then need to copy the UKI to the correct directory. Typically this is `/boot/efi/EFI/Linux/` but can be the directory of your choosing, as long as you specify that in the UKI's BLS file. (If you are planning to sign the UKI, wait to move it until after you have signed it.) ==== How to sign for Secure Boot ==== It's actually possible to sign your UKI or addon during the ukify build, but this more generic procedure can be used to sign any artifact for Secure Boot. Install `openssl` and `pesign` and generate your signing key: <pre> # openssl req -quiet -newkey rsa:4096 -nodes \ -keyout custom_db.key -new -x509 -sha256 -days 3650 \ -subj "/CN=UKI Signing key/" \ --outform DER -out custom_db.der </pre> In this case the key size is 4096 bit, uses [https://en.wikipedia.org/wiki/RSA_cryptosystem RSA] for encryption, and can be used for signing for 10 years. Import the public key into the NSS database that `pesign` uses and give it a nickname: <pre> # certutil -A -t ",," -d /etc/pki/pesign -n \ 'My Secureboot Signer' -i custom_db.der </pre> Convert the public and private keys to PKCS12 format and import the result to enable signing using `pesign`: <pre> # openssl pkcs12 -export -out custom_db.pfx \ -inkey custom_db.key -in custom_db.der </pre> <pre> # pk12util -i custom_db.pfx \ -d/etc/pki/pesign -n 'My Secureboot Signer' </pre> Sign your UKI or addon with your private key: <pre> # pesign --certificate 'My Secureboot Signer' \ --in set_root.unsigned.addon.efi \ --out set_root.addon.efi --sign </pre> Move or copy the UKI or addon to the proper directory, see above. Import your public key into the Machine Owner Key (MOK) database: <pre> # mokutil --import custom_db.der </pre> You will be asked to create a password. You need to reboot the machine to complete the enrollment, and you will be asked for this password at that time. After rebooting, you can check that your key is actually in the MOK database: <pre> # mokutil --list-enrolled </pre> == Dependencies == N/A as this is a new package. == Documentation == N/A (not a System Wide Change) or to be determined. == Release Notes == To be determined. -- Aoife Moloney Fedora Operations Architect Fedora Project Matrix: @amoloney:fedora.im IRC: amoloney -- _______________________________________________ devel-announce mailing list -- devel-announce@lists.fedoraproject.org To unsubscribe send an email to devel-announce-leave@lists.fedoraproject.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/devel-announce@lists.fedoraproject.org Do not reply to spam, report it: https://forge.fedoraproject.org/infra/tickets/issues/new
No comments:
Post a Comment