v0.7.0: Secure Boot chain, boot rules + decision webhook, tokenized answer files
Three features, all zero-toggle and principle-clean (single static musl
binary, container-first, no test certs, no client trust-store changes).
Secure Boot via signed shim+GRUB (automatic):
- The v0.6.1 escalation ladder gains a third rung: Firmware -> Builtin
-> Shim. Secure-Boot firmware downloads our unsigned iPXE but refuses
to execute it — indistinguishable from a failed chainload — so after
two unconfirmed attempts the MAC is offered Fedora's Microsoft-signed
shimx64.efi, which loads the signed GRUB, which fetches a
server-rendered grub.cfg. Fully signed chain, SB stays on.
- scripts/fetch-shim.sh pulls shim-x64/grub2-efi-x64 (+aa64 best-effort)
from the official Fedora 43 packages and ships the EFI binaries
byte-for-byte unmodified; Dockerfile fetch stage gained rpm2cpio/cpio.
- New grub_script renderer (Linux kernel entries only — signed GRUB only
boots signed kernels; sanboot/wimboot have no signed equivalent and
are omitted with an explanatory menu line).
- TFTP server gains a DynamicAsset hook for server-rendered names
(grub.cfg); HTTP serves the same config under /ipxe/grub.cfg for
native UEFI HTTP Boot chains. Arch-aware fallback walks back down the
ladder where no shim exists (BIOS, IA32).
Boot rules + decision webhook (open 'Matrix Boot'):
- Ordered first-match-wins rules over MAC prefix + client arch (the DHCP
proxy now bakes arch into the boot.ipxe chain URL), generalizing
per-MAC pins. Persisted to boot_rules.json; GET/PUT /api/boot-rules;
rules editor + webhook field on the Hosts tab.
- Optional pixiecore-style webhook: unmatched boots GET
<url>?mac=&arch= and 200 {"target":"id"} chains to it. Fail-open
with a 2s budget — a dead endpoint can never block PXE.
- Decision order: exact pin -> rules -> webhook -> menu. Empty config
is byte-for-byte the previous behavior.
Tokenized answer files (the post-WDS/CVE-2026-0386 hardening):
- Every generated unattended URL (inst.ks / preseed url / autoinstall
seed) now carries a 4h boot-scoped token; /unattended/{id} and the
cloud-init seed routes require it (or an operator session) once an
admin exists. Stops answer-file credential harvesting by anything
else on the network. No toggle; setup-mode installs stay open.
Validation: clippy clean, fmt clean, 290 workspace tests green
(+18 new across boot_tokens, boot_rules, arch ladder, escalation,
grub renderer, and four new full-flow integration tests).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
7f25bb681c
commit
3a32d65fb7
@@ -2,8 +2,8 @@ use crate::auth::SessionStore;
|
||||
use crate::saml_routes::SamlRuntime;
|
||||
use crate::uploads::UploadSessions;
|
||||
use openpxe_core::{
|
||||
AdminStore, BootLog, BrandingStore, ClientRegistry, DeploymentQueue, HostBindings, LogBus,
|
||||
Metrics, NotifyStore, SettingsStore, SsoStore,
|
||||
AdminStore, BootLog, BootRulesStore, BootTokens, BrandingStore, ClientRegistry,
|
||||
DeploymentQueue, HostBindings, LogBus, Metrics, NotifyStore, SettingsStore, SsoStore,
|
||||
};
|
||||
use openpxe_iso_store::{
|
||||
IsoStore, NfsShareManager, SftpShareManager, SmbManager, SmbShareManager, UnattendedStore,
|
||||
@@ -29,6 +29,14 @@ pub struct AppState {
|
||||
/// every `/boot/<entry>.ipxe` chain that goes on to serve a script
|
||||
/// (i.e. an image actually starting to install on a machine).
|
||||
pub boot_log: BootLog,
|
||||
/// v0.7.0: ordered label-based boot rules (MAC prefix / arch →
|
||||
/// target) plus the optional boot-decision webhook. Consulted by the
|
||||
/// top-level boot script after exact host bindings, before the menu.
|
||||
pub boot_rules: BootRulesStore,
|
||||
/// v0.7.0: short-lived access tokens for unattended answer files.
|
||||
/// Minted into every generated answer-file URL; the serving endpoint
|
||||
/// requires one (or an operator session) once an admin exists.
|
||||
pub boot_tokens: BootTokens,
|
||||
/// Operator-controlled UI overrides (custom logo). When the
|
||||
/// operator hasn't uploaded anything, the WebUI serves the bundled
|
||||
/// rainbow-horizon mark.
|
||||
|
||||
Reference in New Issue
Block a user