From 27a326dafb621269c501225fd4842615ca4adf73 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Fri, 5 Mar 2021 16:35:21 +1300 Subject: [PATCH] Support secure-boot bootloader where possible As of grub2 >= 2.02-95 on redhat family distros, calling grub2-install on an EFI partition will fail with: "this utility cannot be used for EFI platforms because it does not support UEFI Secure Boot." This version of grub is now in centos8-stream and non-eus repos of RHEL-8. It is not currently possible to build whole-disk UEFI images on these distros, and when this package is promoted this will also affect centos8 and RHEL-8 eus. The grub maintainers made this change because the grub2-install generated /boot/efi/EFI/BOOT/BOOTX64.EFI will never be capable of booting with Secure Boot. This change defines a $EFI_BOOT_DIR for every distro element. When directory /boot/efi/$EFI_BOOT_DIR exists a grub.cfg file in will be generated there. This change also installs the shim package on redhat family distros, which installs a copy of the shim bootloader to /boot/efi/EFI/BOOT/BOOTX64.EFI. Using centos as an example, this allows UEFI to boot the shim /boot/efi/EFI/BOOT/BOOTX64.EFI which then chains to /boot/efi/EFI/centos/grubx64.efi. If /boot/efi/$EFI_BOOT_DIR doesn't exist (such as for Ubuntu, /boot/efi/EFI/ubuntu) the current behaviour of running grub-install to generate /boot/efi/EFI/BOOT/BOOTX64.EFI will continue. For distros such as Ubutnu where packaging does not populate /boot/efi/EFI/ubuntu with .efi files, secure boot can be added in the future by copying .efi files to /boot/efi/EFI/ubuntu and copying the shim file to /boot/efi/EFI/BOOT/BOOTX64.EFI. Change-Id: I90925218ff2aa4c4daffcf86e686b6d98d6b0f21 --- .../bootloader/finalise.d/50-bootloader | 24 ++++++++++++------- diskimage_builder/elements/bootloader/pkg-map | 10 ++++---- .../environment.d/10-centos-distro-name.bash | 1 + .../environment.d/10-centos-distro-name.bash | 1 + .../environment.d/10-centos7-distro-name.bash | 1 + .../environment.d/10-debian-minimal.bash | 1 + .../environment.d/10-fedora-distro-name.bash | 1 + .../environment.d/10-fedora-distro-name.bash | 1 + .../environment.d/00-gentoo-envars.bash | 1 + .../elements/iso/cleanup.d/100-build-iso | 3 --- .../10-opensuse-distro-name.bash | 1 + .../10-opensuse-distro-name.bash | 1 + .../environment.d/10-rhel-distro-name.bash | 1 + .../environment.d/10-ubuntu-distro-name.bash | 1 + 14 files changed, 31 insertions(+), 17 deletions(-) diff --git a/diskimage_builder/elements/bootloader/finalise.d/50-bootloader b/diskimage_builder/elements/bootloader/finalise.d/50-bootloader index 8a48d320..ed79b069 100755 --- a/diskimage_builder/elements/bootloader/finalise.d/50-bootloader +++ b/diskimage_builder/elements/bootloader/finalise.d/50-bootloader @@ -79,6 +79,12 @@ function install_grub2 { GRUBNAME=$(type -p grub2-install) fi + if type grub2-mkconfig >/dev/null; then + GRUB_MKCONFIG="grub2-mkconfig" + else + GRUB_MKCONFIG="grub-mkconfig" + fi + # If no GRUB2 is found, fallback to extlinux if [ -z "$GRUBNAME" ] || [ $($GRUBNAME --version | grep "0.97" | wc -l) -ne 0 ]; then echo "No GRUB2 found. Fallback to Extlinux..." @@ -150,7 +156,7 @@ function install_grub2 { modules="part_msdos part_gpt lvm" extra_options="" if [[ ${DIB_BLOCK_DEVICE} == "mbr" || ${DIB_BLOCK_DEVICE} == "gpt" ]]; then - modules="$modules biosdisk" + $GRUBNAME --modules="$modules biosdisk" $GRUB_OPTS $BOOT_DEV elif [[ ${DIB_BLOCK_DEVICE} == "efi" ]]; then # This tells the EFI install to put the EFI binaries into # the generic /BOOT directory and avoids trying to update @@ -168,8 +174,14 @@ function install_grub2 { # At this point, we don't need to override the target # for any other architectures. esac + if [ -d /boot/efi/$EFI_BOOT_DIR ]; then + # Make the grub config in the EFI directory for UEFI boot + $GRUB_MKCONFIG -o /boot/efi/$EFI_BOOT_DIR/grub.cfg + else + echo "WARNING: /boot/efi/$EFI_BOOT_DIR does not exist, UEFI secure boot not supported" + $GRUBNAME --modules="$modules" $extra_options $GRUB_OPTS $BOOT_DEV + fi fi - $GRUBNAME --modules="$modules" $extra_options $GRUB_OPTS $BOOT_DEV fi # This might be better factored out into a per-distro 'install-bootblock' @@ -204,12 +216,6 @@ function install_grub2 { echo "GRUB_CMDLINE_LINUX_DEFAULT=\"${GRUB_CMDLINE_LINUX_DEFAULT} ${DIB_BOOTLOADER_DEFAULT_CMDLINE}\"" >>/etc/default/grub echo 'GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"' >>/etc/default/grub - if type grub2-mkconfig >/dev/null; then - GRUB_MKCONFIG="grub2-mkconfig -o $GRUB_CFG" - else - GRUB_MKCONFIG="grub-mkconfig -o $GRUB_CFG" - fi - # os-prober leaks /dev/sda into config file in dual-boot host # Disable grub-os-prober to avoid the issue while running # grub-mkconfig @@ -220,7 +226,7 @@ function install_grub2 { echo 'GRUB_DISABLE_OS_PROBER=true' >> /etc/default/grub fi - $GRUB_MKCONFIG + $GRUB_MKCONFIG -o $GRUB_CFG # Remove the fix to disable os_prober if [ -n "$PROBER_DISABLED" ]; then diff --git a/diskimage_builder/elements/bootloader/pkg-map b/diskimage_builder/elements/bootloader/pkg-map index e57aaf52..016f21a9 100644 --- a/diskimage_builder/elements/bootloader/pkg-map +++ b/diskimage_builder/elements/bootloader/pkg-map @@ -18,11 +18,11 @@ "redhat": { "extlinux": "syslinux-extlinux", "grub-pc": "grub2-tools grub2", - "grub-efi-amd64": "grub2-tools grub2-pc grub2-efi-x64 grub2-efi-x64-modules efibootmgr", - "grub-efi-arm64": "grub2-tools grub2-efi-aa64 grub2-efi-aa64-modules efibootmgr", - "grub-efi-aarch64": "grub2-tools grub2-efi-aa64 grub2-efi-aa64-modules efibootmgr", + "grub-efi-amd64": "grub2-tools grub2 grub2-pc grub2-efi-x64 grub2-efi-x64-modules efibootmgr shim-x64", + "grub-efi-arm64": "grub2-tools grub2-efi-aa64 grub2-efi-aa64-modules efibootmgr shim-aa64", + "grub-efi-aarch64": "grub2-tools grub2-efi-aa64 grub2-efi-aa64-modules efibootmgr shim-aa64", "grub-efi": "grub2-tools grub2-efi efibootmgr", - "grub-efi-x86_64": "grub2-tools grub2-efi-x64 grub2-efi-x64-modules efibootmgr", + "grub-efi-x86_64": "grub2-tools grub2 grub2-efi-x64 grub2-efi-x64-modules efibootmgr shim-x64", "grub-ppc64": "grub2-tools grub2" } }, @@ -31,7 +31,7 @@ "extlinux": "extlinux", "grub-pc": "grub-pc", "grub-efi-amd64": "grub-efi grub-pc-bin efibootmgr", - "grub-efi-arm64": "grub-efi-arm64 efibootmgr", + "grub-efi-arm64": "grub-efi-arm64 grub-efi-arm64-bin efibootmgr", "grub-ppc64": "grub-ieee1275" } } diff --git a/diskimage_builder/elements/centos-minimal/environment.d/10-centos-distro-name.bash b/diskimage_builder/elements/centos-minimal/environment.d/10-centos-distro-name.bash index d9e49a4d..fc55bec9 100644 --- a/diskimage_builder/elements/centos-minimal/environment.d/10-centos-distro-name.bash +++ b/diskimage_builder/elements/centos-minimal/environment.d/10-centos-distro-name.bash @@ -1,5 +1,6 @@ export DISTRO_NAME=centos export DIB_RELEASE=${DIB_RELEASE:-7} +export EFI_BOOT_DIR="EFI/centos" # by default, enable DHCP configuration of eth0 & eth1 in network # scripts for centos 7. See yum-minimal for full details. CentOS 8 diff --git a/diskimage_builder/elements/centos/environment.d/10-centos-distro-name.bash b/diskimage_builder/elements/centos/environment.d/10-centos-distro-name.bash index 9864057d..ca893816 100644 --- a/diskimage_builder/elements/centos/environment.d/10-centos-distro-name.bash +++ b/diskimage_builder/elements/centos/environment.d/10-centos-distro-name.bash @@ -1,2 +1,3 @@ export DISTRO_NAME=centos export DIB_RELEASE=${DIB_RELEASE:-8} +export EFI_BOOT_DIR="EFI/centos" diff --git a/diskimage_builder/elements/centos7/environment.d/10-centos7-distro-name.bash b/diskimage_builder/elements/centos7/environment.d/10-centos7-distro-name.bash index 66a7fdc5..11aa38c0 100644 --- a/diskimage_builder/elements/centos7/environment.d/10-centos7-distro-name.bash +++ b/diskimage_builder/elements/centos7/environment.d/10-centos7-distro-name.bash @@ -1,5 +1,6 @@ export DISTRO_NAME=centos7 export DIB_RELEASE=7 +export EFI_BOOT_DIR="EFI/centos" # Useful for elements that work with fedora (dnf) & centos export YUM=${YUM:-yum} diff --git a/diskimage_builder/elements/debian-minimal/environment.d/10-debian-minimal.bash b/diskimage_builder/elements/debian-minimal/environment.d/10-debian-minimal.bash index 62f95fe9..2f565305 100644 --- a/diskimage_builder/elements/debian-minimal/environment.d/10-debian-minimal.bash +++ b/diskimage_builder/elements/debian-minimal/environment.d/10-debian-minimal.bash @@ -1,6 +1,7 @@ export DISTRO_NAME=debian export DIB_RELEASE=${DIB_RELEASE:-stable} export DIB_INIT_SYSTEM=systemd +export EFI_BOOT_DIR="EFI/debian" if [ -n "${DIB_DEBIAN_DISTRIBUTION_MIRROR:-}" ]; then DIB_DISTRIBUTION_MIRROR=$DIB_DEBIAN_DISTRIBUTION_MIRROR diff --git a/diskimage_builder/elements/fedora-minimal/environment.d/10-fedora-distro-name.bash b/diskimage_builder/elements/fedora-minimal/environment.d/10-fedora-distro-name.bash index 161e01b5..ae38976c 100644 --- a/diskimage_builder/elements/fedora-minimal/environment.d/10-fedora-distro-name.bash +++ b/diskimage_builder/elements/fedora-minimal/environment.d/10-fedora-distro-name.bash @@ -1,2 +1,3 @@ export DISTRO_NAME=fedora export DIB_RELEASE=${DIB_RELEASE:-32} +export EFI_BOOT_DIR="EFI/fedora" diff --git a/diskimage_builder/elements/fedora/environment.d/10-fedora-distro-name.bash b/diskimage_builder/elements/fedora/environment.d/10-fedora-distro-name.bash index 6b032b01..b7acaefe 100644 --- a/diskimage_builder/elements/fedora/environment.d/10-fedora-distro-name.bash +++ b/diskimage_builder/elements/fedora/environment.d/10-fedora-distro-name.bash @@ -1,5 +1,6 @@ export DISTRO_NAME=fedora export DIB_RELEASE=${DIB_RELEASE:-32} +export EFI_BOOT_DIR="EFI/fedora" # Note the filename URL has a "sub-release" in it # http:// ... Fedora-Cloud-Base-25-1.3.x86_64.qcow2 diff --git a/diskimage_builder/elements/gentoo/environment.d/00-gentoo-envars.bash b/diskimage_builder/elements/gentoo/environment.d/00-gentoo-envars.bash index 649dabdf..b7a61755 100644 --- a/diskimage_builder/elements/gentoo/environment.d/00-gentoo-envars.bash +++ b/diskimage_builder/elements/gentoo/environment.d/00-gentoo-envars.bash @@ -1,5 +1,6 @@ export DIB_RELEASE=gentoo export DISTRO_NAME=gentoo +export EFI_BOOT_DIR="EFI/gentoo" export GENTOO_PROFILE=${GENTOO_PROFILE:-'default/linux/amd64/17.1'} export GENTOO_PORTAGE_CLEANUP=${GENTOO_PORTAGE_CLEANUP:-'True'} export GENTOO_PYTHON_TARGETS=${GENTOO_PYTHON_TARGETS:-'python3_8'} diff --git a/diskimage_builder/elements/iso/cleanup.d/100-build-iso b/diskimage_builder/elements/iso/cleanup.d/100-build-iso index 9f9febf5..dfe8a669 100755 --- a/diskimage_builder/elements/iso/cleanup.d/100-build-iso +++ b/diskimage_builder/elements/iso/cleanup.d/100-build-iso @@ -63,15 +63,12 @@ function build_iso() { SCRIPTDIR=$(dirname $0) MKISOFS="/usr/bin/mkisofs" if [ $DISTRO_NAME = "fedora" ]; then - EFI_BOOT_DIR="EFI/fedora" EXTRA_KERNEL_PARAMS="usbcore.autosuspend=-1" #debian elif [ $DISTRO_NAME = "debian" ]; then - EFI_BOOT_DIR="EFI/debian" EXTRA_KERNEL_PARAMS="" #ubuntu: else - EFI_BOOT_DIR="EFI/ubuntu" EXTRA_KERNEL_PARAMS="" fi diff --git a/diskimage_builder/elements/opensuse-minimal/environment.d/10-opensuse-distro-name.bash b/diskimage_builder/elements/opensuse-minimal/environment.d/10-opensuse-distro-name.bash index 23834bbb..1ea3fef0 100644 --- a/diskimage_builder/elements/opensuse-minimal/environment.d/10-opensuse-distro-name.bash +++ b/diskimage_builder/elements/opensuse-minimal/environment.d/10-opensuse-distro-name.bash @@ -1,5 +1,6 @@ export DISTRO_NAME=opensuse DIB_RELEASE=${DIB_RELEASE:-15.1} export DIB_RELEASE=${DIB_RELEASE,,} +export EFI_BOOT_DIR="EFI/opensuse" export DIB_OPENSUSE_PATTERNS=patterns-openSUSE-base export DIB_INIT_SYSTEM=systemd diff --git a/diskimage_builder/elements/opensuse/environment.d/10-opensuse-distro-name.bash b/diskimage_builder/elements/opensuse/environment.d/10-opensuse-distro-name.bash index 2f656212..cf41925b 100644 --- a/diskimage_builder/elements/opensuse/environment.d/10-opensuse-distro-name.bash +++ b/diskimage_builder/elements/opensuse/environment.d/10-opensuse-distro-name.bash @@ -1,5 +1,6 @@ export DISTRO_NAME=opensuse export DIB_RELEASE=${DIB_RELEASE:-15.1} +export EFI_BOOT_DIR="EFI/opensuse" export DIB_OPENSUSE_PATTERNS=patterns-openSUSE-base export DIB_INIT_SYSTEM=systemd case ${DIB_RELEASE} in diff --git a/diskimage_builder/elements/rhel/environment.d/10-rhel-distro-name.bash b/diskimage_builder/elements/rhel/environment.d/10-rhel-distro-name.bash index 0fe70cd1..ab8126ea 100644 --- a/diskimage_builder/elements/rhel/environment.d/10-rhel-distro-name.bash +++ b/diskimage_builder/elements/rhel/environment.d/10-rhel-distro-name.bash @@ -1,2 +1,3 @@ export DISTRO_NAME=rhel export DIB_RELEASE=${DIB_RELEASE:-8} +export EFI_BOOT_DIR="EFI/redhat" diff --git a/diskimage_builder/elements/ubuntu-common/environment.d/10-ubuntu-distro-name.bash b/diskimage_builder/elements/ubuntu-common/environment.d/10-ubuntu-distro-name.bash index 06e5651c..8261112d 100644 --- a/diskimage_builder/elements/ubuntu-common/environment.d/10-ubuntu-distro-name.bash +++ b/diskimage_builder/elements/ubuntu-common/environment.d/10-ubuntu-distro-name.bash @@ -1,6 +1,7 @@ export DISTRO_NAME=${DISTRO_NAME:-ubuntu} export DIB_RELEASE=${DIB_RELEASE:-bionic} export DIB_DEBIAN_COMPONENTS=${DIB_DEBIAN_COMPONENTS:-main,universe} +export EFI_BOOT_DIR="EFI/ubuntu" # There are two default distro mirrors depending on architecture ARCH=${ARCH:-}