Files
diskless-workstation/serving/enrol-broker/verify-serving.sh
T
Audiobuzz 8376f9a92e enrol-broker: run in serving stack + fix step signer path end-to-end
Verifying the step signer against a real step-ca surfaced two real bugs the
mock signer had hidden, plus made the bench CA actually initialise:

- signer.go: move --not-after from `step ca token` (validity caps ~1h ->
  "token validity too long") to `step ca sign` (it is the CERT lifetime).
  Without this the step signer never issues a cert.
- dot1x-bench compose: DOCKER_STEPCA_INIT_PASSWORD_FILE pointed at a file that
  does not exist at first init (it is an INPUT path), so `step ca init` failed
  and never wrote secrets/password. Use DOCKER_STEPCA_INIT_PASSWORD (the value)
  which the entrypoint writes to secrets/password, where bootstrap + broker read.
- bootstrap.sh: self-heal the root-owned ./pki Docker auto-creates; detect the
  CA password at $STEPPATH/password or secrets/password (varies by image
  version); raise authority.claims.maxTLSCertDuration so 720h fleet certs are
  allowed (stock cap 24h, which also blocked bootstrap's own RADIUS cert); fix
  RADIUS cert paths to write via the /export mount (were host paths run inside
  the container, so they never resolved).

- serving stack: add the enrol-broker service (temporary home; nginx already
  proxies /enrol/) defaulting to the zero-dependency lab path (mock signer +
  insecure loopback admin), with ENROL_* knobs to switch to step + mTLS.
- verify-serving.sh: exercise request -> approve -> cert through the deployed
  nginx /enrol/ proxy.
- TODO #11: record the step-signer verification + the two fixes.

Step signer VERIFIED end-to-end against a real step-ca: issued cert chains to
the fleet root, EKU clientAuth, hostnqn derived from serial.
2026-07-02 08:35:35 +00:00

51 lines
2.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Verify the enrol-broker as deployed in the serving stack. Run ON THE SERVING
# HOST. Exercises the FULL path: public side through the nginx /enrol/ proxy
# (:80) + the admin plane on loopback :9443.
#
# ./verify-serving.sh # admin insecure (ENROL_ADMIN_INSECURE=true)
# ADMIN_P12=enrol-pki/broker/clients/alice.p12 ./verify-serving.sh # admin mTLS
#
# Stand-in for the (not-yet-built) host side: an openssl CSR plays the TPM key.
set -euo pipefail
PUB_BASE="${PUB_BASE:-http://127.0.0.1/enrol}" # via nginx; use http://127.0.0.1:9090 to hit broker directly
ADMIN_BASE="${ADMIN_BASE:-http://127.0.0.1:9443}"
ADMIN_P12="${ADMIN_P12:-}" # set => admin is mTLS (https + client cert)
WORK="$(mktemp -d)"; trap 'rm -rf "$WORK"' EXIT
jqget() { python3 -c 'import json,sys;print(json.load(sys.stdin)["'"$1"'"])'; }
# admin curl: plaintext by default, or mTLS if a .p12 is given.
admin() {
if [ -n "$ADMIN_P12" ]; then
openssl pkcs12 -in "$ADMIN_P12" -clcerts -nokeys -passin pass: -out "$WORK/ac.pem" 2>/dev/null
openssl pkcs12 -in "$ADMIN_P12" -nocerts -nodes -passin pass: -out "$WORK/ak.pem" 2>/dev/null
curl -fsS --cert "$WORK/ac.pem" --key "$WORK/ak.pem" -k "${ADMIN_BASE/http:/https:}$1" "${@:2}"
else
curl -fsS "$ADMIN_BASE$1" "${@:2}"
fi
}
echo "== healthz (through nginx) =="
curl -fsS "$PUB_BASE/healthz"; echo
echo "== generate CSR (stand-in for the TPM key) =="
openssl ecparam -name prime256v1 -genkey -noout -out "$WORK/h.key" 2>/dev/null
openssl req -new -key "$WORK/h.key" -subj "/CN=fleet-host" -out "$WORK/h.csr" 2>/dev/null
CSR_JSON=$(python3 -c 'import json,sys;print(json.dumps(open(sys.argv[1]).read()))' "$WORK/h.csr")
echo "== POST /enrol/request =="
REQ=$(curl -fsS -X POST "$PUB_BASE/request" -H 'Content-Type: application/json' \
-d "{\"csr\": $CSR_JSON, \"context\": {\"mac\":\"de:ad:be:ef:00:01\",\"dmi_serial\":\"VERIFY-001\"}}")
echo "$REQ"
ID=$(echo "$REQ" | jqget enrol_id)
echo "enrol_id=$ID fingerprint=$(echo "$REQ" | jqget fingerprint)"
echo "== admin /pending =="; admin /pending; echo
echo "== approve $ID =="; admin "/approve/$ID" -X POST; echo
echo "== /enrol/status/$ID (expect approved + cert) =="
curl -fsS "$PUB_BASE/status/$ID" | python3 -m json.tool
echo
echo "PASS: request -> approve -> cert through the serving deployment."