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:
@@ -55,8 +55,14 @@ Client PXE boot (UEFI Secure Boot)
|
||||
|
||||
```bash
|
||||
./scripts/download-packages.sh
|
||||
./scripts/fetch-ipxe.sh
|
||||
```
|
||||
|
||||
`fetch-ipxe.sh` downloads the Secure Boot iPXE chain into `boot-files/`, pinned by sha256: the iPXE release
|
||||
tarball (its snponly build becomes `ipxe.efi`) and iPXE's dual-signed shim (Microsoft UEFI CA 2011 + 2023),
|
||||
which every UEFI client boots as `ipxe-shim.efi`. Keep the old Broadcom-signed `boot-files/ipxe.efi` too: the
|
||||
playbook installs it as `ipxe-bcm.efi`, the rollback boot file.
|
||||
|
||||
Downloads all .deb packages and Python wheels for offline installation (~140 MB of debs, ~20 MB of wheels).
|
||||
|
||||
### Step 2: Prepare Boot Tools (optional)
|
||||
|
||||
6
SETUP.md
6
SETUP.md
@@ -47,8 +47,14 @@ Client PXE boot
|
||||
|
||||
```bash
|
||||
./scripts/download-packages.sh
|
||||
./scripts/fetch-ipxe.sh
|
||||
```
|
||||
|
||||
`fetch-ipxe.sh` downloads the Secure Boot iPXE chain into `boot-files/`, pinned by sha256: the iPXE release
|
||||
tarball (its snponly build becomes `ipxe.efi`) and iPXE's dual-signed shim (Microsoft UEFI CA 2011 + 2023),
|
||||
which every UEFI client boots as `ipxe-shim.efi`. Keep the old Broadcom-signed `boot-files/ipxe.efi` too: the
|
||||
playbook installs it as `ipxe-bcm.efi`, the rollback boot file.
|
||||
|
||||
Downloads all .deb packages (ansible, dnsmasq, apache2, samba, wimtools, etc.) into `offline-packages/` and Python wheels (flask, lxml) into `pip-wheels/`. Approximately 252 packages (~140 MB) + 8 Python wheels.
|
||||
|
||||
**Packages included:**
|
||||
|
||||
@@ -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: >
|
||||
|
||||
61
scripts/fetch-ipxe.sh
Executable file
61
scripts/fetch-ipxe.sh
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# fetch-ipxe.sh - Download the pinned Secure Boot iPXE chain into boot-files/
|
||||
# for the USB build (build-usb.sh copies boot-files/* to the USB root, and
|
||||
# playbook/pxe_server_setup.yml installs them into the TFTP root).
|
||||
#
|
||||
# ipxeboot.tar.gz iPXE release (github.com/ipxe/ipxe). The playbook takes
|
||||
# x86_64-sb/snponly.efi (installed as ipxe.efi: firmware
|
||||
# network + USB drivers, so USB keyboards work at the menu)
|
||||
# and x86_64/ipxe.pxe (legacy BIOS).
|
||||
# ipxe-shimx64.efi iPXE's Microsoft-signed shim (github.com/ipxe/shim),
|
||||
# dual-signed under Microsoft UEFI CA 2011 and 2023.
|
||||
# Installed as ipxe-shim.efi, the boot file every UEFI
|
||||
# client gets. Not the tarball's shimx64.efi, which is
|
||||
# signed under the 2011 CA only.
|
||||
#
|
||||
# Every file is checked against the sha256 pinned below; a mismatch deletes
|
||||
# it and fails. To move to a new release, change the pins here AND the
|
||||
# matching ipxe_* vars in playbook/pxe_server_setup.yml.
|
||||
#
|
||||
# Usage: ./scripts/fetch-ipxe.sh [boot-files dir]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd)"
|
||||
OUT_DIR="${1:-$REPO_ROOT/boot-files}"
|
||||
|
||||
IPXE_TAG="v2.0.0"
|
||||
IPXE_TARBALL_SHA256="01a526d4cc791fc30362259c609d6c506cc64a7bdff51b9a5eb788354e17eee1"
|
||||
SHIM_TAG="ipxe-16.1"
|
||||
SHIM_SHA256="5eecca2780bd49c900565e124516a1bd666ec5e012825f34991b6ba1ef2fa6cf"
|
||||
|
||||
fetch() { # url dest sha256
|
||||
local url="$1" dest="$2" sha="$3"
|
||||
if [ -f "$dest" ] && echo "$sha $dest" | sha256sum -c --status; then
|
||||
echo " ok (cached) $(basename "$dest")"
|
||||
return
|
||||
fi
|
||||
rm -f "$dest"
|
||||
# GitHub goes through Zscaler on GE networks: a TLS error here means the
|
||||
# Zscaler root CA is missing from the system trust store.
|
||||
curl -fsSL --retry 3 -o "$dest" "$url"
|
||||
if ! echo "$sha $dest" | sha256sum -c --status; then
|
||||
echo "ERROR: sha256 mismatch for $(basename "$dest"); removed it" >&2
|
||||
rm -f "$dest"
|
||||
exit 1
|
||||
fi
|
||||
echo " ok $(basename "$dest")"
|
||||
}
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
echo "Fetching the Secure Boot iPXE chain into $OUT_DIR"
|
||||
fetch "https://github.com/ipxe/ipxe/releases/download/$IPXE_TAG/ipxeboot.tar.gz" \
|
||||
"$OUT_DIR/ipxeboot.tar.gz" "$IPXE_TARBALL_SHA256"
|
||||
fetch "https://github.com/ipxe/shim/releases/download/$SHIM_TAG/ipxe-shimx64.efi" \
|
||||
"$OUT_DIR/ipxe-shimx64.efi" "$SHIM_SHA256"
|
||||
if [ ! -f "$OUT_DIR/ipxe.efi" ]; then
|
||||
echo "NOTE: $OUT_DIR/ipxe.efi (the old Broadcom-signed 1.21.1 build) is missing."
|
||||
echo " The playbook installs it as ipxe-bcm.efi, the rollback boot file;"
|
||||
echo " copy it from an existing PXE server's /srv/tftp/ipxe-bcm.efi."
|
||||
fi
|
||||
@@ -1,21 +1,19 @@
|
||||
"""Keep the Secure Boot iPXE chain on the TFTP root current.
|
||||
|
||||
What dnsmasq serves (see /etc/dnsmasq.conf):
|
||||
* ipxe-shim.efi - Microsoft-signed shim, for the MACs tagged ipxe2. Over
|
||||
TFTP it always loads ipxe.efi from the TFTP root (it
|
||||
does not derive the name from its own, whatever the
|
||||
upstream docs say);
|
||||
* snponly-shim.efi - the same shim under the name dnsmasq hands the
|
||||
ipxesnp-tagged MACs;
|
||||
* ipxe.efi - iPXE signed by the iPXE Secure Boot CA, loaded by the
|
||||
shim. The full build drives USB itself, which kills a
|
||||
USB keyboard at the iPXE menu;
|
||||
* snponly.efi - the same release built to use the firmware's network
|
||||
and USB drivers (keyboard keeps working). Served to a
|
||||
client as ipxe.efi from its per-MAC folder;
|
||||
* ipxe-bcm.efi - the old 2021 Broadcom-signed build, everyone else.
|
||||
Never touched here;
|
||||
* ipxe.pxe - legacy BIOS iPXE (unsigned; BIOS has no Secure Boot).
|
||||
What dnsmasq serves (see /etc/dnsmasq.conf), since 2026-10-14:
|
||||
* ipxe-shim.efi - iPXE's Microsoft-signed shim, every UEFI client. Over
|
||||
TFTP it always loads ipxe.efi from the TFTP root (it does
|
||||
not derive the name from its own, whatever the upstream
|
||||
docs say);
|
||||
* ipxe.efi - iPXE signed by the iPXE Secure Boot CA, loaded by the
|
||||
shim. It is the release's SNPONLY build (x86_64-sb/
|
||||
snponly.efi): firmware network and USB drivers. The
|
||||
release's full ipxe.efi drives USB itself, which kills a
|
||||
USB keyboard at the iPXE menu, so it is never installed;
|
||||
* ipxe-bcm.efi - the old 2021 Broadcom-signed 1.21.1 build, kept as the
|
||||
rollback (point dnsmasq's UEFI line back at it). Never
|
||||
touched here;
|
||||
* ipxe.pxe - legacy BIOS iPXE (unsigned; BIOS has no Secure Boot).
|
||||
|
||||
Per-MAC folders: with tftp-unique-root=mac, /srv/tftp/<aa-bb-cc-dd-ee-ff>/
|
||||
wins over the root for that client, with NO fallback for a file missing
|
||||
@@ -71,14 +69,13 @@ JOB_UNIT = "pxe-webapp-ipxe-stage"
|
||||
# Secure Boot signature (and from whom).
|
||||
MANAGED = {
|
||||
"ipxe-shim.efi": ("ipxeboot/x86_64-sb/shimx64.efi", "microsoft"),
|
||||
"snponly-shim.efi": ("ipxeboot/x86_64-sb/shimx64.efi", "microsoft"),
|
||||
"ipxe.efi": ("ipxeboot/x86_64-sb/ipxe.efi", "ipxe"),
|
||||
"snponly.efi": ("ipxeboot/x86_64-sb/snponly.efi", "ipxe"),
|
||||
# The snponly build, installed under the name the shim loads.
|
||||
"ipxe.efi": ("ipxeboot/x86_64-sb/snponly.efi", "ipxe"),
|
||||
"ipxe.pxe": ("ipxeboot/x86_64/ipxe.pxe", None),
|
||||
}
|
||||
SHIMS = ("ipxe-shim.efi", "snponly-shim.efi")
|
||||
SHIMS = ("ipxe-shim.efi",)
|
||||
# Installed by default; ipxe.pxe (legacy BIOS) only when asked.
|
||||
DEFAULT_INSTALL = ("ipxe-shim.efi", "snponly-shim.efi", "ipxe.efi", "snponly.efi")
|
||||
DEFAULT_INSTALL = ("ipxe-shim.efi", "ipxe.efi")
|
||||
# Shown on the page for reference, never written.
|
||||
READ_ONLY = ("ipxe-bcm.efi",)
|
||||
|
||||
@@ -266,8 +263,7 @@ def installed():
|
||||
rows.append({"name": name, "managed": name in MANAGED, "info": info})
|
||||
# The shim only starts an iPXE signed under the CA it embeds.
|
||||
by = {r["name"]: r["info"] for r in rows}
|
||||
_check_chain(by.get("ipxe-shim.efi") or by.get("snponly-shim.efi"),
|
||||
[by.get("ipxe.efi"), by.get("snponly.efi")])
|
||||
_check_chain(by.get("ipxe-shim.efi"), [by.get("ipxe.efi")])
|
||||
return rows
|
||||
|
||||
|
||||
@@ -530,11 +526,13 @@ def stage(info=None):
|
||||
_use_dual_signed_shim(folder, files)
|
||||
# The shim must trust the CA this release's iPXE builds are signed by.
|
||||
shim = files.get("ipxe-shim.efi") or {}
|
||||
for name in ("ipxe.efi", "snponly.efi"):
|
||||
ipxe = files.get(name) or {}
|
||||
if shim.get("ok") and ipxe.get("ok") and shim.get("trusts"):
|
||||
if shim["trusts"] not in {i for _, i in ipxe["signers"]}:
|
||||
ipxe.update(ok=False, error=f"not signed under {shim['trusts']}, which this shim trusts")
|
||||
ipxe = files.get("ipxe.efi") or {}
|
||||
if shim.get("ok") and ipxe.get("ok") and shim.get("trusts"):
|
||||
if shim["trusts"] not in {i for _, i in ipxe["signers"]}:
|
||||
ipxe.update(ok=False, error=f"not signed under {shim['trusts']}, which this shim trusts")
|
||||
if ipxe.get("ok") and ipxe.get("drivers") == "native":
|
||||
# The full build would kill USB keyboards on every client.
|
||||
ipxe.update(ok=False, error="this build drives USB itself (not snponly); refusing it as ipxe.efi")
|
||||
record = {"tag": info["tag"], "published": info.get("published"), "folder": folder,
|
||||
"tarball_sha256": info["sha256"], "files": files, "staged": uc.now()}
|
||||
uc.write_json(os.path.join(folder, "staged.json"), record)
|
||||
@@ -775,12 +773,10 @@ def _install(tag, rec, names):
|
||||
if not any(n in names for n in SHIMS):
|
||||
# iPXE alone must still be one the installed shim will start.
|
||||
trusts = vendor_cert_cn(os.path.join(config.TFTP_ROOT, "ipxe-shim.efi"))
|
||||
for n in ("ipxe.efi", "snponly.efi"):
|
||||
if n not in names:
|
||||
continue
|
||||
issuers = {i for _, i in rec["files"][n].get("signers", [])}
|
||||
if "ipxe.efi" in names:
|
||||
issuers = {i for _, i in rec["files"]["ipxe.efi"].get("signers", [])}
|
||||
if trusts and trusts not in issuers:
|
||||
raise ValueError(f"the installed shim trusts {trusts}; this {n} is not signed "
|
||||
raise ValueError(f"the installed shim trusts {trusts}; this ipxe.efi is not signed "
|
||||
"under it, install the shim from the same release too")
|
||||
backup = _backup(names, f"before installing {tag}")
|
||||
_place_all([(os.path.join(rec["folder"], n), n, rec["files"][n]["sha256"]) for n in names])
|
||||
|
||||
@@ -164,14 +164,13 @@
|
||||
<details>
|
||||
<summary class="disc"><span class="chev" aria-hidden="true">▾</span>What this page manages</summary>
|
||||
<p class="sub" style="margin: 4px 0 0; max-width: 900px; line-height: 1.6">
|
||||
The Secure Boot chain that dnsmasq hands out over TFTP: the Microsoft-signed shim (<span class="mono">ipxe-shim.efi</span>,
|
||||
and the same file as <span class="mono">snponly-shim.efi</span>) starts <span class="mono">ipxe.efi</span>, which is signed by the
|
||||
iPXE Secure Boot CA. <span class="mono">snponly.efi</span> is the same release built on the firmware's drivers (USB keyboards
|
||||
keep working). Updates come from the upstream iPXE release tarball on GitHub, plus the dual-signed shim (Microsoft UEFI CA
|
||||
2011 and 2023) from the separate ipxe/shim release; each download's sha256 is checked against GitHub's published digest and
|
||||
each file's signer chain is read with <span class="mono">sbverify</span> before it can be installed.
|
||||
<span class="mono">ipxe-bcm.efi</span>, the per-client folders, <span class="mono">dnsmasq.conf</span> and the Blancco files are
|
||||
never changed here.
|
||||
The Secure Boot chain dnsmasq hands every UEFI client over TFTP: the Microsoft-signed shim (<span class="mono">ipxe-shim.efi</span>,
|
||||
dual-signed under Microsoft UEFI CA 2011 and 2023) starts <span class="mono">ipxe.efi</span>, which is signed by the iPXE Secure
|
||||
Boot CA. <span class="mono">ipxe.efi</span> is the release's snponly build (firmware network and USB drivers, so USB keyboards keep
|
||||
working); the release's full build is refused. Updates come from the upstream iPXE release tarball on GitHub, plus the dual-signed
|
||||
shim from the separate ipxe/shim release; each download's sha256 is checked against GitHub's published digest and each file's
|
||||
signer chain is read with <span class="mono">sbverify</span> before it can be installed. <span class="mono">ipxe-bcm.efi</span>
|
||||
(the old build, kept as the rollback), <span class="mono">dnsmasq.conf</span> and the Blancco files are never changed here.
|
||||
</p>
|
||||
</details>
|
||||
|
||||
@@ -446,23 +445,20 @@ sbverify --list ipxeboot/x86_64-sb/snponly.efi</pre>
|
||||
is normal. Do not rely on <span class="mono">sbverify --cert</span>: it reports OK even for the wrong certificate.</li>
|
||||
<li><strong>Back up the current files.</strong> A backup made in this folder also shows in the Backups list above, with Restore.
|
||||
<pre class="cmd mono">B=/var/lib/pxe-webapp/updates/ipxe/backups/$(date +%Y%m%d-%H%M%S)
|
||||
mkdir -p "$B" && cp -p /srv/tftp/ipxe-shim.efi /srv/tftp/snponly-shim.efi /srv/tftp/ipxe.efi /srv/tftp/snponly.efi "$B"/</pre></li>
|
||||
mkdir -p "$B" && cp -p /srv/tftp/ipxe-shim.efi /srv/tftp/ipxe.efi "$B"/</pre></li>
|
||||
<li><strong>Install both files, from the same release.</strong> The shim only starts an <span class="mono">ipxe.efi</span> signed under the
|
||||
CA it carries, and it always loads <span class="mono">ipxe.efi</span> from the TFTP root, so the name must stay
|
||||
<span class="mono">ipxe.efi</span>. Copy to a temporary name and rename, so a client that is booting never reads half a file:
|
||||
<pre class="cmd mono">install -m 0644 ipxeboot/x86_64-sb/ipxe.efi /srv/tftp/.ipxe.efi.new && mv -f /srv/tftp/.ipxe.efi.new /srv/tftp/ipxe.efi
|
||||
install -m 0644 ipxeboot/x86_64-sb/snponly.efi /srv/tftp/.snponly.efi.new && mv -f /srv/tftp/.snponly.efi.new /srv/tftp/snponly.efi
|
||||
install -m 0644 ipxe-shimx64.efi /srv/tftp/.ipxe-shim.efi.new && mv -f /srv/tftp/.ipxe-shim.efi.new /srv/tftp/ipxe-shim.efi
|
||||
install -m 0644 ipxe-shimx64.efi /srv/tftp/.snponly-shim.efi.new && mv -f /srv/tftp/.snponly-shim.efi.new /srv/tftp/snponly-shim.efi</pre>
|
||||
<span class="sub">No dnsmasq restart is needed. Never replace <span class="mono">ipxe-bcm.efi</span>; it serves every other UEFI client.
|
||||
A per-client folder keeps its own copies: update its <span class="mono">ipxe.efi</span> (the snponly build) and shim the same way.</span></li>
|
||||
<li><strong>Who gets it.</strong> dnsmasq decides, in <span class="mono">/etc/dnsmasq.conf</span>: clients listed as
|
||||
<span class="mono">dhcp-host=<mac>,set:ipxe2</span> get the shim through
|
||||
<span class="mono">dhcp-boot=tag:ipxe2,tag:!ipxe,tag:!bios,ipxe-shim.efi</span>; every other UEFI client gets
|
||||
<span class="mono">ipxe-bcm.efi</span> through the untagged <span class="mono">dhcp-boot=tag:!bios,...,ipxe-bcm.efi</span> line. Clients tagged
|
||||
<span class="mono">ipxesnp</span> get <span class="mono">snponly-shim.efi</span>; since the shim asks for <span class="mono">ipxe.efi</span>
|
||||
whatever it is called, each of them also needs a per-client folder whose <span class="mono">ipxe.efi</span> is the snponly build.
|
||||
Who gets which file above shows the live lines. Test on one tagged machine before tagging more.</li>
|
||||
<pre class="cmd mono">install -m 0644 ipxeboot/x86_64-sb/snponly.efi /srv/tftp/.ipxe.efi.new && mv -f /srv/tftp/.ipxe.efi.new /srv/tftp/ipxe.efi
|
||||
install -m 0644 ipxe-shimx64.efi /srv/tftp/.ipxe-shim.efi.new && mv -f /srv/tftp/.ipxe-shim.efi.new /srv/tftp/ipxe-shim.efi</pre>
|
||||
<span class="sub">Note the first line: the snponly build goes in as <span class="mono">ipxe.efi</span>. Never install the release's
|
||||
full <span class="mono">x86_64-sb/ipxe.efi</span> (it kills USB keyboards), and never replace <span class="mono">ipxe-bcm.efi</span>
|
||||
(the rollback). No dnsmasq restart is needed.</span></li>
|
||||
<li><strong>Who gets it.</strong> dnsmasq decides, in <span class="mono">/etc/dnsmasq.conf</span>: every UEFI client gets the shim
|
||||
through <span class="mono">dhcp-boot=tag:!bios,tag:!ipxe,ipxe-shim.efi</span>. To roll back, point that line at
|
||||
<span class="mono">ipxe-bcm.efi</span> and restart dnsmasq; to keep one model on the old build, tag its MAC
|
||||
(<span class="mono">dhcp-host=<mac>,set:oldipxe</span>) and add <span class="mono">dhcp-boot=tag:oldipxe,tag:!ipxe,tag:!bios,ipxe-bcm.efi</span>
|
||||
above the default line. Who gets which file above shows the live lines.</li>
|
||||
<li><strong>Roll back.</strong> Use Restore in the Backups list, or copy the backed-up files back the same way (temporary name, then
|
||||
<span class="mono">mv -f</span>).</li>
|
||||
<li><strong>Normal log noise.</strong> While booting, the shim asks TFTP for optional files such as
|
||||
|
||||
Reference in New Issue
Block a user