Files

66 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# issue-cert.sh — issue the audit collector's syslog-over-TLS server cert from
# the fleet CA (the dot1x-bench step-ca) into ./tls/, where docker-compose
# mounts it read-only at /etc/rsyslog-tls for the :6514 gtls listener.
#
# The cert's SAN must be the name senders verify (x509/name): ${AUDIT_HOST},
# the same host-generic DNS name baked into the image's 2f forward and resolved
# by the serving dnsmasq. Hosts validate it against the fleet CA root already
# baked at /etc/dot1x/radius-ca.pem — so this MUST be the same CA whose root
# the image was built with (var.fleet_ca).
#
# Same in-container issuance pattern as dot1x-bench/step-ca/bootstrap.sh: `step`
# runs inside the step-ca container; /export = dot1x-bench/pki on the host.
#
# Certs expire (default 720h — see bootstrap.sh CA claims): re-run this script
# and `docker compose restart audit` to renew. If the collector starts logging
# TLS handshake errors and senders spool, check expiry first:
# openssl x509 -in tls/server.crt -noout -enddate
set -euo pipefail
cd "$(dirname "$0")"
COLLECTOR_DIR=$PWD
BENCH_DIR=../dot1x-bench
# AUDIT_HOST from the serving stack's .env (the name dnsmasq resolves for hosts).
[ -f ../.env ] && . ../.env
AUDIT_HOST=${AUDIT_HOST:-audit.fleet.lab}
cd "$BENCH_DIR"
[ -f .env ] && . ./.env
CA_PORT=${CA_PORT:-8443}
CA_CONNECT=${CA_CONNECT:-localhost} # see bootstrap.sh: SAN-valid AND resolvable
CA_URL="https://${CA_CONNECT}:${CA_PORT}"
step() { docker compose exec -T step-ca step "$@"; }
incca() { docker compose exec -T step-ca "$@"; }
# CA/provisioner password file, as seen INSIDE the container. Location varies by
# smallstep image version (newer: $STEPPATH/password, older: $STEPPATH/secrets/
# password) — probe both, like bootstrap.sh does.
# shellcheck disable=SC2016 # $f expands in the CONTAINER's sh, not here
CONTAINER_PW=$(incca sh -c 'for f in /home/step/password /home/step/secrets/password; do [ -f "$f" ] && { echo "$f"; exit 0; }; done; exit 1') \
|| { echo "ERROR: no CA password file in the step-ca container (/home/step{,/secrets}/password) — did the CA auto-init? Check: docker compose logs step-ca" >&2; exit 1; }
echo "==> issuing audit-collector cert (CN/SAN: $AUDIT_HOST) from the fleet CA"
incca mkdir -p /export/audit
step ca certificate "$AUDIT_HOST" \
/export/audit/server.crt /export/audit/server.key \
--ca-url "$CA_URL" --root /home/step/certs/root_ca.crt \
--provisioner enrol --provisioner-password-file "$CONTAINER_PW" \
--not-after "${AUDIT_CERT_DUR:-720h}" --force
incca cp /home/step/certs/root_ca.crt /export/audit/ca.crt
# Stage into ./tls/ (compose bind-mounts it). pki/ may be uid-1000/root-owned
# (see bootstrap.sh perm notes) — copy via the container's /export if needed.
mkdir -p "$COLLECTOR_DIR/tls" 2>/dev/null || { echo "==> fixing tls/ perms with sudo (lab)"; sudo mkdir -p "$COLLECTOR_DIR/tls" && sudo chown "$(id -u)" "$COLLECTOR_DIR/tls"; }
for f in server.crt server.key ca.crt; do
cp pki/audit/"$f" "$COLLECTOR_DIR/tls/$f" 2>/dev/null \
|| { echo "==> pki/audit unreadable by this user; fixing with sudo (lab)"; sudo cp pki/audit/"$f" "$COLLECTOR_DIR/tls/$f" && sudo chown "$(id -u)" "$COLLECTOR_DIR/tls/$f"; }
done
chmod 0600 "$COLLECTOR_DIR/tls/server.key"
chmod 0644 "$COLLECTOR_DIR/tls/server.crt" "$COLLECTOR_DIR/tls/ca.crt"
echo "==> done: $(openssl x509 -in "$COLLECTOR_DIR/tls/server.crt" -noout -subject -enddate 2>/dev/null || echo 'tls/server.crt staged')"
echo " apply: (cd .. && docker compose up -d audit) # or restart if already up"