Support UEFI PXE boot with DHCPv4
authorMichael Prokop <mika@grml.org>
Sat, 18 Jul 2020 11:02:57 +0000 (13:02 +0200)
committerMichael Prokop <mika@grml.org>
Sat, 18 Jul 2020 11:03:03 +0000 (13:03 +0200)
pxelinux supports booting via BIOS, but to get EFI boot working via PXE
(especially when booting via Secure Boot even), then we need a proper
GRUB based boot toolchain.

By using binaries from grub-efi-amd64-signed + shim-signed packages and
integrating them in our configuration, we support BIOS boot via pxelinux
and EFI boot via GRUB at the same time.

FTR: to support grml-terminalserver as arch all package and not
*strictly* requiring the grub-efi-amd64-signed + shim-signed packages
(at least for now), we use a dependency chain as follows:

| grub-efi-amd64-signed | grub-efi-amd64-bin | pxelinux,
| shim-signed:amd64 | pxelinux,

This means that only pxelinux is strictly needed if you don't care about
PXE support, but need to ensure grub-efi-amd64-signed (or
grub-efi-amd64-bin as its fallback) and shim-signed are present on your
system if you want PXE boot support within grml-terminalserver.  This
change will be implemented in GRML_FULL class of grml-live for the
official Grml ISOs.

This work was funded by Grml-Forensic.

debian/control
grml-terminalserver
templates/dhcpd_config
templates/grub-shim_config [new file with mode: 0644]

index 40a0ae4..253d2ea 100644 (file)
@@ -17,11 +17,13 @@ Depends: atftpd (>=0.7.dfsg-1.2),
          dialog,
          grml-shlib (>=1.02.03),
          grml2usb (>=0.9.14),
+         grub-efi-amd64-signed | grub-efi-amd64-bin | pxelinux,
          ipcalc,
          isc-dhcp-server | dhcp3-server,
          nfs-kernel-server,
          pxelinux | syslinux-common (<= 2:4.05+dfsg-6+deb7u1),
-         ${misc:Depends}
+         shim-signed:amd64 | pxelinux,
+         ${misc:Depends},
 Description: terminalserver for grml to boot via PXE
  These packages provides all what's needed to boot
  grml over the network (PXE). An easy to use interface
index 3fcfa37..3e7a6aa 100755 (executable)
@@ -221,7 +221,11 @@ function createTftpConf
   execute "install -m 644 $PXE_BOOT_MSG_ $TFTPD_DATA_DIR_" die
   [ -f "$PXE_BOOT_LOGO_" ] && execute "install -m 644 $PXE_BOOT_LOGO_ $TFTPD_DATA_DIR_" die
 
+  # PXE / BIOS boot (pxelinux)
   execute "source $TEMPLATE_CONFIG_DIR_/grub-pxelinux_config" die
+
+  # PXE / EFI boot (GRUB)
+  execute "source $TEMPLATE_CONFIG_DIR_/grub-shim_config" die
 }
 
 function stopTftp
index 824b42e..5bf9ded 100644 (file)
@@ -45,21 +45,27 @@ cat >"$DHCPD_CONFIG_FILE_" <<EOT
 # global settings
 allow booting;
 allow bootp;
-#option option-150 code 150 = text ;
-#option T150 code 150 = string;
 default-lease-time 600;
 max-lease-time 7200;
 
+# UEFI boot with DHCPv4
+option architecture-type code 93 = unsigned integer 16;
+
 subnet $NETWORK_ netmask $NETMASK_ {
   next-server $IP_;
-  if substring (option vendor-class-identifier, 0, 9) = "Etherboot" { filename "etherboot.nbi"; }
-  else { filename "pxelinux.0"; }
 #  option subnet-mask $NETMASK_;
   range $IPRANGE_FROM_ $IPRANGE_TO_;
   $ROUTERS_LINE_
   $DNS_LINE_
-#  option T150 "/menu.lst";
-#  option option-150 "(nd)/menu.lst";
+
+  class "pxeclients" {
+    match if substring (option vendor-class-identifier, 0 ,9) = "PXEClient";
+    if option architecture-type = 00:07 {
+      filename "shim.efi";
+    } else {
+      filename "pxelinux.0";
+    }
+  }
 }
 
 EOT
