Skip to content

Commit

Permalink
Add Secure Boot support for arbitrary Client OS
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan Löser authored and maximiliankolb committed Jul 16, 2024
1 parent eaf5e2c commit 429b413
Show file tree
Hide file tree
Showing 3 changed files with 230 additions and 6 deletions.
94 changes: 94 additions & 0 deletions guides/common/assembly_using-pxe-to-provision-hosts.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,99 @@ include::modules/proc_creating-hosts-with-pxeless-provisioning.adoc[leveloffset=

include::modules/proc_creating-hosts-with-uefi-http-boot-provisioning.adoc[leveloffset=+1]

ifndef::satellite[]
:extract_deb_prefix: cd /tmp && ar x /tmp
:extract_deb_xz_suffix: && tar -xf data.tar.xz && cd -
:extract_deb_zst_suffix: && tar --use-compress-program=unzstd -xf data.tar.zst && cd -
:extract_rpm_prefix: rpm2cpio /tmp
:extract_rpm_suffix: | cpio -idv --directory /tmp
:parent-client-os: {client-os}
:parent-client-pkg-ext: {client-pkg-ext}
:secureboot-os-name: My_Operating_System_In_Lowercase

:client-os-context: almalinux
:client-os: AlmaLinux
:client-pkg-ext: rpm
:grub_efi_download_url: https://repo.almalinux.org/almalinux/9/BaseOS/x86_64/os/Packages/
:grub_efi_downloaded_package_name: grub2-efi-x64.rpm
:grub_efi_package_name: grub2-efi-x64
:grub_efi_tmp_binary_path: /tmp/boot/efi/EFI/{client-os-context}/grubx64.efi
:shim_efi_download_url: https://repo.almalinux.org/almalinux/9/BaseOS/x86_64/os/Packages/
:shim_efi_downloaded_package_name: shim-x64.rpm
:shim_efi_package_name: shim-x64
:shim_efi_tmp_binary_path: /tmp/boot/efi/EFI/{client-os-context}/shimx64.efi
:extract_grub: {extract_rpm_prefix}/{grub_efi_downloaded_package_name} {extract_rpm_suffix}
:extract_shim: {extract_rpm_prefix}/{shim_efi_downloaded_package_name} {extract_rpm_suffix}
include::modules/proc_configuring-smart-proxy-to-provision-secure-boot-enabled-hosts.adoc[leveloffset=+1]

:client-os-context: debian
:client-os: Debian
:client-pkg-ext: deb
:grub_efi_download_url: http://security.debian.org/debian-security/pool/updates/main/g/grub-efi-amd64-signed/
:grub_efi_downloaded_package_name: grub-efi-amd64-signed.deb
:grub_efi_package_name: grub-efi-amd64-signed
:grub_efi_tmp_binary_path: /tmp/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed
:shim_efi_download_url: http://ftp.de.debian.org/debian/pool/main/s/shim-signed/
:shim_efi_downloaded_package_name: shim-signed.deb
:shim_efi_package_name: shim-signed
:shim_efi_tmp_binary_path: /tmp/usr/lib/shim/shimx64.efi.signed
:extract_grub: {extract_deb_prefix}/{grub_efi_downloaded_package_name} {extract_deb_xz_suffix}
:extract_shim: {extract_deb_prefix}/{shim_efi_downloaded_package_name} {extract_deb_xz_suffix}
include::modules/proc_configuring-smart-proxy-to-provision-secure-boot-enabled-hosts.adoc[leveloffset=+1]

:client-os-context: rocky
:client-os: Rocky Linux
:client-pkg-ext: rpm
:grub_efi_download_url: http://dl.rockylinux.org/pub/rocky/9/BaseOS/x86_64/os/Packages/g/
:grub_efi_downloaded_package_name: grub2-efi-x64.rpm
:grub_efi_package_name: grub2-efi-x64
:grub_efi_tmp_binary_path: /tmp/boot/efi/EFI/{client-os-context}/grubx64.efi
:shim_efi_download_url: http://dl.rockylinux.org/pub/rocky/9/BaseOS/x86_64/os/Packages/s/
:shim_efi_downloaded_package_name: shim-x64.rpm
:shim_efi_package_name: shim-x64
:shim_efi_tmp_binary_path: /tmp/boot/efi/EFI/{client-os-context}/shimx64.efi
:extract_grub: {extract_rpm_prefix}/{grub_efi_downloaded_package_name} {extract_rpm_suffix}
:extract_shim: {extract_rpm_prefix}/{shim_efi_downloaded_package_name} {extract_rpm_suffix}
include::modules/proc_configuring-smart-proxy-to-provision-secure-boot-enabled-hosts.adoc[leveloffset=+1]

:client-os-context: ubuntu
:client-os: Ubuntu
:client-pkg-ext: deb
:grub_efi_download_url: http://security.ubuntu.com/ubuntu/pool/main/g/grub2-signed/
:grub_efi_downloaded_package_name: grub-efi-amd64-signed.deb
:grub_efi_package_name: grub-efi-amd64-signed
:grub_efi_tmp_binary_path: /tmp/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed
:shim_efi_download_url: http://de.archive.ubuntu.com/ubuntu/pool/main/s/shim-signed/
:shim_efi_downloaded_package_name: shim-signed.deb
:shim_efi_package_name: shim-signed
:shim_efi_tmp_binary_path: /tmp/usr/lib/shim/shimx64.efi.signed.latest
:extract_grub: {extract_deb_prefix}/{grub_efi_downloaded_package_name} {extract_deb_zst_suffix}
:extract_shim: {extract_deb_prefix}/{shim_efi_downloaded_package_name} {extract_deb_xz_suffix}
include::modules/proc_configuring-smart-proxy-to-provision-secure-boot-enabled-hosts.adoc[leveloffset=+1]

// reset global attributes
:client-os: {parent-client-os}
:client-pkg-ext: {parent-client-pkg-ext}
:!client-os-context:
:!extract_deb_prefix:
:!extract_deb_xz_suffix:
:!extract_deb_zst_suffix:
:!extract_grub:
:!extract_rpm_prefix:
:!extract_rpm_suffix:
:!extract_shim:
:!grub_efi_download_url:
:!grub_efi_downloaded_package_name:
:!grub_efi_package_name:
:!grub_efi_tmp_binary_path:
:!parent-client-os:
:!parent-client-pkg-ext:
:!secureboot-os-name:
:!shim_efi_download_url:
:!shim_efi_downloaded_package_name:
:!shim_efi_package_name:
:!shim_efi_tmp_binary_path:
endif::[]

include::modules/proc_deploying-ssh-keys-during-provisioning.adoc[leveloffset=+1]
:!using-pxe-to-provision-hosts:
29 changes: 23 additions & 6 deletions guides/common/modules/con_using-pxe-to-provision-hosts.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,30 @@ For information about supported workflows, see https://access.redhat.com/solutio
endif::[]

In {Project} provisioning, the PXE loader option defines the DHCP `filename` option to use during provisioning.
For BIOS systems, use the *PXELinux BIOS* option to enable a provisioned node to download the `pxelinux.0` file over TFTP.
For UEFI systems, use the *PXEGrub2 UEFI* option to enable a TFTP client to download `grub2/grubx64.efi` file, or use the *PXEGrub2 UEFI HTTP* option to enable an UEFI HTTP client to download `grubx64.efi` from {SmartProxy} with the HTTP Boot feature.
ifndef::satellite[]
Use SecureBoot options to enable a client to download the `shim.efi` bootstrap bootloader that then loads the signed `grubx64.efi`.
Other PXE loaders like PXELinux UEFI, Grub2 ELF or iPXE Chain, require additional configuration. These workflows are not documented at the moment.
For BIOS systems, select the *PXELinux BIOS* option to enable a provisioned node to download the `pxelinux.0` file over TFTP.
For UEFI systems, select the *Grub2 UEFI* option to enable a TFTP client to download `grubx64.efi` file, or select the *Grub2 UEFI HTTP* option to enable an UEFI HTTP client to download `grubx64.efi` with the HTTP Boot feature.

ifndef::orcharhino,satellite[]
Other PXE loaders like *PXELinux UEFI*, *Grub2 ELF* or *iPXE Chain*, require additional configuration.
These workflows are not documented at the moment.
endif::[]

For BIOS provisioning, you must associate a PXELinux template with the operating system.
For UEFI provisioning, you must associate a PXEGrub2 template with the operating system.
If you associate both PXELinux and PXEGrub2 templates, {Project} can deploy configuration files for both on a TFTP server, so that you can switch between PXE loaders easily.
If you associate both PXELinux and PXEGrub2 templates, {Project} deploys configuration files for both on a TFTP server, so that you can switch between PXE loaders easily.

ifndef::satellite[]
.Provisioning of Secure Boot enabled hosts
Select the *Grub2 UEFI SecureBoot* or the *Grub2 UEFI HTTPS SecureBoot* PXE loader options to enable a client to download the `shimx64.efi` bootstrap bootloader that then loads the signed `grubx64.efi`.

By default, you can provision operating systems from the vendor of the operating system of your {ProjectServer} on Secure Boot enabled hosts.
To provision operating systems on Secure Boot enabled hosts from different vendors, you have to provide signed shim and GRUB2 binaries provided by the vendor of your operating system.
ifndef::orcharhino[]
For more information, see:

* xref:configuring-{smart-proxy-context}-to-provision-almalinux-on-Secure-Boot-enabled-hosts[]
* xref:configuring-{smart-proxy-context}-to-provision-debian-on-Secure-Boot-enabled-hosts[]
* xref:configuring-{smart-proxy-context}-to-provision-rocky-on-Secure-Boot-enabled-hosts[]
* xref:configuring-{smart-proxy-context}-to-provision-ubuntu-on-Secure-Boot-enabled-hosts[]
endif::[]
endif::[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
[id="configuring-{smart-proxy-context}-to-provision-{client-os-context}-on-Secure-Boot-enabled-hosts"]
= Configuring {SmartProxy} to provision {client-os} on Secure Boot enabled hosts

Secure Boot follows a chain of trust from the start of the host to the loading of Linux kernel modules.
The first shim that is loaded determines which distribution can be booted or loaded by using a `kexec` system call until the next reboot.

To provision {client-os} on Secure Boot enabled hosts with the *Grub2 UEFI SecureBoot* and *Grub2 UEFI HTTPS SecureBoot* PXE loaders, you have to provide signed shim and GRUB2 binaries provided by the vendor of your operating system.

[IMPORTANT]
====
ifdef::satellite[]
You have to perform the following configuration steps on each TFTP {SmartProxy} for a subnet to provision Secure Boot enabled hosts on that subnet.
endif::[]
ifndef::satellite[]
You have to perform the following configuration steps on each TFTP proxy for a subnet to provision Secure Boot enabled hosts on that subnet.
endif::[]
====

The following example works for {client-os} on x86_64 architecture.

.Prerequisites
ifeval::["{client-os}" == "Debian"]
* Ensure that `ar` and `xz` are installed on your {SmartProxy}.
endif::[]
ifeval::["{client-os}" == "Ubuntu"]
* Ensure that `ar`, `xz`, and `zstd` are installed on your {SmartProxy}.
endif::[]
ifeval::["{client-pkg-ext}" == "rpm"]
* Ensure that `cpio` is installed on your {SmartProxy}.
endif::[]

.Procedure
. On your {SmartProxy}, configure the directory to store the shim and GRUB2 binaries required for provisioning Secure Boot enabled hosts:
+
[options="nowrap" subs="+quotes,verbatim,attributes"]
----
# {foreman-installer} --foreman-proxy-tftp-bootloader-universe _My_Bootloader_Directory_
----
+
Replace _My_Bootloader_Directory_ with the absolute path where you want to store the shim and GRUB2 binaries.
. Set the path for the shim and GRUB2 binaries for the operating system of your host:
+
[options="nowrap" subs="+quotes,verbatim,attributes"]
----
# BOOTLOADER_PATH="_My_Bootloader_Directory_/pxegrub2/_{secureboot-os-name}_/default/x86_64"
----
+
If you require specific versions of the shim and GRUB2 binaries for the version of the operating system of your host, replace `default` with the *Major* and *Minor* version of the operating system separated by a dot.
If no *Minor* version is set, replace `default` with the *Major* version.
+
{Team} recommends to not use version-specific shim and GRUB2 binaries unless it is really necessary.
. Create the directory to store the shim and GRUB2 binaries for the operating system of your host:
+
[options="nowrap" subs="+quotes,verbatim,attributes"]
----
# install -o foreman-proxy -g foreman-proxy -d $BOOTLOADER_PATH
----
. Download the shim and GRUB2 packages for the operating system of your host:
+
[options="nowrap" subs="+quotes,verbatim,attributes"]
----
# wget -O /tmp/{grub_efi_downloaded_package_name} _https://{server-example-com}/{grub_efi_downloaded_package_name}_
# wget -O /tmp/{shim_efi_downloaded_package_name} _https://{server-example-com}/{shim_efi_downloaded_package_name}_
----
+
You can download the `{grub_efi_package_name}` package from {grub_efi_download_url}.
You can download the `{shim_efi_package_name}` package from {shim_efi_download_url}.
. Extract the shim and GRUB2 binaries:
+
[options="nowrap" subs="+quotes,verbatim,attributes"]
----
# {extract_grub}
# {extract_shim}
----
. Make the shim and GRUB2 binaries available for host provisioning:
+
[options="nowrap" subs="+quotes,verbatim,attributes"]
----
# cp {grub_efi_tmp_binary_path} $BOOTLOADER_PATH/grubx64.efi
# cp {shim_efi_tmp_binary_path} $BOOTLOADER_PATH/shimx64.efi
# ln -sr $BOOTLOADER_PATH/grubx64.efi $BOOTLOADER_PATH/boot.efi
# ln -sr $BOOTLOADER_PATH/shimx64.efi $BOOTLOADER_PATH/boot-sb.efi
# chmod 644 $BOOTLOADER_PATH/grubx64.efi
# chmod 644 $BOOTLOADER_PATH/shimx64.efi
----
ifeval::["{client-pkg-ext}" == "deb"]
. Link the `grub.cfg` file from the TFTP servers `grub2` folder to the legacy `grub` folder:
+
[options="nowrap" subs="+quotes,verbatim,attributes"]
----
# ln --relative --symbolic /var/lib/tftpboot/grub2/grub.cfg /var/lib/tftpboot/grub/grub.cfg
----
endif::[]

.Verification
* Verify the contents of your bootloader directory:
+
[options="nowrap" subs="+quotes,verbatim,attributes"]
----
# tree _My_Bootloader_Directory_
_My_Bootloader_Directory_
└── pxegrub2
└── _{secureboot-os-name}_
└── default
└── x86_64
├── boot.efi -> grubx64.efi
├── boot-sb.efi -> shimx64.efi
├── grubx64.efi
└── shimx64.efi
----

.Next steps
* You can now provision Secure Boot enabled {client-os} hosts by using the *Grub2 UEFI SecureBoot* and *Grub2 UEFI HTTPS SecureBoot* PXE loaders.

0 comments on commit 429b413

Please sign in to comment.