#!/usr/bin/env bash # gen_agent_cert.sh — Generate a TLS certificate for a fleet agent. # # Usage: # ./scripts/gen_agent_cert.sh --agent [--ca-dir ] [--out-dir ] # # Known agents: timmy, allegro, ezra (case-insensitive; any name is accepted) # # Outputs (default: ~/.hermes/pki/agents//): # .key — agent private key (chmod 600, stays on the agent host) # .crt — agent certificate (signed by the fleet CA) # # Run gen_fleet_ca.sh first if you haven't already. # Refs #806 set -euo pipefail CERT_DAYS=365 # 1 year; rotate annually KEY_BITS=2048 # --------------------------------------------------------------------------- # Parse args # --------------------------------------------------------------------------- AGENT_NAME="" CA_DIR="${HOME}/.hermes/pki/ca" OUT_DIR="" while [[ $# -gt 0 ]]; do case "$1" in --agent) AGENT_NAME="${2,,}"; shift 2 ;; # lower-case --ca-dir) CA_DIR="$2"; shift 2 ;; --out-dir) OUT_DIR="$2"; shift 2 ;; -h|--help) echo "Usage: $0 --agent [--ca-dir ] [--out-dir ]" echo " Known agents: timmy, allegro, ezra" exit 0 ;; *) echo "Unknown option: $1" >&2 exit 1 ;; esac done if [[ -z "$AGENT_NAME" ]]; then echo "ERROR: --agent is required." >&2 exit 1 fi OUT_DIR="${OUT_DIR:-${HOME}/.hermes/pki/agents/${AGENT_NAME}}" # --------------------------------------------------------------------------- # Prereq check # --------------------------------------------------------------------------- if ! command -v openssl &>/dev/null; then echo "ERROR: openssl not found." >&2 exit 1 fi CA_KEY="$CA_DIR/fleet-ca.key" CA_CRT="$CA_DIR/fleet-ca.crt" if [[ ! -f "$CA_KEY" || ! -f "$CA_CRT" ]]; then echo "ERROR: Fleet CA not found in $CA_DIR" >&2 echo " Run scripts/gen_fleet_ca.sh first." >&2 exit 1 fi mkdir -p "$OUT_DIR" chmod 700 "$OUT_DIR" AGENT_KEY="$OUT_DIR/${AGENT_NAME}.key" AGENT_CRT="$OUT_DIR/${AGENT_NAME}.crt" AGENT_CSR="$OUT_DIR/${AGENT_NAME}.csr" if [[ -f "$AGENT_KEY" || -f "$AGENT_CRT" ]]; then echo "Cert for agent '$AGENT_NAME' already exists in $OUT_DIR" echo " $AGENT_KEY" echo " $AGENT_CRT" echo "Delete them manually if you want to regenerate." exit 0 fi echo "Generating cert for agent '$AGENT_NAME' ..." SUBJECT="/CN=${AGENT_NAME}.fleet.hermes/O=Hermes/OU=Fleet Agent" # Agent private key openssl genrsa -out "$AGENT_KEY" "$KEY_BITS" 2>/dev/null chmod 600 "$AGENT_KEY" # Certificate Signing Request openssl req -new \ -key "$AGENT_KEY" \ -out "$AGENT_CSR" \ -subj "$SUBJECT" 2>/dev/null # Sign with fleet CA — include SAN so modern TLS stacks accept it EXT_CONF=$(mktemp) trap 'rm -f "$EXT_CONF" "$AGENT_CSR"' EXIT cat > "$EXT_CONF" </dev/null chmod 644 "$AGENT_CRT" echo "" echo "Agent cert generated:" echo " Private key : $AGENT_KEY" echo " Certificate : $AGENT_CRT" echo "" openssl x509 -in "$AGENT_CRT" -noout -subject -issuer -dates