generated from coulomb/repo-seed
Deploy privacyIDEA (MFA core) in the mfa namespace: - pvc.yaml: privacyidea-data (5Gi) and privacyidea-logs (2Gi) - configmap.yaml: pi.cfg reading secrets from env vars - deployment.yaml: Deployment + ClusterIP Service (port 8080) - middleware.yaml: Traefik RateLimit + admin IP AllowList - ingress.yaml: pink.coulomb.social (portal + admin), pink-account.coulomb.social (self-service) - create-secrets.sh: creates privacyidea-config Secret - enckey-bootstrap.sh: post-deploy key extraction + DR Secrets - bootstrap-admin.sh: pi-admin, trigger-admin, privacyidea-trigger-admin Secret - verify-t04.sh: 8-section done-criteria checker Config points CP-NK-002 (pink.coulomb.social) and CP-NK-003 (pink-account.coulomb.social) registered in CONFIG.md. pink = PrivacyIDEA Net Knights (project mnemonic). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
122 lines
5.3 KiB
Bash
Executable File
122 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# enckey-bootstrap.sh — extract privacyIDEA key material and create DR Secrets
|
|
#
|
|
# Run ONCE after the first successful pod start (deployment.yaml applied and Running).
|
|
#
|
|
# What it does:
|
|
# 1. Finds the running privacyIDEA pod.
|
|
# 2. Generates RSA audit keys inside the pod if they do not exist yet.
|
|
# 3. Extracts: enckey, private.pem, public.pem → local files.
|
|
# 4. Creates K8s Secrets privacyidea-enckey and privacyidea-auditkeys.
|
|
# These are disaster-recovery copies — the authoritative key material
|
|
# lives in the privacyidea-data PVC.
|
|
# 5. Prints instructions to copy the extracted files into KeePassXC.
|
|
#
|
|
# Usage:
|
|
# ./enckey-bootstrap.sh [secrets-dir]
|
|
#
|
|
# <secrets-dir> is where local copies are written (default: ../../bootstrap/secrets).
|
|
# Files in secrets-dir are sensitive — shred them after entering into KeePassXC.
|
|
#
|
|
# Re-running is safe: kubectl apply is idempotent; pi-manage create_audit_keys
|
|
# does not overwrite existing keys.
|
|
|
|
set -euo pipefail
|
|
|
|
NAMESPACE="mfa"
|
|
SECRETS_DIR="${1:-../../bootstrap/secrets}"
|
|
PI_DIR="$SECRETS_DIR/privacyidea"
|
|
|
|
mkdir -p "$PI_DIR"
|
|
|
|
# ── 1. Find the running pod ───────────────────────────────────────────────────
|
|
echo "Looking for running privacyIDEA pod in namespace: $NAMESPACE"
|
|
PI_POD=$(kubectl get pod -n "$NAMESPACE" \
|
|
-l app.kubernetes.io/name=privacyidea \
|
|
--field-selector=status.phase=Running \
|
|
-o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
|
|
|
|
if [[ -z "$PI_POD" ]]; then
|
|
echo "ERROR: no Running privacyIDEA pod found in namespace '$NAMESPACE'." >&2
|
|
echo " Apply the manifests first and wait for the pod to reach Running state:" >&2
|
|
echo " kubectl get pods -n $NAMESPACE -w" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Found pod: $PI_POD"
|
|
|
|
# ── 2. Generate audit keys if missing ────────────────────────────────────────
|
|
echo ""
|
|
echo "Checking for audit keys..."
|
|
if kubectl exec -n "$NAMESPACE" "$PI_POD" -- test -f /etc/privacyidea/private.pem 2>/dev/null; then
|
|
echo " Audit keys already exist — skipping generation."
|
|
else
|
|
echo " Generating audit keys (pi-manage create_audit_keys)..."
|
|
kubectl exec -n "$NAMESPACE" "$PI_POD" -- pi-manage create_audit_keys
|
|
echo " Done."
|
|
fi
|
|
|
|
# ── 3. Check enckey exists (auto-generated by PI on first DB init) ────────────
|
|
echo ""
|
|
echo "Checking for encryption key..."
|
|
if ! kubectl exec -n "$NAMESPACE" "$PI_POD" -- test -f /etc/privacyidea/enckey 2>/dev/null; then
|
|
echo " enckey not found — generating (pi-manage create_enckey)..."
|
|
kubectl exec -n "$NAMESPACE" "$PI_POD" -- pi-manage create_enckey
|
|
echo " Done."
|
|
else
|
|
echo " enckey exists."
|
|
fi
|
|
|
|
# ── 4. Extract key material to local files ────────────────────────────────────
|
|
echo ""
|
|
echo "Extracting key material..."
|
|
|
|
kubectl exec -n "$NAMESPACE" "$PI_POD" -- \
|
|
cat /etc/privacyidea/enckey > "$PI_DIR/pi.enc"
|
|
echo " Wrote: $PI_DIR/pi.enc"
|
|
|
|
kubectl exec -n "$NAMESPACE" "$PI_POD" -- \
|
|
cat /etc/privacyidea/private.pem > "$PI_DIR/private.pem"
|
|
echo " Wrote: $PI_DIR/private.pem"
|
|
|
|
kubectl exec -n "$NAMESPACE" "$PI_POD" -- \
|
|
cat /etc/privacyidea/public.pem > "$PI_DIR/public.pem"
|
|
echo " Wrote: $PI_DIR/public.pem"
|
|
|
|
# ── 5. Create K8s Secrets (DR copies) ────────────────────────────────────────
|
|
echo ""
|
|
echo "Creating K8s Secret: privacyidea-enckey (namespace: $NAMESPACE)"
|
|
kubectl create secret generic privacyidea-enckey \
|
|
--namespace="$NAMESPACE" \
|
|
--from-file=enckey="$PI_DIR/pi.enc" \
|
|
--dry-run=client -o yaml | kubectl apply -f -
|
|
|
|
echo "Creating K8s Secret: privacyidea-auditkeys (namespace: $NAMESPACE)"
|
|
kubectl create secret generic privacyidea-auditkeys \
|
|
--namespace="$NAMESPACE" \
|
|
--from-file=private.pem="$PI_DIR/private.pem" \
|
|
--from-file=public.pem="$PI_DIR/public.pem" \
|
|
--dry-run=client -o yaml | kubectl apply -f -
|
|
|
|
# ── 6. Summary and KeePassXC instructions ─────────────────────────────────────
|
|
echo ""
|
|
echo "════════════════════════════════════════════════════════════"
|
|
echo " Key material extracted and K8s Secrets created."
|
|
echo "════════════════════════════════════════════════════════════"
|
|
echo ""
|
|
echo "IMPORTANT — Store the extracted files in KeePassXC NOW:"
|
|
echo ""
|
|
echo " KeePassXC group: net-kingdom/privacyIDEA"
|
|
echo " Entry: PI_ENCFILE"
|
|
echo " → Attach $PI_DIR/pi.enc as a binary attachment."
|
|
echo " Entry: Audit Keys"
|
|
echo " → Attach $PI_DIR/private.pem and $PI_DIR/public.pem"
|
|
echo ""
|
|
echo " Then shred the local copies:"
|
|
echo " find '$PI_DIR' -name '*.enc' -o -name '*.pem' | xargs shred -u"
|
|
echo ""
|
|
echo "DR restore: if the privacyidea-data PVC is lost, copy these files"
|
|
echo " back into a fresh PVC before starting the pod."
|
|
echo ""
|
|
echo "Next step: run ./bootstrap-admin.sh"
|