No secure element is on-site: event signing runs on the software HMAC (EVENT_SIGNING_KEY, an env var on the host disk), so the ledger is tamper-EVIDENT but forgeable by anyone who owns the host. Several pages overstated it as present-tense "ATECC608-signed / unforgeable"; correct them. - NEW concepts/hardware-signer-options.md: four options for a non-extractable signing key (USB HSM / YubiKey / reuse the TPM / plain-dongle trap) + the recommendation (TPM interim → USB-HSM target; ATECC608 stays for the embedded ESP32, wrong part for a PC host). - entities/atecc608.md: UPCOMING-not-present status banner + PC-vs-embedded. - disk-os-hardening.md: fix the live-USB row (BIOS boot-order password is load-bearing, not Secure Boot — a signed live USB runs); add a physical-tamper chain (Dell 7070 CMOS-reset → live-USB → PCR-7 same-signer unseal) + accepted risks (that unseal, unsigned-initramfs evil-maid, operator-USB read TODO). - open-questions #6 reframed; standing-decisions / overview / threat-model / index de-overstated; log query entry. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
12 KiB
type, tags, sources, updated, status
| type | tags | sources | updated | status | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| decision |
|
|
2026-06-30 | 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. Disk/OS hardening defends the threat-model 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).
⚠ Caveat on the ledger's tamper-resistance (2026-07-02). The "signed event chain" above is software-signed today (HMAC, key in
EVENT_SIGNING_KEYon the host disk) — the atecc608 secure element is open-questions. So a physical adversary who decrypts the disk (see the tamper chain below) reads the signing key and can forge/re-sign a doctored ledger undetectably — the chain does not save you against a host-owner until a non-extractable hardware signer (tpm / USB HSM — hardware-signer-options) is wired. Until then the disk's confidentiality/integrity leans harder on the controls below, and the residual backstop against forgery is external reconciliation against records the box doesn't hold (payments, an offsite backup, a separate witness), not the on-disk signature.
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 → the BIOS boot-order/boot-menu password is the load-bearing control here, NOT Secure Boot. Secure Boot happily runs a signed Ubuntu live USB, and PCR-7-only sealing can't distinguish it from our own boot (same signing authorities → same PCR 7 → the TPM would unseal). So confidentiality rests on the operator being unable to select the USB. See the physical-tamper chain below (a CMOS reset strips that password).
- 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/lxdgroups) → 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).
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 byfwupd/LVFS — a channel SEPARATE from APT (Ubuntu's GNOME "Firmware Updater" = thefirmware-updatersnap). A cleanapt list --upgradabledoes 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(currentgrub-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 asEVENT_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-passphrasesilently 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.
Physical-tamper chain & accepted risks (traced 2026-07-02, Dell OptiPlex 7070)
The BIOS admin password gates Setup and the one-time boot menu (verified: choosing a USB device at F12 prompts for the password). That closes the live-USB path — while the password holds. The uncomfortable finding is that the password is a soft control against a case-opening adversary:
- CMOS reset (pull the coin cell, or the on-board PSWD/CMOS-clear jumper — Dell documents its location) → BIOS settings return to factory defaults: admin password cleared, boot menu open. It does NOT wipe the Secure-Boot key databases (PK/KEK/db/dbx live in SPI-flash NVRAM, not the battery-backed RTC), and the 7070's factory default is Secure Boot = Enabled. So after the reset Secure Boot comes back on, same MS keys → PCR 7 reconstructs to the same value.
- Boot a signed Ubuntu live USB (now selectable). Same signing authorities → PCR 7 matches the
sealing policy → the attacker runs
cryptsetup/systemd-cryptsetupand the TPM releases the LUKS key. Disk decrypts; they have root on the decrypted filesystem, including the ledger.- Note the asymmetry: if instead they disable Secure Boot in the now-unlocked BIOS, PCR 7 changes → the TPM refuses → the box drops to the slot-0 passphrase prompt they don't have. So disabling Secure Boot locks them out; leaving it at the reset default lets them in. This is the PCR-7-only "same-signer" weakness (systemd docs recommend PCR 7 + a PIN to close it).
Net: a battery-pull alone yields nothing (disk stays sealed), but battery-pull → live-USB → PCR-7 unseal is a realistic chain to root on the decrypted data. What it costs the attacker: a screwdriver and a signed USB. What still holds after it: they never get the escrowed slot-0 passphrase, and (the point of the caveat above) the ledger's forgery-resistance depends on the signer — with today's on-disk HMAC key they CAN forge the ledger; only a hardware signer (hardware-signer-options) would keep the financial record unforgeable through this.
Accepted risks (named, not silently "covered"):
- PCR-7 same-signer unseal via CMOS reset (above). Not mitigated by the current config. Real
fixes both cost the thing we optimised for: a TPM PIN (
--tpm2-with-pin=yes) closes it but kills unattended boot (someone types a PIN each power event); custom Secure-Boot keys / more PCRs close it but reintroduce re-seal churn on kernel/shim updates (the exact thing PCR-7-only avoids). Deferred decision — accept for now; the primary control remains reconciliation + escrowed backups, not disk confidentiality. - Unsigned initramfs (evil-maid).
/bootis unencrypted and Ubuntu does not sign the initramfs (Secure Boot verifies shim→GRUB→kernel; PCR 7 doesn't measure the initrd). The initramfs is exactly the code that receives the LUKS key, so a maid who tampers it and waits one boot can harvest the key. Accepted: needs repeated privileged physical access, and a hardware signer would still keep the ledger unforgeable even from a fully-owned host. - Operator USB at an auto-logged-in session — unverified what the unprivileged operator account
can read on the host (e.g. can it reach the Docker-mounted
/data?). TODO: verify the operator can't read the DB volume orEVENT_SIGNING_KEYfrom its own login.
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.
- hardware-signer-options — TPM / USB-HSM / ATECC608 options for a non-extractable ledger signing key (the missing piece this page's tamper chain exposes).
- fleet-deployment-komodo — Periphery as part of the trusted computing base.