docs(wiki): firmware/dbx-vs-TPM hardening + create disk-os-hardening page
Real-world park-buzi episode: a UEFI dbx update (delivered via fwupd/LVFS, NOT apt) revoked a stale GRUB -> panic, and moved PCR 7 -> broke TPM-sealed LUKS auto-unlock -> passphrase prompt. Recovered by re-sealing PCR 7. - appliance-provisioning.md: extend the §4 re-seal runbook to name dbx; new §4a (fwupd-not-apt, GRUB-panic ordering, PCR-7 re-seal, operator lockdown: mask fwupd + remove firmware-updater snap + BIOS-password + passphrase escrow) incl. the --test-passphrase-silently-passes-via-TPM trap (--disable-external-tokens); gotchas #12/#13. - disk-os-hardening.md: NEW — resolves a long-dangling wikilink referenced from ~18 pages. The *why* of host hardening (5 controls + firmware lockdown); commands stay in appliance-provisioning; reconciliation remains the primary anti-fraud control. - index.md: expand the disk-os-hardening catalog line. - log.md: two note entries. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
---
|
||||
type: decision
|
||||
tags: [parking, hardening, threat-model, luks, tpm, secure-boot, grub, firmware, offline-first]
|
||||
sources: [parking-system-architecture]
|
||||
updated: 2026-06-30
|
||||
status: settled
|
||||
---
|
||||
|
||||
# Disk & OS hardening (booth appliance)
|
||||
|
||||
The host-level defences that raise the cost of **offline, physical tamper** of a booth PC: full-disk
|
||||
encryption, TPM-sealed auto-unlock, Secure Boot, a GRUB edit-lock, an unprivileged operator account,
|
||||
and locking firmware updates away from the operator. This page is the **rationale (the *why*)**; the
|
||||
step-by-step verified commands live in the [[appliance-provisioning]] runbook (§3–5c, §4a). Settled
|
||||
across the first real provisioning (2026-06-23) and the firmware-update episode (2026-06-30).
|
||||
|
||||
> ⚠ **This is the secondary control, not the main event.** The load-bearing anti-fraud mechanism is
|
||||
> [[reconciliation]] over the [[append-only-event-chain|signed event chain]]. Disk/OS hardening
|
||||
> defends the [[threat-model|outsider-with-the-box]] and raises the cost of offline tamper — it does
|
||||
> **not** replace reconciliation, and it cannot stop a *legitimate, logged-in* operator from
|
||||
> committing fraud through the app (that's what the signed ledger + reconciliation are for).
|
||||
|
||||
## What it defends against
|
||||
|
||||
The appliance sits on-site, physically reachable by the [[threat-model|booth operator (the primary
|
||||
adversary)]] and by an outsider who can open the case. Without host hardening, either can:
|
||||
|
||||
- **Pull the SSD** and read/alter the SQLite ledger offline → FDE (LUKS) defeats this.
|
||||
- **Boot a live USB** to mount and edit the disk → Secure Boot + TPM-sealing (PCR 7) defeats booting
|
||||
a tampered/unsigned kernel; FDE keeps the data unreadable.
|
||||
- **Edit the GRUB cmdline** (`init=/bin/bash`) for a no-login root shell on the *decrypted* disk →
|
||||
the GRUB edit-lock defeats this (the TPM seal does NOT — see below).
|
||||
- **Escalate from the operator login** (sudo, `docker`/`lxd` groups) → the unprivileged-operator
|
||||
model defeats this.
|
||||
|
||||
## The five controls and why each is shaped the way it is
|
||||
|
||||
| Control | Choice | Why this shape (the load-bearing nuance) |
|
||||
| --- | --- | --- |
|
||||
| **FDE** | LUKS, **passphrase** at install (not the installer's "hardware-backed" option) | The 26.04 installer's automated FDE profiler fails on this firmware (`PCR_UNUSABLE`/`dbt`). Passphrase LUKS + a *manual* TPM seal sidesteps it and lets us pick PCRs. The passphrase slot is the **permanent recovery key**. |
|
||||
| **TPM auto-unlock** | `systemd-cryptenroll`, **PCR 7 only** | Unattended reboot is a hard requirement (no operator types a passphrase). PCR 7 = Secure-Boot policy: catches the attack that matters (disabling Secure Boot) **without** churning on kernel/GRUB updates (PCRs 4/8/9 → would drop to passphrase every boot). **Keep BOTH slots** — slot 0 password (recovery), slot 1 tpm2 (auto-unlock); the TPM is never the only key. |
|
||||
| **Secure Boot** | Enabled, **Deployed Mode**, stock MS keys | Ubuntu's signed shim needs stock `db`. Reaching the installer with Secure Boot ON is itself proof the MS third-party UEFI CA is trusted. |
|
||||
| **GRUB edit-lock** | password, **edit-only** (`--unrestricted`) | Closes the `init=/bin/bash` root-shell hole. **The PCR-7 TPM seal does NOT cover this** — editing the cmdline doesn't change PCR 7, so the TPM still releases the key and the attacker lands on the decrypted disk. Edit-only so the box still boots **unattended** (password required only to *edit* entries). |
|
||||
| **Operator account** | unprivileged, auto-login; separate **admin**+sudo | The operator is the adversary; their OS identity must not be able to escalate. Strip `sudo`, and the latent-escalation groups `lxd`/`docker` (both root-equivalent) + `lpadmin`. Admin is a distinct, no-auto-login identity. |
|
||||
|
||||
See [[tpm]] for the TPM-2.0 analysis (why PCR-only sealing, bus-sniff limits, TPM-vs-[[atecc608|ATECC608]]).
|
||||
|
||||
## Firmware / UEFI dbx updates — a hardening surface AND an operator threat
|
||||
|
||||
Settled 2026-06-30 after a real incident on `park-buzi`. This is the non-obvious one, because it
|
||||
turns a routine "security update" into a booth-availability risk:
|
||||
|
||||
- **UEFI `dbx`** (the Secure Boot revocation database) and BIOS firmware are delivered by
|
||||
**`fwupd`/LVFS — a channel SEPARATE from APT** (Ubuntu's GNOME "Firmware Updater" = the
|
||||
`firmware-updater` snap). A clean `apt list --upgradable` does NOT mean no firmware update is pending.
|
||||
- **It can brick boot:** a new dbx against a *stale* GRUB/shim **revokes the installed bootloader** →
|
||||
Secure Boot refuses it → unbootable / GRUB panic. Correct order: `apt full-upgrade` (current
|
||||
`grub-efi`/`shim-signed`) **first**, then dbx.
|
||||
- **It breaks auto-unlock:** even with a current GRUB, applying dbx **moves PCR 7** → the TPM refuses
|
||||
the LUKS key → next boot falls back to the slot-0 passphrase prompt (not a brick). Recover with the
|
||||
PCR-7 re-seal runbook ([[appliance-provisioning]] §4/§4a).
|
||||
- **Threat-model consequence:** a firmware/dbx update makes the booth need a passphrase to boot
|
||||
unattended — so the **operator must be unable to trigger one, and must never hold the passphrase.**
|
||||
Lock it down: `systemctl mask fwupd.service fwupd-refresh.timer`, `snap remove firmware-updater`,
|
||||
a **BIOS admin password** that gates *entering setup* (so the operator can't disable Secure Boot /
|
||||
change boot order), and the **slot-0 passphrase escrowed off-machine** (same custody as
|
||||
`EVENT_SIGNING_KEY` / `BACKUP_KEY`). Firmware maintenance becomes **admin-only, on-site, deliberate**.
|
||||
|
||||
> The booth is unattended-bootable **only while the firmware / Secure-Boot state is frozen** — that is
|
||||
> the security property, not a bug. The cost is that legitimate firmware maintenance now needs physical
|
||||
> presence + the slot-0 passphrase + a PCR-7 re-enroll.
|
||||
|
||||
> **⚠ Verification trap:** `cryptsetup … --test-passphrase` **silently passes via the TPM token** (a
|
||||
> false safety signal). Before any firmware change, prove a *typed* passphrase still unlocks the disk
|
||||
> with `--disable-external-tokens` — see [[appliance-provisioning]] §4a.
|
||||
|
||||
## Where the commands live
|
||||
|
||||
This page is the rationale. The **verified, run-on-real-hardware commands** are in
|
||||
[[appliance-provisioning]]: §1 BIOS, §2 Secure-Boot live-USB check, §3 encrypted install (the `dbt`
|
||||
workaround), §4 TPM seal (PCR 7) + re-seal runbook, **§4a firmware/dbx lockdown**, §5 GRUB edit-lock,
|
||||
§5c admin-vs-operator accounts. Komodo Periphery is folded into the same hardened surface as a
|
||||
root-capable remote agent — see [[fleet-deployment-komodo]] (bind to the NetBird interface only).
|
||||
|
||||
## Relates
|
||||
|
||||
- [[appliance-provisioning]] — the runbook (commands); this page is its *why*.
|
||||
- [[tpm]] — TPM 2.0 analysis (sealing, PCR choice, limits, vs ATECC608).
|
||||
- [[threat-model]] — the operator-adversary framing this hardening serves.
|
||||
- [[reconciliation]] / [[append-only-event-chain]] — the **primary** anti-fraud control this
|
||||
complements, never replaces.
|
||||
- [[fleet-deployment-komodo]] — Periphery as part of the trusted computing base.
|
||||
Reference in New Issue
Block a user