From 8f7833a7e00242bb205048cea668f9cea11fe4a0 Mon Sep 17 00:00:00 2001 From: Audiobuzz Date: Sat, 13 Jun 2026 05:06:44 +0000 Subject: [PATCH] Updating docs --- .claude/settings.local.json | 7 ++++ docs/TODO.md | 66 +++++++++++++++++++++++++++++++++++++ docs/design-v2-errata.md | 60 +++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 .claude/settings.local.json create mode 100644 docs/TODO.md create mode 100644 docs/design-v2-errata.md diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..2515fc0 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,7 @@ +{ + "permissions": { + "allow": [ + "Bash(packer validate *)" + ] + } +} diff --git a/docs/TODO.md b/docs/TODO.md new file mode 100644 index 0000000..4949054 --- /dev/null +++ b/docs/TODO.md @@ -0,0 +1,66 @@ +# TODO — diskless fleet boot system + +Persistent backlog, kept in sync with the working session task tracker. Status: +`[ ]` pending · `[~]` in progress · `[x]` done. + +--- + +## [ ] 1. Port the dracut module off `network-legacy` → `network-manager` + +Durable replacement for the current `dhcp-client` stopgap. `dhclient` is +deprecated in RHEL 9 and will eventually leave the repos; the build only works +today because the provisioner installs `dhcp-client` so `network-legacy` passes +dracut's `check()`. + +- Rewrite both network bring-up paths in + [../files/dracut/95dot1x-macsec/dot1x-macsec-up.sh](../files/dracut/95dot1x-macsec/dot1x-macsec-up.sh): + the secure path's `ifup macsec0` and the `rd.dot1x=0` bypass path's + `ifup $NIC` — use `nmcli`/NetworkManager-in-initramfs (or `ip=` cmdline + the + nm module) instead. +- Change `depends()` `network-legacy` → `network-manager` in + [../files/dracut/95dot1x-macsec/module-setup.sh](../files/dracut/95dot1x-macsec/module-setup.sh). +- Update `add_dracutmodules` in + [../files/etc/dracut.conf.d/90-diskless.conf](../files/etc/dracut.conf.d/90-diskless.conf). +- Drop `dhcp-client` from the provisioner `dnf install` in + [../diskless.pkr.hcl](../diskless.pkr.hcl). +- Re-verify the `lsinitrd` assertion. +- **Gate:** full boot-chain smoke test (swtpm + hostapd + FreeRADIUS) before + merge, per CLAUDE.md. + +## [ ] 2. Apply RHEL9 STIG hardening to the built image + +OpenSCAP + SCAP Security Guide (`xccdf_org.ssgproject.content_profile_stig`), run +as a Packer provisioner after `dnf install` and before the dracut/initramfs build +and cleanup. + +- **Tailoring** (`autotailor`): unselect rules this architecture can't satisfy — + separate-partition rules (single erofs root + tmpfs overlay; satisfy intent + with `nodev,nosuid,noexec` tmpfs mounts), GRUB/kernel-cmdline rules (no GRUB), + and AIDE/file-integrity rules (dm-verity is the documented compensating + control). +- **Kernel params → UKI cmdline** in + [../scripts/extract-artifacts.sh](../scripts/extract-artifacts.sh) before + signing: `audit=1 audit_backlog_limit=8192 slub_debug=P page_poison=1 + vsyscall=none` (+ `fips=1` if FIPS). +- **Reproducibility guard:** strip non-deterministic remediation output (SSH host + keys → regen at boot into overlay, AIDE db, timestamps, fresh UUIDs) so the + verity hash stays stable. +- **Audit logging:** `audisp-remote`/rsyslog to a central collector addressed by + DNS name (host-generic). +- **Optional FIPS:** `fips=1` cmdline + `01fips` dracut module + FIPS crypto + policy. +- **CI:** run `oscap eval` (no `--remediate`) to publish an ARF+HTML STIG report + as a build artifact; optionally hard-fail below a score threshold. +- **Decisions needed before implementing:** FIPS on/off · remote-audit collector + DNS name (or ephemeral/none for lab) · CI fail-on-score threshold vs + report-only. +- Note: orthogonal to the `rd.dot1x=0` test toggle, but a full STIG production + posture wants 802.1X re-enabled. + +## [ ] 3. Roll the errata into design doc v3 + +Once the boot path is validated and item 1 lands, fold +[design-v2-errata.md](design-v2-errata.md) into the source design document and +re-export a **v3** PDF (key change: `rootovl` → `systemd.volatile=overlay` in §3 +step 8 and §5). Retire/reset the errata afterward. Needs the design-doc source +(not in this repo). diff --git a/docs/design-v2-errata.md b/docs/design-v2-errata.md new file mode 100644 index 0000000..f7fecd4 --- /dev/null +++ b/docs/design-v2-errata.md @@ -0,0 +1,60 @@ +# Design v2 — implementation errata (RHEL/Rocky 9) + +Records where the as-built implementation diverges from +`diskless-fleet-design-v2.pdf`. The PDF remains authoritative for the +architecture; this note captures deltas discovered bringing the build up on +**Rocky 9.8** until they are folded into a consolidated **v3**. Last updated +2026-06-13. + +The architecture is unchanged: 802.1X EAP-TLS with a TPM-held key, MACsec on the +access link, dm-verity-protected erofs root over NVMe/TCP, signed UKI, and the +FROM-scratch OCI release artifact. Only the items below differ. + +## 1. Design-level change — writable root overlay + +**PDF says (§3 step 8, §5):** runtime state lives on a tmpfs overlay enabled by +the kernel cmdline option **`rootovl`**. + +**As built:** the cmdline uses **`systemd.volatile=overlay`** instead. + +**Why:** `rootovl`/`overlayfs` is a Debian/third-party dracut module; RHEL/Rocky +dracut does not ship it (`dracut: module 'overlayfs' cannot be found`). +`systemd.volatile=overlay` is the RHEL-native, systemd-supported mechanism and +is the recommended overlay for dm-verity-protected read-only roots. Behaviour is +equivalent: the verity erofs root mounts read-only and a tmpfs overlay carries +runtime writes; per-host `machine-id` is still generated into the overlay. + +**Caveat:** requires `systemd-volatile-root.service` in the initramfs (bundled by +recent dracut; `install_items` it if the root stays read-only at boot). The known +failure mode is NFS root — not applicable here (NVMe block root). Set in +[../scripts/extract-artifacts.sh](../scripts/extract-artifacts.sh); module list +in [../files/etc/dracut.conf.d/90-diskless.conf](../files/etc/dracut.conf.d/90-diskless.conf). + +## 2. Implementation notes (not architectural) + +These don't contradict the PDF (it doesn't specify them) but are worth recording. + +- **Network backend.** The dracut hook uses `network-legacy`/`ifup`, which needs + `dhclient`; RHEL 9 deprecated it and the minimal ISO omits it, so the + provisioner installs `dhcp-client` explicitly. dhclient is on its way out — the + durable fix is porting the hook to the `network-manager` dracut module + (tracked; see project todo). +- **Build ISO.** Defaults to a version-pinned Rocky 9.x **minimal** ISO on the + internal mirror (`iso_url` + `sha256` `iso_checksum`). `http/ks.cfg` installs + only core+sshd+chrony from the ISO; the diskless tooling is pulled online by + the provisioner, so the build VM needs outbound repo access. +- **Reference serving stack.** §7's SPDK + nginx + DHCP/DNS serving stack has a + concrete docker-compose implementation in [../serving/](../serving/), incl. + Docker image-volume mounting of the OCI artifact image. +- Assorted build-time fixes (HCL `%%{` escaping, file-provisioner staging, + dracut module naming) are documented in + [../CLAUDE.md](../CLAUDE.md) → "RHEL 9.x build notes". + +## 3. Temporary deviation — must be reverted before production + +- **802.1X/MACsec test bypass.** `disable_dot1x=true` bakes `rd.dot1x=0` into the + cmdline so the host skips authentication/MACsec and DHCPs the NIC directly, to + validate the UKI/rootfs/NVMe-oF path on an open switch port. The auth stack + stays in the image (dormant). This is **lab-only**; a production build must + drop the flag (`DISABLE_DOT1X: "false"` in CI) to restore the secure boot + chain described throughout the PDF.