adding ssh host signing

This commit is contained in:
Audiobuzz
2026-07-11 16:20:21 +09:30
parent b5d6c790c4
commit 2e318fba00
24 changed files with 1626 additions and 90 deletions
+25 -2
View File
@@ -10,7 +10,7 @@ Authoritative design: [`../../docs/tpm-enrolment-design.md`](../../docs/tpm-enro
This is **v1** (fingerprint-only OOB assurance; inline empty-NV vehicle on the host
side). TPM attestation and the host-side dracut branch are the next phases.
## Two listeners, by design
## Three listeners, by design
```
PUBLIC (plain HTTP, behind the serving nginx /enrol/) UNAUTHENTICATED
@@ -23,10 +23,28 @@ ADMIN (mTLS, management network / loopback ONLY) admin client cert
GET /pending JSON queue
POST /approve/{id} OOB-approve -> step ca sign -> store cert
POST /deny/{id} reject
HOST (mTLS, boot LAN) FLEET host client cert
POST /ssh/hostcert {publicKey, principals, keyID} -> {cert}
GET /healthz
```
The public side is deliberately tiny and stdlib-only — it is the only thing
reachable by un-enrolled devices. The admin side never touches the boot LAN.
reachable by un-enrolled devices. The admin side never touches the boot LAN. The
**host plane** (F-02/P-17) is the automatic, self-authenticating counterpart of
enrolment: an already-enrolled host proves itself with its **TPM identity** as the
mTLS client cert (verified to the fleet CA) and the broker has step-ca sign an SSH
**host** certificate — no human approval, no CA secret on the host. This keeps
step-ca behind the single front door for SSH host certs too. The host plane is
**disabled unless `BROKER_HOST_ADDR` is set**. Enable the SSH CA on step-ca +
issue its certs with `serving/dot1x-bench/step-ca/ssh-ca-bootstrap.sh`; the client
is `files/ssh-hostcert` (docs/ssh-host-certificate-design.md).
> **Client CA differs by plane:** the ADMIN plane uses a *dedicated admin CA*
> (`admin-pki.sh`) — deliberately **not** the fleet root. The HOST plane uses the
> **fleet CA** (`BROKER_HOST_CLIENT_CA` = root+intermediate), because host clients
> present fleet-signed TPM identities. Its *server* cert must also be fleet-signed
> so the booted host verifies it against `radius-ca.pem`.
## How identity is gated
@@ -84,6 +102,11 @@ authenticate to the admin plane and approve enrolments (privilege escalation).
| `HOSTNQN_BASE` | `nqn.2026-06.org.example.fleet:host-` | hostnqn = base + cert-serial |
| `BROKER_ADMIN_CERT` / `_KEY` / `_CLIENT_CA` | — | admin mTLS (required unless insecure) |
| `BROKER_ADMIN_INSECURE` | `false` | **dev only**: plaintext admin, no client-cert auth |
| `BROKER_HOST_ADDR` | — (disabled) | SSH host-cert plane listener; unset ⇒ off |
| `BROKER_HOST_CERT` / `_KEY` | — | host-plane server cert/key (**fleet-signed**) |
| `BROKER_HOST_CLIENT_CA` | `STEP_CA_ROOT` | verifies host TPM identities (**fleet** root+intermediate) |
| `BROKER_HOST_INSECURE` | `false` | **dev only**: plaintext host plane, no client-cert auth |
| `STEP_SSH_CERT_NOT_AFTER` | `720h` | issued SSH host-cert validity |
Swap `wordlist.txt` for the 2048-word BIP39 list (11 bits/word) for more entropy
per word; it just needs to be a power-of-two number of lines.