-
Notifications
You must be signed in to change notification settings - Fork 991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes #36834 - Add SecureBoot support for arbitrary operating systems to "Grub2 UEFI" PXE loaders #9864
base: develop
Are you sure you want to change the base?
Conversation
Can one of the admins verify this patch? |
2 similar comments
Can one of the admins verify this patch? |
Can one of the admins verify this patch? |
I have opened a PR to document this feature in foreman-documentation: |
This PR also requires the changes from Foreman Smart Proxy PR #877 |
Hi there, The other thing I was investigating is why the Any thoughts or objections? |
Hey there, What do you think, @ekohl? And I just saw, that there are some failing tests. 😅 I'll do that ASAP. |
Hey @ekohl, But we definitely require some feedback, weather this PR is going in the right direction and regarding the Smart Proxy capability (see my question above). Thanks! |
Hi there, What's left to do for now:
@sbernhard @ekohl What do you think? Please share your thoughts. I'm looking forward to input and discussion. |
The assumption was that `exit 1` in GRUB2 triggers a boot from the next bootdevice by the firmware and that the `chainloader` command is not working at all when SecureBoot is enabled (`lockdown=y`). These assumptions seems to be wrong. It looks like that distribution vendors patch GRUB2 differently which results in different behavior affecting these assumptions. Some support `chainloader` command, some do simply end up in the BIOS menu when using `exit 1`. As an alternative we can do a "chainload light" and only load the GRUB2 configuration file from local disk. This means that the PXE booted GRUB2 boots the actual kernel from local disk. For successful SecureBoot verification, the following changes are required: #9864 The proposed solution would also work when SecureBoot is disabled, however to avoid side effects I propose to only boot next device if SecureBoot is enabled (GRUB2 variable `lockdown=y` [2]).
See discussion in smart-proxy PR for information on recent changes. |
Affects "Grub2 UEFI" PXE loaders * PR in foreman: theforeman/foreman#9864 * PR in smart-proxy: theforeman/smart-proxy#877 * RFC: https://community.theforeman.org/t/add-secureboot-support-for-arbitrary-distributions/32601/1
Affects "Grub2 UEFI" PXE loaders * PR in foreman: theforeman/foreman#9864 * PR in smart-proxy: theforeman/smart-proxy#877 * RFC: https://community.theforeman.org/t/add-secureboot-support-for-arbitrary-distributions/32601/1
The assumption was that `exit 1` in GRUB2 triggers a boot from the next bootdevice by the firmware and that the `chainloader` command is not working at all when SecureBoot is enabled (`lockdown=y`). These assumptions seems to be wrong. It looks like that distribution vendors patch GRUB2 differently which results in different behavior affecting these assumptions. Some support `chainloader` command, some do simply end up in the BIOS menu when using `exit 1`. As an alternative we can do a "chainload light" and only load the GRUB2 configuration file from local disk. This means that the PXE booted GRUB2 boots the actual kernel from local disk. For successful SecureBoot verification, the following changes are required: theforeman#9864 The proposed solution would also work when SecureBoot is disabled, however to avoid side effects I propose to only boot next device if SecureBoot is enabled (GRUB2 variable `lockdown=y` [2]).
… to "Grub2 UEFI" PXE loaders In the course of theforeman/foreman#9864 and theforeman/smart-proxy#877, SecureBoot support for arbitrary operating systems has been added to the "Grub2 UEFI" PXE loaders. This patch adds a new parameter 'bootloader_universe' to the TFTP configuration and a directory 'host_config' inside the TFTP root directory, that are both required by the aforementioned PRs.
Rebased to head of develop |
… to "Grub2 UEFI" PXE loaders In the course of theforeman/foreman#9864 and theforeman/smart-proxy#877, SecureBoot support for arbitrary operating systems has been added to the "Grub2 UEFI" PXE loaders. This patch adds a new parameter 'bootloader_universe' to the TFTP configuration and a directory 'host_config' inside the TFTP root directory, that are both required by the aforementioned PRs.
… to "Grub2 UEFI" PXE loaders In the course of theforeman/foreman#9864 and theforeman/smart-proxy#877, SecureBoot support for arbitrary operating systems has been added to the "Grub2 UEFI" PXE loaders. This patch adds the 'bootloader-universe' and 'host-config' directories inside the TFTP root, that are both required by the aforementioned PRs.
I renamed the |
… to "Grub2 UEFI" PXE loaders In the course of theforeman/foreman#9864 and theforeman/smart-proxy#877, SecureBoot support for arbitrary operating systems has been added to the "Grub2 UEFI" PXE loaders. This patch adds the 'bootloader-universe' and 'host-config' directories inside the TFTP root, that are both required by the aforementioned PRs.
… to "Grub2 UEFI" PXE loaders In the course of theforeman/foreman#9864 and theforeman/smart-proxy#877, SecureBoot support for arbitrary operating systems has been added to the "Grub2 UEFI" PXE loaders. This patch adds the 'bootloader-universe' and 'host-config' directories inside the TFTP root, that are both required by the aforementioned PRs.
See this comment for the latest update. |
While reviewing the changes again, I discovered further obsoleted changes in the |
Affects "Grub2 UEFI" PXE loaders * PR in foreman: theforeman/foreman#9864 * PR in smart-proxy: theforeman/smart-proxy#877 * RFC: https://community.theforeman.org/t/add-secureboot-support-for-arbitrary-distributions/32601/1
Affects "Grub2 UEFI" PXE loaders * PR in foreman: theforeman/foreman#9864 * PR in smart-proxy: theforeman/smart-proxy#877 * RFC: https://community.theforeman.org/t/add-secureboot-support-for-arbitrary-distributions/32601/1
Affects "Grub2 UEFI" PXE loaders * PR in foreman: theforeman/foreman#9864 * PR in smart-proxy: theforeman/smart-proxy#877 * RFC: https://community.theforeman.org/t/add-secureboot-support-for-arbitrary-distributions/32601/1
… to "Grub2 UEFI" PXE loaders This feature consists of four patches, one each for foreman, smart-proxy, foreman-installer, and puppet-foreman_proxy. This patch adds support for individual Network Bootstrap Programs (NBP) in order to enable network based installations of SecureBoot enabled hosts for arbitrary operating systems. SecureBoot expects to follow a chain of trust from the initial boot of the host to the loading of Linux kernel modules. The very first shim that is loaded determines which distribution is allowed to be booted or kexec'ed until next reboot. Currently the "Grub2 UEFI SecureBoot" PXE loaders use NBPs provided by the vendor of the Foreman/Smart Proxy host system. All hosts receive and execute the same binary. On SecureBoot enabled hosts, this limits installations to operating systems by the vendor of the Foreman/ Smart Proxy host system. Providing shim and GRUB2 by the vendor of the operating system to be installed allows Foreman to install any operating system on SecureBoot enabled hosts over network. To achieve this, the host's DHCP filename option is set to a shim/GRUB2 binary in a host specific directory based on their MAC address. Corresponding shim and GRUB2 binaries are copied into that directory along with the generated GRUB2 configuration files. When provisioning a host, the Smart Proxy checks in a dedicated directory inside the TFTP root - the so called "bootloader universe" - if NBPs are present matching the operating system, operating system version, and architecture of the host to be installed. If this is the case, these NBPs are copied from the bootloader universe directory to the host specific directory. If not, as a fallback the default NBPs provided by the vendor of the Foreman/Smart Proxy host system are copied from the `:tftproot:/grub2` directory to the host specific directory. Up to now, shim and GRUB2 binaries have to be retrieved and set up in the bootloader universe directory manually according to the documentation. An automatic way to provide OS dependent NBPs will be added in future. In case there are no NBPs present in the bootloader universe matching the operating system, operating system version, and architecture of the host to be installed, the behaviour of the "Grub2 UEFI" PXE loaders does not change to the behavior prior to this feature. Implementation notes: --------------------- * To be future proof (e.g. to be able to provide NBPs in the bootloader universe for other PXE loaders without running into any filename conflicts) and for better structure, the PXE kind is prepended as a first directory level inside the bootloader universe. * The operating system version inside the bootloader universe consists of the major and minor version (if applicable) of the operating system separated by a dot (`.`). If no NBPs are configured for a specific operating system version the fallback directory `default` is used. * To simplify things on Foreman side in future, symlinks are used for the shim (boot-sb.efi) and GRUB2 (boot.efi) binaries. * Inside the TFTP root directory a new directory `host-config` is created for storing all the host specific directories. * Inside the TFTP root directory a new directory `bootloader-universe` is created for storing all the OS specific boot files. * For storage efficiency the shim and GRUB2 binaries from the bootloader universe or the `:tftproot:/grub2` directory are symlinked to the host specific directory. Full example: ------------- [root@vm ~]# hammer host info --id 241 | grep -E "(MAC address|Operating System)" MAC address: 00:50:56:b4:75:5e Operating System: AlmaLinux 8.9 [root@vm ~]# tree /var/lib/tftpboot/bootloader-universe/ /var/lib/tftpboot/bootloader-universe/ └── pxegrub2 └── almalinux ├── 8.9 │ └── x86_64 │ ├── boot.efi -> grubx64.efi │ ├── boot-sb.efi -> shimx64.efi │ ├── grubx64.efi │ └── shimx64.efi └── default └── x86_64 ├── boot.efi -> grubx64.efi ├── boot-sb.efi -> shimx64.efi ├── grubx64.efi └── shimx64.efi [root@vm ~]# hammer host update --id 241 --build true [root@vm ~]# tree /var/lib/tftpboot/host-config /var/lib/tftpboot/host-config └── 00-50-56-a3-41-a8 └── grub2 ├── boot.efi -> ../../../bootloader-universe/grubx64.efi ├── boot-sb.efi -> ../../../bootloader-universe/shimx64.efi ├── grub.cfg ├── grub.cfg-00:50:56:a3:41:a8 ├── grub.cfg-01-00-50-56-a3-41-a8 ├── grubx64.efi -> ../../../bootloader-universe/grubx64.efi ├── os_info └── shimx64.efi -> ../../../bootloader-universe/shimx64.efi [root@vm ~]# grep -B2 00-50-56-b4-75-5e /var/lib/dhcpd/dhcpd.leases hardware ethernet 00:50:56:b4:75:5e; fixed-address 192.168.145.84; supersede server.filename = "host-config/00-50-56-b4-75-5e/grub2/boot-sb.efi"; [root@vm ~]# pesign -S -i /var/lib/tftpboot/host-config/00-50-56-b4-75-5e/grub2/boot-sb.efi | grep "Microsoft Windows UEFI Driver Publisher" The signer's common name is Microsoft Windows UEFI Driver Publisher
See this comment in the Smart Proxy PR regarding the recent changes. |
The assumption was that `exit 1` in GRUB2 triggers a boot from the next bootdevice by the firmware and that the `chainloader` command is not working at all when SecureBoot is enabled (`lockdown=y`). These assumptions seems to be wrong. It looks like that distribution vendors patch GRUB2 differently which results in different behavior affecting these assumptions. Some support `chainloader` command, some do simply end up in the BIOS menu when using `exit 1`. As an alternative we can do a "chainload light" and only load the GRUB2 configuration file from local disk. This means that the PXE booted GRUB2 boots the actual kernel from local disk. For successful SecureBoot verification, the following changes are required: theforeman#9864 The proposed solution would also work when SecureBoot is disabled, however to avoid side effects I propose to only boot next device if SecureBoot is enabled (GRUB2 variable `lockdown=y` [2]). (cherry picked from commit aca4023)
/packit build |
This feature consists of two patches, one for foreman and one for smart-proxy.
This patch introduces a new loader of kind
:PXEGrub2TargetOS
which allows to provide host-specific Network Bootstrap Programs (NPB) in order to enable network based installations for SecureBoot-enabled hosts.SecureBoot expects to follow a chain of trust from the start of the host to the loading of Linux kernel modules. The very first shim that is loaded basically determines which distribution is allowed to be booted or kexec'ed until next reboot.
The existing "Grub2 UEFI SecureBoot" is not sufficient as it limits the possible installations to the vendor of the Foreman (Smart Proxy) host system.
Providing shim and GRUB2 by the vendor of the to-be-installed operating system allows Foreman to install any operating system on SecureBoot-enabled hosts over network.
To achieve this, the host's DHCP filename option is set to a shim path in a directory that is host-specific (contains MAC address). Corresponding shim and GRUB2 binaries are copied into that directory along with the generated GRUB2 configuration files as we know from "Grub2 UEFI".
The required binaries must be provided once in the so called "bootloader universe". This directory can be configured via the settings file
/etc/foreman-proxy/settings.d/tftp.yml
and defaults to/usr/local/share/bootloader-universe/<os>/
. These binaries can be manually retrieved from the installation media and is not part of this patch set.Full example:
[root@vm ~]# hammer host info --id 241 | grep -E "(MAC address|Operating System)"
MAC address: 00:50:56:b4:75:5e
Operating System: Ubuntu 22.04 LTS
[root@vm ~]# tree /usr/local/share/bootloader-universe/ /usr/local/share/bootloader-universe/
|-- centos
| |-- grubx64.efi
|
-- shimx64.efi
-- ubuntu|-- grubx64.efi
`-- shimx64.efi
[root@vm ~]# hammer host update --id 241 --build true
[root@vm ~]# tree /var/lib/tftpboot/grub2/00-50-56-b4-75-5e/ /var/lib/tftpboot/grub2/00-50-56-b4-75-5e/
|-- grub.cfg
|-- grub.cfg-00:50:56:b4:75:5e
|-- grub.cfg-01-00-50-56-b4-75-5e
|-- grubx64.efi
|-- shimx64.efi
`-- targetos
[root@vm ~]# grep -B2 00-50-56-b4-75-5e /var/lib/dhcpd/dhcpd.leases
hardware ethernet 00:50:56:b4:75:5e;
fixed-address 192.168.145.84;
supersede server.filename = "grub2/00-50-56-b4-75-5e/shimx64.efi";
[root@vm ~]# pesign -S -i /var/lib/tftpboot/grub2/00-50-56-b4-75-5e/grubx64.efi | grep Canonical The signer's common name is Canonical Ltd. Secure Boot Signing (2021 v1)