diff --git a/templates/grub-shim_config b/templates/grub-shim_config
new file mode 100644 (file)
index 0000000..fdfba5c
--- /dev/null
@@ -0,0 +1,89 @@
+# the following variables are available in the template:
+#
+# $INTERFACE_     (interface for the terminalserver)
+# $IP_            (ip for the terminalserver to bind)
+# $NETMASK_       (network mask)
+# $GW_            (gateway)
+# $NAMESERVERS_   (nameservers for the nodes)
+# $IPRANGE_FROM_  (user configured iprange, first ip)
+# $IPRANGE_TO_    (user configured iprange, last ip)
+# $NETWORK_       (first ip in this subnet)
+# $OPTIONS_       (options for grml-terminalserver)
+# $BOOT_ARGS_     (boot arguments for the nodes)
+#
+# NOTE:
+# templates are shellscript fragments and will be sourced from the
+# terminalserver
+#
+# GLOBAL_README_END
+
+if [ -r "${TFTPD_DATA_DIR_}"/shim.efi ] ; then
+  echo "${TFTPD_DATA_DIR_}/shim.efi exists already, nothing to do."
+elif [ -r /usr/lib/shim/shimx64.efi.signed ] ; then
+  echo "Installing /usr/lib/shim/shimx64.efi.signed as shim.efi for TFTP usage"
+  cp /usr/lib/shim/shimx64.efi.signed "${TFTPD_DATA_DIR_}"/shim.efi
+elif [ -r /usr/lib/shim/shimx64.efi ] ; then
+  echo "Installing /usr/lib/shim/shimx64.efi as shim.efi for TFTP usage"
+  cp /usr/lib/shim/shimx64.efi "${TFTPD_DATA_DIR_}"/shim.efi
+else
+  echo "WARN: No shimx64.efi for usage with PXE boot found, not setting up UEFI boot via GRUB."
+  (( ret_=ret_+ $? ))
+  return "$ret_"
+fi
+
+if [ -r "${TFTPD_DATA_DIR_}"/grubx64.efi ] ; then
+  echo "${TFTPD_DATA_DIR_}/grubx64.efi exists already, nothing to do."
+elif [ -r /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed ] ; then
+  echo "Installing /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed as grubx64.efi for TFTP usage"
+  cp /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed "${TFTPD_DATA_DIR_}"/grubx64.efi
+elif [ -r /usr/lib/grub/x86_64-efi/monolithic/grubnetx64.efi ] ; then
+  echo "Installing /usr/lib/grub/x86_64-efi/monolithic/grubnetx64.efi as grubx64.efi for TFTP usage"
+  cp /usr/lib/grub/x86_64-efi/monolithic/grubnetx64.efi "${TFTPD_DATA_DIR_}"/grubx64.efi
+else
+  echo "WARN: No grubnetx64.efi for usage with PXE boot found, not setting up UEFI boot via GRUB."
+  (( ret_=ret_+ $? ))
+  return "$ret_"
+fi
+
+echo "Setting up GRUB configuration for PXE/UEFI usage"
+mkdir -p "${TFTPD_DATA_DIR_}/grub/"
+cat > "${TFTPD_DATA_DIR_}/grub/grub.cfg" << EOT
+# GRUB PXE configuration file
+
+# adjust according to your needs
+#set timeout=300
+
+insmod png
+set gfxmode=auto
+insmod gfxterm
+terminal_output gfxterm
+
+set menu_color_normal=white/black
+set menu_color_highlight=black/yellow
+
+# this needs some tuning, so not enabled by default
+# set theme=/boot/grub/grml-theme/theme.txt
+# export theme
+
+EOT
+
+# theme support requires e.g. icons/submenu.png within the theme directory,
+# which we don't ship though, so not enabled by default
+#mkdir -p "${TFTPD_DATA_DIR_}"/grub/themes/boot/grub
+#ln -s "${TFTPD_DATA_DIR_}"/boot/grub/grml-theme "${TFTPD_DATA_DIR_}"/grub/themes/boot/grub/
+
+for file in "${TFTPD_DATA_DIR_}"/boot/grub/*_default.cfg "${TFTPD_DATA_DIR_}"/boot/grub/*_options.cfg ; do
+  filename="$(basename "${file}")"
+  echo "source boot/grub/${filename}" >> "${TFTPD_DATA_DIR_}/grub/grub.cfg"
+done
+
+cat >> "${TFTPD_DATA_DIR_}/grub/grub.cfg" << EOT
+
+menuentry "Boot OS of first partition on first disk" {
+    set root=(hd0,1)
+    chainloader +1
+}
+EOT
+
+(( ret_=ret_+ $? ))
+return "$ret_"