Secure Boot iPXE chain is the default for every UEFI client
Live since 2026-10-14: dnsmasq hands every UEFI client ipxe-shim.efi (iPXE's shim, dual-signed under Microsoft UEFI CA 2011 + 2023), which loads ipxe.efi from the TFTP root, now the iPXE v2.0.0 snponly build (firmware network and USB drivers; the full build kills USB keyboards). The per-MAC test tags and folders are gone; the old Broadcom-signed 1.21.1 build stays as ipxe-bcm.efi, the rollback. - playbook: pinned sha256 vars, the new dnsmasq default line, and a verified, non-optional task that installs ipxe-shim.efi, ipxe.efi (snponly), ipxe.pxe and ipxe-bcm.efi (was: copy ipxe.efi and the never served undionly.kpxe, errors ignored). - scripts/fetch-ipxe.sh downloads the pinned tarball and shim into boot-files/ for the USB build; README/SETUP list the step. - iPXE page: ipxe.efi is staged from snponly.efi, a build that drives USB itself is refused, and the snponly-shim/snponly root files are gone. Tested: the playbook task against the real release files (installs the live hashes; a tampered file stops it before anything is replaced), ansible --syntax-check, staging, and the full-build refusal.
This commit is contained in:
@@ -38,6 +38,17 @@
|
||||
samba_share: "/srv/samba/winpeapps"
|
||||
usb_mount: "/mnt/usb/playbook" # playbook location on USB
|
||||
usb_root: "/mnt/usb" # CIDATA partition root
|
||||
# Secure Boot iPXE chain, fetched into boot-files/ by scripts/fetch-ipxe.sh
|
||||
# (keep these pins in step with that script). Every UEFI client gets the
|
||||
# dual-signed shim (Microsoft UEFI CA 2011 + 2023), which loads ipxe.efi
|
||||
# from the TFTP root: the release's SNPONLY build (firmware network and
|
||||
# USB drivers; the full ipxe.efi drives USB itself and kills USB
|
||||
# keyboards at the menu). The old Broadcom-signed 1.21.1 build stays on
|
||||
# the box as ipxe-bcm.efi, the rollback.
|
||||
ipxe_tarball_sha256: "01a526d4cc791fc30362259c609d6c506cc64a7bdff51b9a5eb788354e17eee1" # ipxe v2.0.0 ipxeboot.tar.gz
|
||||
ipxe_shim_sha256: "5eecca2780bd49c900565e124516a1bd666ec5e012825f34991b6ba1ef2fa6cf" # ipxe/shim ipxe-16.1 ipxe-shimx64.efi
|
||||
ipxe_snponly_sha256: "b1e67c3e4a1e8708ddfd0079ad4505e3a02245acb55ee9a95437ab3c507be82a" # x86_64-sb/snponly.efi
|
||||
ipxe_bios_sha256: "0fb21c695c82fd70d4f89732ddcd285063776e2bbd71de9a2c39e9cfe4b180b8" # x86_64/ipxe.pxe
|
||||
# Zscaler Root CA: GE's Zscaler re-signs GitHub TLS, so the iPXE update
|
||||
# check fails without it. Repo copy first, else the copy on the image share.
|
||||
zscaler_ca_src: "{{ playbook_dir }}/certs/zscaler-root-ca.crt"
|
||||
@@ -176,17 +187,18 @@
|
||||
tftp-root={{ tftp_dir }}
|
||||
# Arch-aware NBP for Blancco/WinPE PXE clients:
|
||||
# - legacy BIOS (vendorclass PXEClient:Arch:00000) -> ipxe.pxe, a
|
||||
# BIOS full-feature iPXE build (boot.ipxe.org) with an HTTP/TCP
|
||||
# stack. The old undionly.kpxe client-arch=0 scheme was stale -
|
||||
# undionly.kpxe was never staged in tftp-root so it broke BIOS
|
||||
# boot; this vendorclass+ipxe.pxe scheme is what runs on the box.
|
||||
# BIOS full-feature iPXE build with an HTTP/TCP stack.
|
||||
# - iPXE-running clients (userclass "iPXE") -> chain to the HTTP menu
|
||||
# - everything else (UEFI x86_64) -> ipxe.efi
|
||||
# - every UEFI client -> ipxe-shim.efi, iPXE's Microsoft-signed shim
|
||||
# (dual-signed, UEFI CA 2011 + 2023). Over TFTP it always loads
|
||||
# ipxe.efi from the TFTP root, which is the iPXE snponly build
|
||||
# (see the ipxe_* vars). Rollback: point the last line back at
|
||||
# ipxe-bcm.efi (the old Broadcom-signed 1.21.1 build).
|
||||
dhcp-vendorclass=set:bios,PXEClient:Arch:00000
|
||||
dhcp-userclass=set:ipxe,iPXE
|
||||
dhcp-boot=tag:bios,tag:!ipxe,ipxe.pxe
|
||||
dhcp-boot=tag:ipxe,http://172.16.9.1:4433/Altiris/iPXE/GetPxeScript.aspx
|
||||
dhcp-boot=tag:!bios,ipxe.efi
|
||||
dhcp-boot=tag:!bios,tag:!ipxe,ipxe-shim.efi
|
||||
log-dhcp
|
||||
# Per-lease state cleanup: flush conntrack + port-445 sockets for
|
||||
# the client IP on add/del. Prevents "System error 53" when a PXE
|
||||
@@ -808,15 +820,36 @@
|
||||
executable: /bin/bash
|
||||
ignore_errors: yes
|
||||
|
||||
- name: "Copy iPXE binaries from USB (skipped if not present)"
|
||||
copy:
|
||||
src: "{{ usb_root }}/{{ item }}"
|
||||
dest: "{{ tftp_dir }}/{{ item }}"
|
||||
mode: '0755'
|
||||
loop:
|
||||
- ipxe.efi
|
||||
- undionly.kpxe
|
||||
ignore_errors: yes
|
||||
- name: "Install the Secure Boot iPXE chain into the TFTP root (pinned, verified)"
|
||||
# Not ignore_errors: without these files no client can boot. Files come
|
||||
# from boot-files/ via scripts/fetch-ipxe.sh; each is checked against
|
||||
# its pin before anything is replaced, and each is put in place by
|
||||
# rename so a client that is booting never reads half a file.
|
||||
shell: |
|
||||
set -euo pipefail
|
||||
U="{{ usb_root }}"; T="{{ tftp_dir }}"
|
||||
check() { echo "$2 $1" | sha256sum -c --status || { echo "sha256 mismatch or missing: $1" >&2; exit 1; }; }
|
||||
check "$U/ipxeboot.tar.gz" "{{ ipxe_tarball_sha256 }}"
|
||||
check "$U/ipxe-shimx64.efi" "{{ ipxe_shim_sha256 }}"
|
||||
W=$(mktemp -d); trap 'rm -rf "$W"' EXIT
|
||||
tar -xzf "$U/ipxeboot.tar.gz" -C "$W" ipxeboot/x86_64-sb/snponly.efi ipxeboot/x86_64/ipxe.pxe
|
||||
check "$W/ipxeboot/x86_64-sb/snponly.efi" "{{ ipxe_snponly_sha256 }}"
|
||||
check "$W/ipxeboot/x86_64/ipxe.pxe" "{{ ipxe_bios_sha256 }}"
|
||||
put() { install -m 0644 -o root -g root "$1" "$T/.$2.new" && mv -f "$T/.$2.new" "$T/$2"; }
|
||||
put "$U/ipxe-shimx64.efi" ipxe-shim.efi
|
||||
put "$W/ipxeboot/x86_64-sb/snponly.efi" ipxe.efi
|
||||
put "$W/ipxeboot/x86_64/ipxe.pxe" ipxe.pxe
|
||||
# Rollback boot file: the old Broadcom-signed build (boot-files/ipxe.efi).
|
||||
if [ -f "$U/ipxe.efi" ]; then put "$U/ipxe.efi" ipxe-bcm.efi; fi
|
||||
echo "installed ipxe-shim.efi, ipxe.efi (snponly), ipxe.pxe$( [ -f "$U/ipxe.efi" ] && echo ', ipxe-bcm.efi')"
|
||||
args:
|
||||
executable: /bin/bash
|
||||
register: ipxe_chain
|
||||
changed_when: true
|
||||
|
||||
- name: "Show the installed iPXE chain"
|
||||
debug:
|
||||
msg: "{{ ipxe_chain.stdout }}"
|
||||
|
||||
- name: "Copy boot tool files from USB (Clonezilla, Blancco, Memtest)"
|
||||
shell: >
|
||||
|
||||
Reference in New Issue
Block a user