#!/bin/bash # update-caddy-certs.sh # Liest alle Domains aus dem DMS und generiert die notwendigen # Caddyfile-Blöcke für Wildcard-Zertifikate. # # Die generierten Blöcke werden NICHT automatisch in das Caddyfile geschrieben, # sondern in eine separate Datei (caddy_mail_certs.conf) ausgegeben, # die per "import" in das Hauptcaddyfile eingebunden werden kann. # # Usage: # DMS_CONTAINER=mailserver ./update-caddy-certs.sh # DMS_CONTAINER=mailserver CADDY_DIR=/pfad/zu/caddy ./update-caddy-certs.sh # DMS_CONTAINER=mailserver DRY_RUN=true ./update-caddy-certs.sh set -e DMS_CONTAINER=${DMS_CONTAINER:-"mailserver"} CADDY_DIR=${CADDY_DIR:-"."} # Verzeichnis wo das Caddyfile liegt OUTPUT_FILE=${OUTPUT_FILE:-"$CADDY_DIR/mail_certs"} # Ohne Extension - Caddy importiert ohne .conf DRY_RUN=${DRY_RUN:-"false"} echo "============================================================" echo " 📜 Caddy Wildcard-Cert Konfig Generator" echo " DMS Container: $DMS_CONTAINER" echo " Output: $OUTPUT_FILE" [ "$DRY_RUN" = "true" ] && echo " ⚠️ DRY RUN - Keine Dateien werden geschrieben" echo "============================================================" # --- Domains aus DMS lesen --- echo "" echo "📋 Lese Domains aus DMS..." DOMAINS=$(docker exec "$DMS_CONTAINER" setup email list 2>/dev/null \ | grep -oP '(?<=@)[^\s]+' \ | sort -u) if [ -z "$DOMAINS" ]; then echo "❌ Keine Accounts gefunden!" exit 1 fi echo " Gefundene Domains:" for d in $DOMAINS; do echo " - $d"; done # --- email-srvr.com immer einschließen (Default-Domain des DMS) --- EXTRA_DOMAINS="email-srvr.com" for extra in $EXTRA_DOMAINS; do if ! echo "$DOMAINS" | grep -q "^${extra}$"; then DOMAINS="$DOMAINS $extra" echo " + $extra (Default DMS Domain - immer dabei)" fi done # --- Konfig generieren --- echo "" echo "📝 Generiere Caddy-Konfiguration..." CONTENT="" CONTENT="${CONTENT}# mail_certs - Automatisch generiert von update-caddy-certs.sh\n" CONTENT="${CONTENT}# Wildcard-Zertifikate für alle DMS-Domains.\n" CONTENT="${CONTENT}# Einbinden im Hauptcaddyfile: import mail_certs\n" CONTENT="${CONTENT}# Generiert: $(date)\n" CONTENT="${CONTENT}\n" for domain in $DOMAINS; do echo " → Block für: $domain" CONTENT="${CONTENT}# Wildcard-Cert für $domain\n" CONTENT="${CONTENT}*.${domain}, ${domain} {\n" CONTENT="${CONTENT} tls {\n" CONTENT="${CONTENT} dns cloudflare {env.CLOUDFLARE_API_TOKEN}\n" CONTENT="${CONTENT} }\n" CONTENT="${CONTENT} respond \"OK\" 200\n" CONTENT="${CONTENT}}\n" CONTENT="${CONTENT}\n" done # --- Ausgabe --- if [ "$DRY_RUN" = "true" ]; then echo "" echo "--- VORSCHAU (DRY RUN) ---" printf '%b' "$CONTENT" echo "--- ENDE VORSCHAU ---" else printf '%b' "$CONTENT" > "$OUTPUT_FILE" echo "" echo " ✅ Geschrieben: $OUTPUT_FILE" fi # --- Prüfen ob Import im Caddyfile vorhanden --- CADDYFILE="$CADDY_DIR/Caddyfile" if [ -f "$CADDYFILE" ]; then if grep -q "import mail_certs" "$CADDYFILE"; then echo " ✅ 'import mail_certs' bereits im Caddyfile vorhanden." else echo "" echo "⚠️ AKTION ERFORDERLICH:" echo " 'import mail_certs' fehlt noch im Caddyfile!" echo " Bitte folgende Zeile am Anfang (nach dem globalen Block) eintragen:" echo "" echo " import mail_certs" echo "" echo " Oder automatisch einfügen? (y/N)" read -r answer if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then # Import nach der ersten Zeile mit "import " einfügen (falls schon welche da sind) # oder nach dem globalen {} Block if grep -q "^import " "$CADDYFILE"; then # Schreibe nach der letzten import-Zeile sed -i "/^import /a import mail_certs" "$CADDYFILE" else # Schreibe nach dem schließenden } des globalen Blocks sed -i "/^}/a \\\nimport mail_certs" "$CADDYFILE" fi echo " ✅ Import eingefügt." fi fi fi # --- Caddy reload --- echo "" echo "============================================================" echo "🔄 Nächste Schritte:" echo "" echo "1. Caddyfile prüfen - 'import mail_certs' muss vorhanden sein" echo "" echo "2. Caddy Konfiguration validieren:" echo " docker exec caddy caddy validate --config /etc/caddy/Caddyfile" echo "" echo "3. Caddy neu laden (kein Downtime):" echo " docker exec caddy caddy reload --config /etc/caddy/Caddyfile" echo "" echo "4. Cert-Generierung verfolgen (dauert ~30s pro Domain):" echo " docker logs -f caddy 2>&1 | grep -i 'certificate\|acme\|tls'" echo "" echo "5. Cert-Pfade prüfen:" echo " ls /var/lib/docker/volumes/caddy_data/_data/caddy/certificates/" echo " acme-v02.api.letsencrypt.org-directory/" echo "============================================================"