#!/usr/bin/env bash # admin-pki.sh — issue the broker's admin-plane mTLS PKI. # # SECURITY: the admin client CA MUST be SEPARATE from the fleet CA. If you reused # the fleet root as the client CA, any host's *enrolment* cert (signed by that # same root) would also authenticate to the admin plane — a privilege escalation # letting an enrolled host approve enrolments. So this mints a DEDICATED admin CA, # the broker's TLS server cert, and one client cert (+ .p12 for browser import) # per named admin. # # Usage: admin-pki.sh [admin-name ...] # e.g. ./admin-pki.sh ../dot1x-bench/pki/broker alice bob # # Then point the broker at: # BROKER_ADMIN_CERT=/server.crt # BROKER_ADMIN_KEY=/server.key # BROKER_ADMIN_CLIENT_CA=/admin-ca.crt # and import clients/.p12 (empty password) into each admin's browser. set -euo pipefail OUT=${1:?usage: admin-pki.sh [admin-name ...]} shift || true ADMINS=("$@") [ ${#ADMINS[@]} -eq 0 ] && ADMINS=(admin) SAN=${BROKER_ADMIN_SAN:-"IP:127.0.0.1,DNS:localhost"} DAYS=${BROKER_ADMIN_DAYS:-825} mkdir -p "$OUT/clients" cd "$OUT" # --- dedicated admin CA (separate from the fleet CA) ------------------------ if [ ! -f admin-ca.crt ]; then echo "==> creating admin CA" openssl ecparam -name prime256v1 -genkey -noout -out admin-ca.key openssl req -x509 -new -key admin-ca.key -days "$DAYS" \ -subj "/CN=fleet enrol-broker admin CA" -out admin-ca.crt fi # --- broker TLS server cert ------------------------------------------------- echo "==> issuing broker server cert (SAN $SAN)" openssl ecparam -name prime256v1 -genkey -noout -out server.key openssl req -new -key server.key -subj "/CN=enrol-broker-admin" -out server.csr openssl x509 -req -in server.csr -CA admin-ca.crt -CAkey admin-ca.key -CAcreateserial \ -days "$DAYS" -extfile <(printf "subjectAltName=%s\nextendedKeyUsage=serverAuth" "$SAN") \ -out server.crt rm -f server.csr # --- one client cert (+ .p12) per admin ------------------------------------ for a in "${ADMINS[@]}"; do echo "==> issuing admin client cert: $a" openssl ecparam -name prime256v1 -genkey -noout -out "clients/$a.key" openssl req -new -key "clients/$a.key" -subj "/CN=$a" -out "clients/$a.csr" openssl x509 -req -in "clients/$a.csr" -CA admin-ca.crt -CAkey admin-ca.key -CAcreateserial \ -days "$DAYS" -extfile <(printf "extendedKeyUsage=clientAuth") -out "clients/$a.crt" rm -f "clients/$a.csr" openssl pkcs12 -export -inkey "clients/$a.key" -in "clients/$a.crt" -certfile admin-ca.crt \ -name "fleet enrol admin: $a" -passout pass: -out "clients/$a.p12" done chmod 600 ./*.key clients/*.key 2>/dev/null || true echo echo "done. broker env:" echo " BROKER_ADMIN_CERT=$(pwd)/server.crt" echo " BROKER_ADMIN_KEY=$(pwd)/server.key" echo " BROKER_ADMIN_CLIENT_CA=$(pwd)/admin-ca.crt" echo "import clients/.p12 (empty password) into each admin's browser."