tpm-enrol: inline empty-NV first-boot enrolment (host side, TODO #11)
Builds the host side of TPM identity enrolment — the "inline single-UKI"
vehicle from docs/tpm-enrolment-design.md. A production (secure) UKI now
auto-enrols a fresh host with no client cert, then reboots into the normal
secure path.
New dracut hook files/dracut/95dot1x-macsec/tpm-enrol.sh (initqueue/settled
prio 25, BEFORE dot1x-macsec-up at 30):
- no-op when a cert is already present in NV 0x01800001 (normal boot) or
under rd.dot1x=0 (test path has no trustworthy identity to enrol);
- on EMPTY NV: generate the signing key in the TPM @0x81010001 (openssl tpm2
provider builds the CSR; key never leaves the TPM), pre-auth DHCP on the
PHYSICAL NIC (nmcli re-manages en*, overriding the secure-mode unmanaged
drop-in), POST CSR+context to rd.fleet.enrol_url, show the broker
fingerprint on Plymouth, poll /status, write the issued leaf cert (DER) to
NV, and reboot to converge.
- Empty-NV and the secure path are mutually exclusive, so this never reorders
the load-bearing boot sequence (invariant #2).
Wiring:
- module-setup.sh: require+install the tpm2 key-gen/NV tools, curl, awk, and
the openssl tpm2 PROVIDER (ossl-modules/tpm2.so, asserted present — tpm2-tss
alone can't sign with a handle: key); install the hook.
- diskless.pkr.hcl: install tpm2-openssl + curl; assert hook/tools/provider in
the initramfs (invariant #9). New enrol_url var threaded to extract-artifacts.
- extract-artifacts.sh: bake rd.fleet.enrol_url into the cmdline.
- fleet.script: enrol-active/enrol-wait/enrol-done banner; fingerprint on the
message line (public — states only, invariant #1).
Shell JSON build/parse/cert-extract pipeline (no jq in the initramfs) verified
end-to-end against a live broker. BENCH-VERIFY list in docs/TODO.md #11 (tpm2
provider key-ref on real/swtpm, empty-NV detect, pre-auth DHCP override, Plymouth
render, NV write + reboot convergence, prod HTTPS).
This commit is contained in:
@@ -23,6 +23,10 @@ DISABLE_DOT1X=${3:-false}
|
||||
# environments. Defaults to the literal placeholder so build-oci.sh's warning
|
||||
# fires if it was never set.
|
||||
NVMET_TRADDR=${NVMET_TRADDR:-NVMET_TRADDR}
|
||||
# Enrolment broker URL baked into the cmdline (rd.fleet.enrol_url) for the inline
|
||||
# empty-NV first-boot enrolment. Per-environment DNS name (the serving nginx
|
||||
# reverse-proxies /enrol/ to the broker); only used by a host with no TPM cert.
|
||||
ENROL_URL=${ENROL_URL:-http://boot.fleet.lab/enrol}
|
||||
# Plymouth boot splash toggle (from the boot_splash Packer var). "true" bakes
|
||||
# "rhgb quiet" so Plymouth shows the graphical splash; anything else bakes
|
||||
# "plymouth.enable=0" for a fully verbose console boot (boot-chain debugging).
|
||||
@@ -217,6 +221,7 @@ printf '%s' \
|
||||
"$DOT1X_FRAGMENT" \
|
||||
"rd.neednet=1 systemd.volatile=overlay " \
|
||||
"rd.dot1x.nvindex=0x01800001 rd.dot1x.timeout=60 " \
|
||||
"rd.fleet.enrol_url=${ENROL_URL} " \
|
||||
"rd.nvmf.discover=tcp,${NVMET_TRADDR},4420 " \
|
||||
"root=/dev/mapper/root rootfstype=erofs rootflags=ro " \
|
||||
"systemd.verity=yes roothash=${ROOT_HASH} " \
|
||||
|
||||
Reference in New Issue
Block a user