This commit is contained in:
Audiobuzz
2026-06-18 12:03:45 +00:00
parent ada4aa4b18
commit 3b776dd970
47 changed files with 3416 additions and 110 deletions
+87 -9
View File
@@ -5,6 +5,24 @@ Persistent backlog, kept in sync with the working session task tracker. Status:
---
## Current build posture (LAB / test) — as of 2026-06-18
The image currently builds in **open-network test mode**. These toggles must be
flipped back for a secure/production build (consolidated as item #8):
- `disable_dot1x=true` / CI `DISABLE_DOT1X="true"` → `rd.dot1x=0` (NO 802.1X /
MACsec; open NVMe-oF). **TEMPORARY.**
- `nvmet_traddr` / CI `NVMET_TRADDR="192.168.50.10"` → hardcoded IP (should be a
per-env DNS name like `nvme.fleet.lab` once DNS-at-boot is trusted).
- Unsigned UKI (`sb_key`/`sb_cert` not passed) → Secure Boot must be OFF on the
test target. Production needs CI/HSM signing.
- `enable_kiosk=false` by default (CI may set true); `enable_stig=true`;
`boot_splash=true`; NTP via DHCP→serving-host chrony.
What's working/verified vs awaiting bench is per-item below. Cross-cutting
bench-verify checklist lives in `CLAUDE.md` → "Known bench-verify items".
---
## [x] 1. Port the dracut module off `network-legacy` → `network-manager`
**DONE — test path VERIFIED ON THE BENCH 2026-06-17** (host stays up past the
@@ -56,11 +74,28 @@ in **[stig-deviations.md](stig-deviations.md)** (curated register) and reported
per-build by **[../scripts/stig-deviations.sh](../scripts/stig-deviations.sh)**
(non-pass rules tagged intentional vs REVIEW); CI publishes
`stig-report.html` + `stig-arf.xml` + `stig-deviations.md`. Scanner tooling is
removed from the shipped image. **BENCH-VERIFY:** SSG datastream name; boot/login
still work; reproducible verity hash across two builds; triage REVIEW rows.
removed from the shipped image. **BENCH-VERIFY:** boot/login still work;
reproducible verity hash across two builds; triage REVIEW rows.
**FINDING 2026-06-18 (FIXED) — false-clean scan.** The first hardened build
(branch `hardening`, `ada4aa4`) produced a report reading "0 REVIEW / clean",
but the ARF had **0 pass, 0 fail** — only 462 `notapplicable` + 1068
`notselected`. Root cause: the provisioner selected the datastream with
`ls ssg-rhel9-ds.xml ssg-rl9-ds.xml | head -1`, which picks **rhel9**
alphabetically; the RHEL9 datastream's CPE dictionary has **no Rocky entry**, so
on Rocky 9.8 every selected rule went `notapplicable` and **nothing was actually
evaluated or remediated** — the image was unhardened despite a clean-looking
report. Fixes: (a) provisioner now maps `/etc/os-release $ID` → datastream
(Rocky→`ssg-rl9-ds.xml`); (b) provisioner **aborts the build** if the scan
evaluates 0 rules; (c) `stig-deviations.sh` flags an **INVALID SCAN** and exits
non-zero on 0-evaluated. **Re-run the hardened build** and confirm pass/fail
counts are non-zero before trusting any deviations report.
Remaining (future hardening, currently waived — see the register): FIPS,
firewall, remote audit offload, per-host/rotatable admin access.
firewall, per-host/rotatable admin access. **Remote audit offload — receiver
DONE** (`serving/audit-collector/`, rsyslog over TCP/514, per-source-host files;
DNS name `${AUDIT_HOST}`); the **image-side sender** (audisp-syslog + rsyslog
forward to `audit.fleet.lab`) is still to wire — see that dir's README.
### Original spec (retained for reference)
@@ -116,7 +151,12 @@ re-export a **v3** PDF (key change: `rootovl` → `systemd.volatile=overlay` in
step 8 and §5). Retire/reset the errata afterward. Needs the design-doc source
(not in this repo).
## [~] 4. Kiosk mode — autologin + fullscreen Chromium loading a URL
## [x] 4. Kiosk mode — autologin + fullscreen Chromium loading a URL
**WORKING (display-verified 2026-06-17).** Remaining bits are polish (GPU/mesa
trim, ship via CI `enable_kiosk=true`) and the phone-home/NTP lockdown (done) —
all captured in the sub-notes below. Secure-path render check is folded into #8.
**WORKING / display-verified 2026-06-17** (kiosk renders Chromium fullscreen on
the configured URL). Build-flagged OFF by default for now (`enable_kiosk=false`)
@@ -147,11 +187,19 @@ Path to getting here (don't re-discover):
smaller image. **Re-enable with `-var enable_kiosk=true` when returning to
kiosk work** — CI does not pass the var, so CI currently builds lean (no
kiosk) too; add `-var enable_kiosk=true` to the Gitea workflow to ship it.
- `kiosk_url` Packer var (default `http://boot.fleet.lab/kiosk/` — the
self-contained test page served by the boot HTTP server at
`serving/http/kiosk/`, via the `/kiosk/` nginx location; validates a boot
without external connectivity. Empty disables the whole install). Wired in CI
as `KIOSK_URL` env.
- `kiosk_url` Packer var (default `http://boot.fleet.lab/kiosk/` — the kiosk
**SPA** (`serving/kiosk-app/`, Svelte 5 + Tailwind v4, a cyber sci-fi
spaceship monitoring/control terminal) served by the boot HTTP server, which
**reverse-proxies** `/kiosk/` to the `kiosk` container; self-contained so a
boot validates without external connectivity. Empty disables the whole
install). Wired in CI as `KIOSK_URL` env.
- **Kiosk SPA (`serving/kiosk-app/`)** — replaced the old single static
`serving/http/kiosk/index.html` (2026-06-18). Top navbar + 5 pages
(Bridge/Reactor/Nav/Life Support/Comms) with dummy telemetry; hash routing;
builds in a 2-stage Docker image (Vite → nginx), reverse-proxied at `/kiosk/`
by the main serving nginx (loopback `127.0.0.1:${KIOSK_APP_PORT:-8088}`).
`npm run build` verified locally; container build untested (no docker here).
Dummy data lives in `src/lib/data.js` (swap for a fleet API later).
- Provisioner enables EPEL, installs `weston chromium mesa-dri-drivers
mesa-libEGL mesa-libgbm dejavu-sans-fonts`, creates a passwordless
unprivileged `kiosk` user (video/input groups).
@@ -439,3 +487,33 @@ export is read-only + single-namespace = inherently small attack surface.
— it's the fleet's disk). Ties into #6 (rolling updates) availability.
- Revisit a memory-safe target only if/when an off-the-shelf one matures
(e.g. a future Rust-for-Linux `nvmet`).
## [ ] 8. Return to secure / production posture (un-toggle the lab flags)
Consolidates the cleanup of the temporary lab toggles (see "Current build
posture" at the top) and the secure-path bench-verifies deferred while testing
the open-network path. Do these together, then run the full secure boot-chain
smoke test.
- **Re-enable 802.1X/MACsec:** `disable_dot1x=false` (CI `DISABLE_DOT1X="false"`).
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
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
Secure Boot on targets. Until then the loud unsigned warning must stay.
- **Bench-verify on the secure path** (swtpm + hostapd + FreeRADIUS,
`disable_dot1x=false`) — the items deferred this session:
- NM port secure path: `en*` UNMANAGED + `macsec0` MANAGED/renewing, MKA
survives switch-root, NVMe stays up past lease (item #1 risk).
- NTP via DHCP option 42 reaches chrony over macsec0 (`chronyc sources`).
- Plymouth `fleet` theme: test-path render VERIFIED 2026-06-18; still confirm
the auth→macsec rows reach `done` live on the secure path.
- STIG remediation didn't break the secure path; reproducible verity hash;
triage the generated `stig-deviations.md` REVIEW rows (item #2).
- **Secure-path NVMe connect trigger:** the test path uses
`nvmf-connect.service` (gated `rd.dot1x=0`); confirm the secure path's
connect (dracut nvmf over macsec0) actually fires, or give it an equivalent
trigger. Apply the same `-k 30 -l -1 -c 10` keep-alive/reconnect flags to the
secure `nvme connect` as the test path has.
- **Future hardening waived for now** (from the STIG register): FIPS, firewall,
remote audit offload, per-host/rotatable admin (SSH CA / config-agent).