Fixed the secure boot enrollment script

This commit is contained in:
Audiobuzz
2026-06-20 12:16:37 +00:00
parent 33583bb4d8
commit d2b2156a22
7 changed files with 194 additions and 45 deletions
+28 -2
View File
@@ -622,10 +622,29 @@ smoke test.
Removes `rd.dot1x=0`/`ip=dhcp`; the hook owns the link (macsec0). Removes `rd.dot1x=0`/`ip=dhcp`; the hook owns the link (macsec0).
- **NVMe discovery by DNS:** `nvmet_traddr=nvme.fleet.lab` (CI), resolved at boot - **NVMe discovery by DNS:** `nvmet_traddr=nvme.fleet.lab` (CI), resolved at boot
by the serving dnsmasq — drop the hardcoded `192.168.50.10`. by the serving dnsmasq — drop the hardcoded `192.168.50.10`.
- **Signing:** wire `sb_key`/`sb_cert` (CI/HSM secrets) for a signed UKI; enable - **Signing — SIGNED-UKI + SECURE-BOOT-ON PATH BENCH-VERIFIED on the Proxmox VM
Secure Boot on targets. Until then the loud unsigned warning must stay. (HTTP boot, 2026-06-20).** CI signs the UKI when `SB_KEY`/`SB_CERT` secrets are
set (`db` key); `fleet-sb-enroll` enrols db→KEK→PK from the baked public `.auth`
files; OVMF then boots the signed UKI under enforcing Secure Boot. Confirmed
end-to-end: CI-signed UKI verifies (`sbverify`), enrolment succeeds, VM boots
with `mokutil --sb-state` = enabled.
**Key generation + enrolment procedure: [secure-boot-keys.md](secure-boot-keys.md)** **Key generation + enrolment procedure: [secure-boot-keys.md](secure-boot-keys.md)**
(the PK/KEK/db trio; `db` = `sb_key`/`sb_cert`, PK/KEK stay offline). (the PK/KEK/db trio; `db` = `sb_key`/`sb_cert`, PK/KEK stay offline).
- **Bug fixed during bring-up (2026-06-20):** `fleet-sb-enroll` built its 4-byte
EFI attribute prefix in a bash variable (`ATTR=$'\x27\x00\x00\x00'`). Bash
strings can't hold NULs → only `0x27` survived → efivarfs read a corrupt
attribute u32 → every write failed with `EINVAL` ("dd: Invalid argument").
Now emitted directly with `printf` at write time. (Red herring on the way:
Proxmox EFI disks default to `pre-enrolled-keys=1`, so `mokutil --db` shows
the MS cert even in Setup Mode — looked like a non-empty-db rejection but was
the NUL bug all along; it failed identically on a clean `pre-enrolled-keys=0`
disk.)
- **REMAINING for production:** (a) **secure path** — re-verify signed boot with
`disable_dot1x=false` (802.1X/MACsec), not just the test path; (b) **820 / PXE
path** — sign `snponly.efi` with the same `db` key so the iPXE front-end also
passes Secure Boot (the VM's HTTP path has no iPXE stage, so this is still
unverified on real PXE hardware); (c) confirm signing is reproducible (verity
hash stable across two signed builds).
- **PXE-only iPXE fallback — BENCH-VERIFIED on the EliteBook 820 G4 (2026-06-20).** - **PXE-only iPXE fallback — BENCH-VERIFIED on the EliteBook 820 G4 (2026-06-20).**
Firmware without UEFI HTTP boot chainloads `serving/tftp/snponly.efi` → renders Firmware without UEFI HTTP boot chainloads `serving/tftp/snponly.efi` → renders
`autoexec.ipxe` (ifopen + DHCP-retry + `imgargs <real cmdline>`) → UKI over HTTP `autoexec.ipxe` (ifopen + DHCP-retry + `imgargs <real cmdline>`) → UKI over HTTP
@@ -638,6 +657,13 @@ smoke test.
(iii) iPXE aborts the script on any unguarded command failure (use `||`); (iii) iPXE aborts the script on any unguarded command failure (use `||`);
(iv) Secure Boot OFF makes systemd-stub take iPXE's load options as the cmdline, (iv) Secure Boot OFF makes systemd-stub take iPXE's load options as the cmdline,
so the entrypoint extracts the UKI's real `.cmdline` and feeds it via `imgargs`. so the entrypoint extracts the UKI's real `.cmdline` and feeds it via `imgargs`.
**Tidied 2026-06-20** once PortFast was identified: dropped the `autoexec.ipxe` +
`ifopen` + DHCP-retry STP workaround; `boot.ipxe` is now just
`dhcp`+`imgfetch`+`imgargs`+`boot` reached via normal iPXE autoboot. Re-verified
on the 820 G4. **SB-on simplification:** when Secure Boot is enabled the cmdline
injection is unnecessary (the stub ignores the loader cmdline) — collapse
`boot.ipxe` to a plain `chain` of the UKI and drop the `.cmdline` extraction +
`binutils` + the artifact mount from the dnsmasq service.
- **Sign iPXE for the PXE-only fallback (Secure Boot, production).** The lab - **Sign iPXE for the PXE-only fallback (Secure Boot, production).** The lab
`snponly.efi` is **UNSIGNED** → that path needs **Secure Boot OFF**. For `snponly.efi` is **UNSIGNED** → that path needs **Secure Boot OFF**. For
production: `sbsign` the iPXE binary with the fleet **db** key (only `db` needed — production: `sbsign` the iPXE binary with the fleet **db** key (only `db` needed —
+29
View File
@@ -130,6 +130,35 @@ on a trusted/isolated network (see TODO #10).
Only the **public** certs/`.esl`/`.auth` reach the workstation — never copy Only the **public** certs/`.esl`/`.auth` reach the workstation — never copy
`PK.key`/`KEK.key`/`db.key` onto a host. `PK.key`/`KEK.key`/`db.key` onto a host.
### Troubleshooting `fleet-sb-enroll` (bench, 2026-06-20)
**`dd: ... Invalid argument` (EINVAL) on the `db` write** = the firmware's
`SetVariable` rejected the payload (EFI_INVALID_PARAMETER), *not* an auth/Setup
Mode failure (that surfaces as EACCES / "Permission denied"). Diagnose top-down:
- **Is the `.auth` actually a signed authenticated variable?** First 16 bytes are
an `EFI_TIME`: `sudo od -An -tx1 -N16 db.auth` → a valid one starts with the
year little-endian (2026 = `ea 07`). If it starts with `a1 59 c0 a5 …` it's a
bare **ESL** (the `sign-efi-sig-list` step was skipped); `30 82 …` is a raw DER
cert. Re-create the `.auth` (step 2) and re-bake.
- **The 4-byte attribute prefix must contain its NUL bytes.** A bash *variable*
**cannot** hold NULs — `ATTR=$'\x27\x00\x00\x00'` silently truncates to the
single byte `0x27`, so efivarfs reads a corrupt attribute u32 and the kernel
returns EINVAL **before the firmware is even called**. This was a real bug in an
early `fleet-sb-enroll`; the fix emits the prefix with `printf '\x27\x00\x00\x00'`
at write time (never via a variable). If you hand-roll an enrolment, do the same.
- **Proxmox / OVMF red herring:** VM EFI disks default to `pre-enrolled-keys=1`,
so `mokutil --db` shows the **Microsoft** cert (`Windows Production PCA 2011`,
owner `77fa9abd-…`) *even in Setup Mode*. This looks like a "db not empty →
rejected" problem but isn't — the write fails identically on a clean
`pre-enrolled-keys=0` disk if the NUL bug is present. For a clean OVMF test bed:
`qm set <vmid> --efidisk0 <storage>:1,efitype=4m,pre-enrolled-keys=0`.
**Verified:** with the fix, a Proxmox VM enrols db→KEK→PK from the baked `.auth`
files and boots the CI-signed UKI under **enforcing Secure Boot** over the HTTP
boot path (`mokutil --sb-state` = enabled). The PXE/iPXE front-end additionally
needs `snponly.efi` signed with `db` — see the iPXE section below.
## 4. Wire `db` into the build ## 4. Wire `db` into the build
```bash ```bash
+26 -12
View File
@@ -8,6 +8,11 @@
> >
> **A&A framework:** ASD *Information Security Manual* (ISM) — engagement target > **A&A framework:** ASD *Information Security Manual* (ISM) — engagement target
> **May 2026 release**. > **May 2026 release**.
>
> **Annex version:** 0.2 (2026-06-20). v0.2 reflects: STIG hardening applied +
> bench-verified, USBGuard device control enabled, admin `staff_u` confinement,
> audit offload verified, UKI signing wired (not yet enforced — new R-13),
> PXE/iPXE boot path added.
--- ---
@@ -74,8 +79,9 @@ ISM/PSPF style). Ratings are **pre-treatment** unless stated; the AO accepts the
| Topic | ISM (rep.) | Requirement intent | System implementation | Status | Residual | | Topic | ISM (rep.) | Requirement intent | System implementation | Status | Residual |
|---|---|---|---|---|---| |---|---|---|---|---|---|
| Hardened OS to ASD/vendor guidance | ISM-1407*, ISM-1408* | Apply a recognised hardening baseline. | **DISA STIG** (SSG `profile_stig`, RHEL 9) via `oscap --remediate` with documented tailoring ([stig-deviations.md](stig-deviations.md)). | Partial | R-03 (CI report-only/disabled now) | | Hardened OS to ASD/vendor guidance | ISM-1407*, ISM-1408* | Apply a recognised hardening baseline. | **DISA STIG** (SSG `profile_stig`, RHEL 9) via `oscap --remediate` + documented tailoring + per-build deviations report ([stig-deviations.md](stig-deviations.md)); **applied + bench-verified 2026-06-20**, all REVIEW rows triaged. | Partial | R-03 (CI must ship `enable_stig=true` + signed/SB-on) |
| Application control / allow-listing | ISM-0843*, ISM-1490*, ISM-1657* | Only approved executables run. | **fapolicyd** (RPM-trust + one trusted kiosk binary) + immutable dm-verity root. | Implemented | — | | Application control / allow-listing | ISM-0843*, ISM-1490*, ISM-1657* | Only approved executables run. | **fapolicyd** (RPM-trust + two trusted local binaries: kiosk-session, fleet-sb-enroll) + immutable dm-verity root. | Implemented | — |
| Device / removable-media control | ISM-0341*, ISM-1551* | Control USB / peripheral devices. | **USBGuard enforcing** (`ImplicitPolicyTarget=block` + hardware-independent HID/hub allowlist + LinuxAudit). Verified: USB mass storage blocked, console input preserved. | Implemented | — |
| Software / OS integrity | ISM-1493* | Detect unauthorised modification. | **dm-verity** continuous block-level verification of the read-only root against a signed hash; **reproducible** build. | Implemented | — | | Software / OS integrity | ISM-1493* | Detect unauthorised modification. | **dm-verity** continuous block-level verification of the read-only root against a signed hash; **reproducible** build. | Implemented | — |
| Disable unneeded functionality | ISM-0380*, ISM-1416* | Minimise installed software/services. | `@^minimal` install; scanner tooling removed post-scan; FROM-scratch artifact image; kiosk = single app. | Implemented | — | | Disable unneeded functionality | ISM-0380*, ISM-1416* | Minimise installed software/services. | `@^minimal` install; scanner tooling removed post-scan; FROM-scratch artifact image; kiosk = single app. | Implemented | — |
| Hardened user applications (browser) | ISM-1486*, ISM-1412* | Lock down high-risk apps. | Chromium enterprise lockdown policy; weston kiosk; no shell/nav/plugins. | Implemented | — | | Hardened user applications (browser) | ISM-1486*, ISM-1412* | Lock down high-risk apps. | Chromium enterprise lockdown policy; weston kiosk; no shell/nav/plugins. | Implemented | — |
@@ -89,7 +95,7 @@ ISM/PSPF style). Ratings are **pre-treatment** unless stated; the AO accepts the
| Topic | ISM (rep.) | Requirement intent | System implementation | Status | Residual | | Topic | ISM (rep.) | Requirement intent | System implementation | Status | Residual |
|---|---|---|---|---|---| |---|---|---|---|---|---|
| Strong machine authentication | ISM-1546*, ISM-0974* | Mutual, certificate-based auth. | **802.1X EAP-TLS**, client key non-exportable in **TPM** (`0x81010001`), cert in TPM NV. | Partial | R-01 (not bench-verified; disabled in test builds), R-08 (placeholder CA) | | Strong machine authentication | ISM-1546*, ISM-0974* | Mutual, certificate-based auth. | **802.1X EAP-TLS**, client key non-exportable in **TPM** (`0x81010001`), cert in TPM NV. | Partial | R-01 (not bench-verified; disabled in test builds), R-08 (placeholder CA) |
| Privileged access restricted | ISM-1507*, ISM-0445* | Limit & control admin access. | Single key-only `wheel` admin; root login disabled. | Partial | R-05 | | Privileged access restricted | ISM-1507*, ISM-0445* | Limit & control admin access. | Single key-only `wheel` admin; root login disabled; admin **confined to `staff_u`** with a sudo `sysadm_r`/`sysadm_t` role/type transition (SELinux context elevates on privilege use). | Partial | R-05 |
| Secure remote administration | ISM-1506*, ISM-1232* | Hardened admin channel. | SSH **key-only**, password & keyboard-interactive off, hardened ciphers/MACs/KEX (STIG crypto policy; ECDSA/RSA keys — ed25519 excluded by policy). | Implemented | — | | Secure remote administration | ISM-1506*, ISM-1232* | Hardened admin channel. | SSH **key-only**, password & keyboard-interactive off, hardened ciphers/MACs/KEX (STIG crypto policy; ECDSA/RSA keys — ed25519 excluded by policy). | Implemented | — |
| No default/shared credentials | ISM-1304* | No baked credentials. | No per-host secrets in any artifact; identity from TPM at runtime; `machine-id` empty; host keys regenerated at first boot. | Implemented | — | | No default/shared credentials | ISM-1304* | No baked credentials. | No per-host secrets in any artifact; identity from TPM at runtime; `machine-id` empty; host keys regenerated at first boot. | Implemented | — |
| MFA for privileged users | ISM-1173*, ISM-1504* | MFA on privileged access. | Machine auth is cert+TPM (strong). **Human admin MFA on the management plane not yet enforced.** | Partial | R-05 | | MFA for privileged users | ISM-1173*, ISM-1504* | MFA on privileged access. | Machine auth is cert+TPM (strong). **Human admin MFA on the management plane not yet enforced.** | Partial | R-05 |
@@ -109,7 +115,7 @@ ISM/PSPF style). Ratings are **pre-treatment** unless stated; the AO accepts the
| Topic | ISM (rep.) | Requirement intent | System implementation | Status | Residual | | Topic | ISM (rep.) | Requirement intent | System implementation | Status | Residual |
|---|---|---|---|---|---| |---|---|---|---|---|---|
| Centralised event logging | ISM-0988*, ISM-1405* | Logs centrally collected. | `audisp-syslog`→rsyslog `omfwd` (disk-assisted queue) → dedicated collector (`serving/audit-collector/`). | Partial | R-07 | | Centralised event logging | ISM-0988*, ISM-1405* | Logs centrally collected. | `audisp-syslog`→rsyslog `omfwd` (disk-assisted queue) → dedicated collector (`serving/audit-collector/`); **bench-verified end-to-end 2026-06-20**. auditd `space_left_action`→syslog (no MTA). | Partial | R-07 |
| Required events logged | ISM-0582*, ISM-1537* | Log security-relevant events. | STIG auditd rule set; kernel `audit=1`, `audit_backlog_limit=8192`. | Implemented | — | | Required events logged | ISM-0582*, ISM-1537* | Log security-relevant events. | STIG auditd rule set; kernel `audit=1`, `audit_backlog_limit=8192`. | Implemented | — |
| Protect logs in transit | ISM-1432*, ISM-0407* | Encrypt/authenticate log transport. | **Plaintext** offload on isolated LAN (rsyslog TLS rules waived — see [STIG #6](stig-deviations.md)). | Waived (lab) | **R-07** | | Protect logs in transit | ISM-1432*, ISM-0407* | Encrypt/authenticate log transport. | **Plaintext** offload on isolated LAN (rsyslog TLS rules waived — see [STIG #6](stig-deviations.md)). | Waived (lab) | **R-07** |
| Log retention & integrity | ISM-0859*, ISM-1815* | Retain & protect logs. | Per-source-host files on collector; retention policy & tamper-protection not yet defined. | Planned | R-07 | | Log retention & integrity | ISM-0859*, ISM-1815* | Retain & protect logs. | Per-source-host files on collector; retention policy & tamper-protection not yet defined. | Planned | R-07 |
@@ -144,7 +150,7 @@ ISM/PSPF style). Ratings are **pre-treatment** unless stated; the AO accepts the
| Topic | ISM (rep.) | Requirement intent | System implementation | Status | Residual | | Topic | ISM (rep.) | Requirement intent | System implementation | Status | Residual |
|---|---|---|---|---|---| |---|---|---|---|---|---|
| Media sanitisation / no data remanence | ISM-0347*, ISM-1218* | Prevent data remanence. | **Diskless** — no persistent local media; writable layer is **RAM tmpfs**, gone at power-off. | Implemented | — | | Media sanitisation / no data remanence | ISM-0347*, ISM-1218* | Prevent data remanence. | **Diskless** — no persistent local media; writable layer is **RAM tmpfs**, gone at power-off. | Implemented | — |
| Tamper-evidence / boot integrity | ISM-1542*, ISM-0312* | Detect firmware/boot tampering. | **UEFI Secure Boot** + signed UKI + immutable signed cmdline + dm-verity; TPM measurements available for attestation. | Partial | R-11 (remote attestation not yet implemented) | | Tamper-evidence / boot integrity | ISM-1542*, ISM-0312* | Detect firmware/boot tampering. | Design: **UEFI Secure Boot** + signed UKI (+ signed iPXE on the PXE path) + immutable signed cmdline + dm-verity; TPM measurements available. Signing **wired in CI** + key/enrolment procedure + baked `fleet-sb-enroll` helper, but **lab runs unsigned with SB OFF**. | Partial | **R-13** (signing not enforced), R-11 (no remote attestation) |
| Device identification | ISM-1195* | Uniquely identify devices. | Identity derived from TPM cert (hostnqn from cert serial); no spoofable per-host config. | Implemented | — | | Device identification | ISM-1195* | Uniquely identify devices. | Identity derived from TPM cert (hostnqn from cert serial); no spoofable per-host config. | Implemented | — |
### 2.11 Guidelines for Procurement, Outsourcing & Evaluated Products ### 2.11 Guidelines for Procurement, Outsourcing & Evaluated Products
@@ -165,11 +171,12 @@ asked to accept. Treatments map to [docs/TODO.md](TODO.md) (working POA&M).
|---|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|---|
| **R-01** | Secure path (802.1X EAP-TLS + MACsec) **implemented but not bench-verified end-to-end**; disabled in test builds (`disable_dot1x=true`). Until verified, devices may attach to an unauthenticated/unencrypted link. | 2.4, 2.7, 2.8 (ISM-1546*, 0520*, 1187*) | Likely × Major → **High** | Test path on an isolated lab LAN; full auth stack present (dormant); design follows ASD intent. | Full boot-chain bench test (swtpm + hostapd + FreeRADIUS): port `Authorized`, macsec0 addressed, MKA survives switch-root, NVMe root mounts. Re-enable in CI. | **Low** (once verified) | Platform team — *before production ATO* | | **R-01** | Secure path (802.1X EAP-TLS + MACsec) **implemented but not bench-verified end-to-end**; disabled in test builds (`disable_dot1x=true`). Until verified, devices may attach to an unauthenticated/unencrypted link. | 2.4, 2.7, 2.8 (ISM-1546*, 0520*, 1187*) | Likely × Major → **High** | Test path on an isolated lab LAN; full auth stack present (dormant); design follows ASD intent. | Full boot-chain bench test (swtpm + hostapd + FreeRADIUS): port `Authorized`, macsec0 addressed, MKA survives switch-root, NVMe root mounts. Re-enable in CI. | **Low** (once verified) | Platform team — *before production ATO* |
| **R-02** | `debug_shell=true` bakes a **passwordless root shell** on a tty — an undocumented privileged access path. | 2.5 (ISM-1491*) | Possible × Severe → **High** | Lab-only; physical access required; isolated environment. | Set `debug_shell=false` for all non-lab builds; assert absent in CI. | **Low** | Platform team — *before production* | | **R-02** | `debug_shell=true` bakes a **passwordless root shell** on a tty — an undocumented privileged access path. | 2.5 (ISM-1491*) | Possible × Severe → **High** | Lab-only; physical access required; isolated environment. | Set `debug_shell=false` for all non-lab builds; assert absent in CI. | **Low** | Platform team — *before production* |
| **R-03** | STIG hardening currently **report-only / disabled in CI** (`enable_stig=false`); shipped images may be unhardened. | 2.3 (ISM-1407*/1408*) | Possible × Major → **Medium** | Tailoring + register exist; SELinux/fapolicyd still on; re-enable is a single flag. | Flip `ENABLE_STIG="true"`; confirm scan evaluates >0 rules; triage REVIEW rows (buckets A/B/C in TODO #2). | **Low** | Platform team — *before assessment* | | **R-03** | STIG hardening **applied + bench-verified** (2026-06-20, all REVIEW rows triaged); residual is ensuring **CI ships `enable_stig=true`** for production builds (it was toggled off during bring-up). | 2.3 (ISM-1407*/1408*) | Possible × Moderate → **Medium** | Tailoring + register + per-build report; SELinux/fapolicyd/USBGuard on; verified on a real hardened build. | Confirm `ENABLE_STIG="true"` in CI; keep the 0-eval guard; re-run the deviations report on the assessed build. | **Low** | Platform team — *before assessment* |
| **R-04** | NVMe/TCP **root traffic plaintext** on the LAN — exposure of OS content / injection if the segment is compromised. | 2.9 (ISM-1139*/1453*) | Unlikely × Major → **Medium** | Isolated boot LAN; MACsec on the access link (once R-01 done) protects the first hop; dm-verity makes injected root blocks fail verification (integrity preserved even if confidentiality isn't). | Production: TLS/IPsec for the storage transport, or rely on MACsec end-to-end across the fabric; document the decision. | **Low–Medium** | Platform/network — *production* | | **R-04** | NVMe/TCP **root traffic plaintext** on the LAN — exposure of OS content / injection if the segment is compromised. | 2.9 (ISM-1139*/1453*) | Unlikely × Major → **Medium** | Isolated boot LAN; MACsec on the access link (once R-01 done) protects the first hop; dm-verity makes injected root blocks fail verification (integrity preserved even if confidentiality isn't). | Production: TLS/IPsec for the storage transport, or rely on MACsec end-to-end across the fabric; document the decision. | **Low–Medium** | Platform/network — *production* |
| **R-05** | **NOPASSWD key-only admin**; no per-host or rotatable access model; human admin MFA on the mgmt plane not enforced. | 2.4 (ISM-1507*/1173*) | Possible × Moderate → **Medium** | Single fleet-generic admin, key-only, root disabled, ECDSA/RSA key, fully audited; no interactive password to attack. | Per-host/rotatable access (SSH CA / config-agent) + admin MFA on the management plane. | **Low–Medium** | Platform team — *roadmap* | | **R-05** | **NOPASSWD key-only admin**; no per-host or rotatable access model; human admin MFA on the mgmt plane not enforced. | 2.4 (ISM-1507*/1173*) | Possible × Moderate → **Medium** | Single fleet-generic admin, key-only, root disabled, ECDSA/RSA key, **now SELinux-confined to `staff_u`** with sudo role/type elevation, fully audited; no interactive password to attack. | Per-host/rotatable access (SSH CA / config-agent) + admin MFA on the management plane. | **Low–Medium** | Platform team — *roadmap* |
| **R-06** | **FIPS off**; ISM **AACA/AACP conformance not formally asserted**; crypto-module evaluation status unconfirmed. | 2.9 (ISM-0471*/1139*/1277*) | Possible × Major → **Medium** | Modern STIG crypto policy; non-exportable TPM key; no deliberately weak algorithms. Acceptable at OFFICIAL; **mandatory to resolve for PROTECTED+.** | Assert AACA/AACP conformance; decide on FIPS module / evaluated crypto alongside Secure Boot signing. | **Low** (at appropriate classification) | Security + Platform — *before PROTECTED+* | | **R-06** | **FIPS off**; ISM **AACA/AACP conformance not formally asserted**; crypto-module evaluation status unconfirmed. | 2.9 (ISM-0471*/1139*/1277*) | Possible × Major → **Medium** | Modern STIG crypto policy; non-exportable TPM key; no deliberately weak algorithms. Acceptable at OFFICIAL; **mandatory to resolve for PROTECTED+.** | Assert AACA/AACP conformance; decide on FIPS module / evaluated crypto alongside Secure Boot signing. | **Low** (at appropriate classification) | Security + Platform — *before PROTECTED+* |
| **R-07** | Audit-log **offload plaintext**, **single-site**, **no SIEM alerting**; logs interceptable/repudiable and not actively reviewed. | 2.6 (ISM-1432*/0109*/0859*) | Possible × Moderate → **Medium** | Isolated LAN; disk-assisted queue (no loss on collector blip); auditd local copy; per-source files. | rsyslog **TLS** (gtls/6514) + bundle CA in image (re-select the 3 waived `rsyslog_encrypt_offload_*` rules); define retention + integrity; forward to SIEM with alerting. | **Low** | Platform/SecOps — *production* | | **R-07** | Audit-log **offload plaintext**, **single-site**, **no SIEM alerting**; logs interceptable/repudiable and not actively reviewed. (Transport **bench-verified working** 2026-06-20.) | 2.6 (ISM-1432*/0109*/0859*) | Possible × Moderate → **Medium** | Isolated LAN; disk-assisted queue (no loss on collector blip); auditd local copy; per-source files; LinuxAudit captures USBGuard events. | rsyslog **TLS** (gtls/6514) + bundle CA in image (re-select the 3 waived `rsyslog_encrypt_offload_*` rules); define retention + integrity; forward to SIEM with alerting. | **Low** | Platform/SecOps — *production* |
| **R-13** | **Boot chain unsigned / Secure Boot OFF** in the lab — the UKI and (on the PXE path) iPXE are not signed and SB is not enforced, so a substituted boot artifact would not be rejected by firmware. | 2.10 (ISM-1542*/0312*) | Possible × Major → **Medium** | dm-verity still rejects a tampered *root*; isolated lab LAN; signing is **wired in CI** + key/enrolment procedure + baked `fleet-sb-enroll` ready; only the enforcement is pending. | Enrol fleet `db` (PK/KEK/db per [secure-boot-keys.md](secure-boot-keys.md)); set `SB_KEY`/`SB_CERT` CI secrets; `sbsign` the UKI **and** iPXE; enable Secure Boot on targets. | **Low** | Platform team — *before production* |
| **R-08** | **Placeholder RADIUS CA** (`files/etc/dot1x/radius-ca.pem`) — real EAP-TLS trust anchor not provisioned; auth cannot succeed and trust is unestablished. | 2.4 (ISM-1546*) | Certain (lab) × Major → **Medium** | Documented as a placeholder; environment-specific provisioning is the intended path; no real CA committed. | Provision the environment's real RADIUS CA out-of-band (not committed unless classification permits). | **Low** | Environment owner — *before production* | | **R-08** | **Placeholder RADIUS CA** (`files/etc/dot1x/radius-ca.pem`) — real EAP-TLS trust anchor not provisioned; auth cannot succeed and trust is unestablished. | 2.4 (ISM-1546*) | Certain (lab) × Major → **Medium** | Documented as a placeholder; environment-specific provisioning is the intended path; no real CA committed. | Provision the environment's real RADIUS CA out-of-band (not committed unless classification permits). | **Low** | Environment owner — *before production* |
| **R-09** | **Host firewall disabled**; host exposes more network surface than necessary. | 2.7 (ISM-1416*) | Possible × Moderate → **Low–Medium** | Isolated LAN; minimal services; egress controlled at the network/serving layer; no kiosk inbound. | Re-enable firewalld with explicit allow rules (NVMe/TCP `:4420`, DHCP, log offload, SSH) once the secure path is verified. | **Low** | Platform/network — *after R-01* | | **R-09** | **Host firewall disabled**; host exposes more network surface than necessary. | 2.7 (ISM-1416*) | Possible × Moderate → **Low–Medium** | Isolated LAN; minimal services; egress controlled at the network/serving layer; no kiosk inbound. | Re-enable firewalld with explicit allow rules (NVMe/TCP `:4420`, DHCP, log offload, SSH) once the secure path is verified. | **Low** | Platform/network — *after R-01* |
| **R-10** | **Patch SLA undefined** — no documented cadence for rebuilding/redeploying against new CVEs. | 2.5 (ISM-1144*/1472*) | Likely × Moderate → **Medium** | Atomic rebuild/redeploy model makes patching fast & uniform; reproducible builds. | Define patch cadence & critical-CVE SLA; automate rebuild triggers. | **Low** | Platform team — *roadmap* | | **R-10** | **Patch SLA undefined** — no documented cadence for rebuilding/redeploying against new CVEs. | 2.5 (ISM-1144*/1472*) | Likely × Moderate → **Medium** | Atomic rebuild/redeploy model makes patching fast & uniform; reproducible builds. | Define patch cadence & critical-CVE SLA; automate rebuild triggers. | **Low** | Platform team — *roadmap* |
@@ -192,10 +199,12 @@ Likelihood ↓
``` ```
*The heatmap shows pre-treatment positions; every item has a treatment to Low / *The heatmap shows pre-treatment positions; every item has a treatment to Low /
Low–Medium. The AO is asked to authorise on the basis that R-01, R-02, R-03, R-08 Low–Medium. The AO is asked to authorise on the basis that **R-01, R-02, R-08,
and R-12 are **closed before production**, and R-04/R-05/R-06/R-07/R-09/R-10/R-11 R-12 and R-13** (and confirming R-03's `enable_stig=true`) are **closed before
are either accepted with compensating controls (isolated-LAN lab) or carried on production**, and R-04/R-05/R-06/R-07/R-09/R-10/R-11 are either accepted with
the POA&M with target dates.* compensating controls (isolated-LAN lab) or carried on the POA&M with target
dates. Newly strengthened in v0.2: device control (USBGuard, now Implemented),
admin SELinux confinement (R-05), and STIG applied+verified (R-03 reduced).*
--- ---
@@ -215,6 +224,11 @@ the POA&M with target dates.*
anything flagged **REVIEW** is an unjustified finding. anything flagged **REVIEW** is an unjustified finding.
6. **Confirm lab-only flags are off** in the assessed build: `debug_shell=false`, 6. **Confirm lab-only flags are off** in the assessed build: `debug_shell=false`,
`enable_stig=true`, `disable_dot1x=false`, real RADIUS CA in place. `enable_stig=true`, `disable_dot1x=false`, real RADIUS CA in place.
7. **Confirm boot-chain signing is enforced** (R-13): `db` enrolled, Secure Boot
ON, UKI + iPXE signed (`sbverify`). The PXE/iPXE path's SB-OFF cmdline
workaround should be a no-op once SB is on.
8. **Witness device control** (USBGuard): a USB mass-storage device is blocked and
logged, console HID still works.
--- ---
+69 -28
View File
@@ -15,10 +15,10 @@
|---|---| |---|---|
| System name | Diskless Fleet Boot System ("the fleet") | | System name | Diskless Fleet Boot System ("the fleet") |
| Document type | System Security Plan (SSP) | | Document type | System Security Plan (SSP) |
| Version | 0.1 (DRAFT — pre-assessment) | | Version | 0.2 (DRAFT — pre-assessment) |
| Date | 2026-06-19 | | Date | 2026-06-20 |
| Author / maintainer | System Owner (delegate) | | Author / maintainer | System Owner (delegate) |
| Status | Lab / pre-production. Secure path (802.1X/MACsec) not yet bench-verified. | | Status | Lab / pre-production. STIG hardening applied + bench-verified (unsigned, Secure Boot OFF); secure path (802.1X/MACsec) not yet bench-verified. |
| Companion documents | [Annex A — ISM control cross-reference & residual risk](ssp-annex-a-ism-residual-risk.md); [Architecture design v2](diskless-fleet-design-v2.pdf); [Design errata](design-v2-errata.md); [STIG deviation register](stig-deviations.md); [Backlog / POA&M source](TODO.md) | | Companion documents | [Annex A — ISM control cross-reference & residual risk](ssp-annex-a-ism-residual-risk.md); [Architecture design v2](diskless-fleet-design-v2.pdf); [Design errata](design-v2-errata.md); [STIG deviation register](stig-deviations.md); [Backlog / POA&M source](TODO.md) |
> **Currency caveat (read before relying on control numbers).** This SSP and its > **Currency caveat (read before relying on control numbers).** This SSP and its
@@ -72,8 +72,19 @@ manifest. One commit = one release = one digest = one manifest entry.
### 2.2 Boot and trust chain (control flow) ### 2.2 Boot and trust chain (control flow)
1. **UEFI Secure Boot** measures and verifies the UKI signature (vendor/Secure > **Boot transport (two paths, auto-selected):** HTTP-boot-capable firmware
Boot key) before execution. > fetches the UKI directly over UEFI HTTP boot. Firmware **without** HTTP boot
> (e.g. HP EliteBook 820 G4) falls back to **PXE → iPXE → HTTP** (dnsmasq serves
> iPXE over TFTP, which chainloads the same UKI). Both land on the same signed
> UKI. **Lab status:** Secure Boot is currently **OFF** and the UKI/iPXE are
> **unsigned** — signing is wired in CI and the key procedure is documented
> ([secure-boot-keys.md](secure-boot-keys.md)) but not yet enforced (residual
> R-03/signing in Annex A).
1. **UEFI Secure Boot** (when enabled) measures and verifies the UKI signature
against the enrolled `db` key before execution. On the PXE/iPXE path the iPXE
binary is likewise verified against `db`; only the fleet's own `db` need be
enrolled (no Microsoft CA / shim).
2. **UKI (systemd-stub)** carries the kernel, the `--no-hostonly` initramfs, and 2. **UKI (systemd-stub)** carries the kernel, the `--no-hostonly` initramfs, and
an **immutable, signed kernel command line** (includes the dm-verity root an **immutable, signed kernel command line** (includes the dm-verity root
hash and STIG kernel parameters). No GRUB. hash and STIG kernel parameters). No GRUB.
@@ -102,7 +113,9 @@ the tmpfs overlay, the TPM-backed identity, and the hardened OS configuration.
The boundary's external interfaces are: (a) the **access link** (802.1X-controlled The boundary's external interfaces are: (a) the **access link** (802.1X-controlled
port, MACsec-encrypted); (b) the **NVMe/TCP** root storage session; (c) port, MACsec-encrypted); (b) the **NVMe/TCP** root storage session; (c)
**outbound audit log** forwarding; (d) the **kiosk application** endpoint the **outbound audit log** forwarding; (d) the **kiosk application** endpoint the
browser renders. Each crossing is a control point addressed in Annex A. browser renders; (e) the **boot transport** (UEFI HTTP boot, or PXE/TFTP→iPXE)
that delivers the UKI; and (f) **USB/peripheral** ports, now mediated by USBGuard
(§5.2). Each crossing is a control point addressed in Annex A.
### 2.4 Data and classification ### 2.4 Data and classification
@@ -151,12 +164,19 @@ This system follows the ISM A&A lifecycle:
Milestones (POA&M)** (this repo's [TODO.md](TODO.md) is the working POA&M Milestones (POA&M)** (this repo's [TODO.md](TODO.md) is the working POA&M
source). source).
**Current status:** Pre-assessment **DRAFT**. The system is functional in a lab **Current status:** Pre-assessment **DRAFT (v0.2)**. The system is functional in a
configuration. Several controls are **partial or deferred** and are tracked as lab configuration. **Progress since v0.1 (2026-06-20):** DISA STIG hardening
residual risks with treatment plans (Annex A §3). The security-critical path applied and **bench-verified** on a real build (kiosk, key-only SSH, audit
(802.1X/MACsec) is **implemented but not yet bench-verified end-to-end** and is offload, DHCP-named host, NVMe/verity root all good with hardening on); USBGuard
currently disabled in test builds (`disable_dot1x=true`) — this is the single device control enabled + verified; admin confined to `staff_u`; UKI signing wired
largest gate on a production authorisation. in CI + Secure Boot key/enrolment procedure documented; both **HTTP-boot and
PXE/iPXE** boot paths working (the latter verified on an EliteBook 820 G4).
Several controls remain **partial or deferred**, tracked as residual risks with
treatments (Annex A §3). The two largest gates on a production ATO: (a) the
secure path (**802.1X/MACsec**) is implemented but **not yet bench-verified** and
is disabled in test builds (`disable_dot1x=true`, R-01); (b) the lab runs
**unsigned with Secure Boot OFF** (R-13) and with a lab-only **passwordless-root
debug shell** that must be removed (R-02).
## 5. Security control implementation — by ISM cyber security principle ## 5. Security control implementation — by ISM cyber security principle
@@ -180,23 +200,43 @@ summarises the implementation posture.
- **Boot & OS integrity:** **Secure Boot** + **signed UKI** with an **immutable - **Boot & OS integrity:** **Secure Boot** + **signed UKI** with an **immutable
cmdline**; **dm-verity** read-only root (continuous cryptographic integrity); cmdline**; **dm-verity** read-only root (continuous cryptographic integrity);
**erofs** immutable filesystem; **reproducible** build (verity hash is a pure **erofs** immutable filesystem; **reproducible** build (verity hash is a pure
function of inputs). function of inputs). Signing is **wired in CI** (`sbsign`/ukify via
- **System hardening:** **DISA STIG** baseline via OpenSCAP/SSG with a documented `SB_KEY`/`SB_CERT` secrets) with a documented PK/KEK/db key + enrolment
tailoring; **SELinux enforcing**; **fapolicyd** application allow-listing (the procedure ([secure-boot-keys.md](secure-boot-keys.md)) and a baked, efitools-free
exec guard for the writable RAM overlay that dm-verity cannot cover); enrolment helper (`fleet-sb-enroll`); **not yet enforced in the lab** (SB OFF,
**key-only SSH**, root login disabled, hardened ciphers/MACs/KEX; **kiosk unsigned — see Annex A).
lockdown** (single locked browser, no shell/navigation). - **System hardening (DISA STIG applied + bench-verified 2026-06-20):** STIG
baseline via OpenSCAP/SSG with a documented tailoring + per-build deviations
report; all REVIEW rows triaged. **SELinux enforcing**; **fapolicyd**
application allow-listing (the exec guard for the writable RAM overlay dm-verity
cannot cover); **USBGuard enforcing** (`ImplicitPolicyTarget=block` + a
hardware-independent HID/hub allowlist + LinuxAudit — verified blocks USB mass
storage while keeping console input; device/removable-media control); **key-only
SSH**, root login disabled, hardened ciphers/MACs/KEX (note: STIG crypto policy
drops ed25519 → admin key must be ECDSA/RSA); **kiosk lockdown** (single locked
browser, no shell/navigation); **postfix removed** (no local MTA — audit-failure
notification rides the remote offload, not email).
- **Privileged access:** single **key-only `wheel` admin**, root locked. The admin
is now **confined to the `staff_u` SELinux user** with a sudoers role/type
transition (`sysadm_r`/`sysadm_t`) so privilege elevation re-labels the SELinux
context (STIG `selinux_context_elevation_for_sudo`). Still **NOPASSWD** (the
account is passwordless/key-only) and fleet-generic — see R-05.
- **No persistent attack surface:** diskless; overlay discarded each boot; no - **No persistent attack surface:** diskless; overlay discarded each boot; no
per-host secrets in the image. per-host secrets in the image.
- *Gaps / decisions:* **FIPS OFF** (lab phase); **host firewall disabled**; - *Gaps / decisions:* **FIPS OFF** (lab phase); **host firewall disabled** (the
NVMe/TCP and audit offload **plaintext on the isolated LAN**; NOPASSWD key-only workstation; the serving host's ufw is configured); NVMe/TCP and audit offload
admin; **placeholder RADIUS CA**. See Annex A residual risks. **plaintext on the isolated LAN**; NOPASSWD admin; **placeholder RADIUS CA**;
signing not yet enforced (SB OFF). See Annex A residual risks.
### 5.3 Detect ### 5.3 Detect
- **auditd** enabled with STIG audit rules; kernel `audit=1` + - **auditd** enabled with STIG audit rules; kernel `audit=1` +
`audit_backlog_limit` in the signed cmdline. `audit_backlog_limit` in the signed cmdline. USBGuard device events logged via
the LinuxAudit backend. auditd `space_left_action` repointed to **syslog**
(no local MTA), so audit-volume alerts ride the remote offload.
- **Centralised log offload** via rsyslog (`audisp-syslog` → rsyslog `omfwd`, - **Centralised log offload** via rsyslog (`audisp-syslog` → rsyslog `omfwd`,
disk-assisted queue) to a dedicated **audit collector** (`serving/audit-collector/`). disk-assisted queue) to a dedicated **audit collector** (`serving/audit-collector/`).
**Bench-verified end-to-end 2026-06-20** (records reach the collector,
per-source-host files).
- *Gaps:* offload currently **plaintext** (TLS planned, R-07); offload is - *Gaps:* offload currently **plaintext** (TLS planned, R-07); offload is
**local site only**; no SIEM correlation/alerting defined yet. **local site only**; no SIEM correlation/alerting defined yet.
@@ -215,11 +255,11 @@ AO will expect a maturity view:
| Mitigation | Posture | Notes | | Mitigation | Posture | Notes |
|---|---|---| |---|---|---|
| Application control | **Strong** | fapolicyd allow-listing + immutable verified root; only RPM-trusted (plus one trusted kiosk binary) executables run. | | Application control | **Strong** | fapolicyd allow-listing + immutable verified root; only RPM-trusted (plus two trusted local binaries: kiosk-session, fleet-sb-enroll) executables run. USBGuard enforces device control on USB ports. |
| Patch applications | **Process** | Patching = rebuild + re-sign + redeploy a new digest; cadence/SLA to be defined. | | Patch applications | **Process** | Patching = rebuild + re-sign + redeploy a new digest; cadence/SLA to be defined. |
| Configure MS Office macros | **N/A** | No office suite; kiosk is a locked browser. | | Configure MS Office macros | **N/A** | No office suite; kiosk is a locked browser. |
| User application hardening | **Strong (kiosk)** | Chromium locked down via enterprise policy; no plugins/shell/nav. | | User application hardening | **Strong (kiosk)** | Chromium locked down via enterprise policy; no plugins/shell/nav. |
| Restrict admin privileges | **Partial** | Single key-only `wheel` admin (NOPASSWD, see R-05); no per-host/rotatable model yet. | | Restrict admin privileges | **Partial** | Single key-only `wheel` admin, root locked, now **SELinux-confined to `staff_u`** with a sudo role/type transition (NOPASSWD, see R-05); no per-host/rotatable model or admin-MFA yet. |
| Patch operating systems | **Process** | Same rebuild/redeploy model; immutable image means uniform, atomic OS updates. | | Patch operating systems | **Process** | Same rebuild/redeploy model; immutable image means uniform, atomic OS updates. |
| Multi-factor authentication | **Strong (machine)** | Host auth is certificate + TPM-bound key (something-the-machine-has, non-exportable). Human admin MFA to be addressed for the management plane. | | Multi-factor authentication | **Strong (machine)** | Host auth is certificate + TPM-bound key (something-the-machine-has, non-exportable). Human admin MFA to be addressed for the management plane. |
| Regular backups | **N/A (by design)** | Diskless, stateless hosts hold nothing to back up; recoverability is re-provisioning from a pinned digest. Backup applies to serving-side state, out of scope here. | | Regular backups | **N/A (by design)** | Diskless, stateless hosts hold nothing to back up; recoverability is re-provisioning from a pinned digest. Backup applies to serving-side state, out of scope here. |
@@ -234,13 +274,14 @@ production ATO:
|---|---|---|---| |---|---|---|---|
| R-01 | Secure path (802.1X/MACsec) not yet bench-verified; currently disabled in test builds. | **High** | Treat — verify before production authorisation. | | R-01 | Secure path (802.1X/MACsec) not yet bench-verified; currently disabled in test builds. | **High** | Treat — verify before production authorisation. |
| R-02 | `debug_shell=true` bakes a **passwordless root shell** on a tty. | **High** | Treat — must be removed before production (lab-only). | | R-02 | `debug_shell=true` bakes a **passwordless root shell** on a tty. | **High** | Treat — must be removed before production (lab-only). |
| R-03 | STIG hardening temporarily **report-only / disabled in CI** (`enable_stig=false`). | **Medium** | Treat — re-enable before assessment. | | R-03 | STIG hardening **applied + bench-verified** (2026-06-20); residual is that CI ships **unsigned, Secure Boot OFF** and `enable_stig` must be confirmed on for production builds. | **Medium** | Treat — confirm `enable_stig=true` in CI + enforce signing/SB before assessment. |
| R-04 | NVMe/TCP root traffic **plaintext** on the lab LAN. | **Medium** | Accept (isolated LAN) / treat for production. | | R-04 | NVMe/TCP root traffic **plaintext** on the lab LAN. | **Medium** | Accept (isolated LAN) / treat for production. |
| R-05 | NOPASSWD key-only admin; no per-host or rotatable access model. | **Medium** | Accept with compensating controls / roadmap. | | R-05 | NOPASSWD key-only admin (now `staff_u`-confined); no per-host/rotatable access model or admin-MFA. | **Medium** | Accept with compensating controls / roadmap. |
| R-06 | **FIPS off**; ASD-approved-cryptography conformance not yet asserted. | **Medium** | Treat — required for PROTECTED+; revisit with signing. | | R-06 | **FIPS off**; ASD-approved-cryptography conformance not yet asserted. | **Medium** | Treat — required for PROTECTED+; revisit with signing. |
| R-07 | Audit-log offload **plaintext**, single-site, no SIEM alerting. | **Medium** | Treat — TLS offload + monitoring on roadmap. | | R-07 | Audit-log offload **plaintext** (bench-verified working), single-site, no SIEM alerting. | **Medium** | Treat — TLS offload + monitoring on roadmap. |
| R-08 | **Placeholder RADIUS CA** in the repo; real trust anchor not yet provisioned. | **Medium** | Treat — environment-specific, before production. | | R-08 | **Placeholder RADIUS CA** in the repo; real trust anchor not yet provisioned. | **Medium** | Treat — environment-specific, before production. |
| R-09 | Host **firewall disabled**. | **Low–Medium** | Accept (isolated LAN) / treat with explicit allow-rules. | | R-09 | Host **firewall disabled** (workstation). | **Low–Medium** | Accept (isolated LAN) / treat with explicit allow-rules. |
| R-13 | **Boot chain unsigned / Secure Boot OFF** in the lab (UKI + iPXE); CI signing wired but not enforced. | **Medium** | Treat — enrol `db`, enforce SB + sign UKI & iPXE before production. |
Each is detailed, ISM-cross-referenced, rated and assigned a treatment in Annex A. Each is detailed, ISM-cross-referenced, rated and assigned a treatment in Annex A.
+24
View File
@@ -114,6 +114,30 @@ reverts to a justified deviation; (b) reproducibility — `semanage` rebuilds th
SELinux policy store, so confirm the verity hash is stable across two builds (and SELinux policy store, so confirm the verity hash is stable across two builds (and
normalize in 2d hygiene if it drifts). normalize in 2d hygiene if it drifts).
## 13. Ctrl+Alt+Del console reboot hotkey kept enabled (decision 2026-06-20)
The RHEL 9 STIG disables the console reboot hotkey via two rules, both **waived**
in the tailoring:
- `disable_ctrlaltdel_reboot` — masks `ctrl-alt-del.target` (single Ctrl+Alt+Del).
- `disable_ctrlaltdel_burstaction` — sets `CtrlAltDelBurstAction=none` in
`/etc/systemd/system.conf` (the rapid 7× burst reboot).
**Why waived:** the STIG intent is to stop an **unauthenticated console user from
causing an unplanned reboot/outage**. On this fleet that risk is structurally
absent — the hosts are **diskless and stateless** (immutable erofs+dm-verity root,
tmpfs volatile overlay), so a console reboot loses nothing and persists nothing,
and a **field technician needs to recover a wedged kiosk from the keyboard when
SSH is unavailable**. The two rules are unselected so `--remediate` leaves the
systemd default (the hotkey reboots).
**Compensating control / scope:** the hotkey only triggers a **clean stateless
reboot** — it cannot exfiltrate data, alter the read-only root, or bypass auth to
a shell. Authenticated reboot paths (`systemctl reboot` over the key-only admin
SSH session) are unaffected either way. The console itself is otherwise locked
down (kiosk autologin to a single locked browser; no getty shell on tty1;
`debug_shell` is lab-only and never shipped). If a future deployment wants the
hotkey disabled (e.g. a physically exposed terminal), re-select both rule IDs.
## Things that are NOT deviations (kept / enforced) ## Things that are NOT deviations (kept / enforced)
- **SELinux enforcing** (`selinux --enforcing`; labels preserved into the erofs). - **SELinux enforcing** (`selinux --enforcing`; labels preserved into the erofs).
+7 -3
View File
@@ -28,8 +28,12 @@ EFIVARS=/sys/firmware/efi/efivars
GUID_GLOBAL=8be4df61-93ca-11d2-aa0d-00e098032b8c # PK, KEK, SetupMode GUID_GLOBAL=8be4df61-93ca-11d2-aa0d-00e098032b8c # PK, KEK, SetupMode
GUID_DB=d719b2cb-3d3a-4596-a3bc-dad00e67656f # db, dbx GUID_DB=d719b2cb-3d3a-4596-a3bc-dad00e67656f # db, dbx
# EFI var attributes: NON_VOLATILE|BOOTSERVICE_ACCESS|RUNTIME_ACCESS| # EFI var attributes: NON_VOLATILE|BOOTSERVICE_ACCESS|RUNTIME_ACCESS|
# TIME_BASED_AUTHENTICATED_WRITE_ACCESS = 0x27, little-endian 4 bytes. # TIME_BASED_AUTHENTICATED_WRITE_ACCESS = 0x27, written as a 4-byte little-endian
ATTR=$'\x27\x00\x00\x00' # u32 prefixed to the .auth payload. These 4 bytes contain NULs, so they are
# emitted with printf at WRITE TIME, never stored in a variable: a bash string
# can't hold a NUL (it truncates at the first one), which would leave only the
# 0x27 byte, corrupt the 4-byte attribute field efivarfs reads, and make the
# kernel reject the write with EINVAL ("dd: Invalid argument").
die() { echo "fleet-sb-enroll: $*" >&2; exit 1; } die() { echo "fleet-sb-enroll: $*" >&2; exit 1; }
@@ -57,7 +61,7 @@ enrol_one() { # $1=var name $2=guid $3=.auth path
local f="$EFIVARS/$1-$2" tmp local f="$EFIVARS/$1-$2" tmp
[ -f "$3" ] || die "missing $3" [ -f "$3" ] || die "missing $3"
tmp=$(mktemp) tmp=$(mktemp)
printf '%s' "$ATTR" > "$tmp" printf '\x27\x00\x00\x00' > "$tmp" # 4-byte LE attribute prefix (see note above)
cat "$3" >> "$tmp" cat "$3" >> "$tmp"
# Existing EFI vars carry the immutable flag; clear it before overwriting. # Existing EFI vars carry the immutable flag; clear it before overwriting.
[ -e "$f" ] && chattr -i "$f" 2>/dev/null || true [ -e "$f" ] && chattr -i "$f" 2>/dev/null || true
+11
View File
@@ -162,5 +162,16 @@
<xccdf:select idref="xccdf_org.ssgproject.content_rule_usbguard_allow_hub" selected="true"/> <xccdf:select idref="xccdf_org.ssgproject.content_rule_usbguard_allow_hub" selected="true"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_usbguard_allow_hid_and_hub" selected="true"/> <xccdf:select idref="xccdf_org.ssgproject.content_rule_usbguard_allow_hid_and_hub" selected="true"/>
<!-- Ctrl+Alt+Del reboot hotkey (decision 2026-06-20): KEEP the console
reboot hotkey working on these diskless kiosks. The STIG masks
ctrl-alt-del.target + sets CtrlAltDelBurstAction=none to stop an
unauthenticated console reboot, but the hosts are STATELESS (immutable
erofs+verity root, tmpfs overlay) so a console reboot has no data-loss
or persistence risk, and a field tech needs to recover a wedged kiosk
without SSH. Unselect both so remediation leaves the systemd default
(hotkey reboots). Justified in docs/stig-deviations.md #13. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_disable_ctrlaltdel_reboot" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_disable_ctrlaltdel_burstaction" selected="false"/>
</xccdf:Profile> </xccdf:Profile>
</xccdf:Tailoring> </xccdf:Tailoring>