This commit is contained in:
2026-02-22 12:58:24 -06:00
parent b072083318
commit ee19b5b659
5 changed files with 413 additions and 369 deletions

202
DMS/setup-dms-tls.sh Executable file
View File

@@ -0,0 +1,202 @@
#!/bin/bash
# setup-dms-tls.sh
# Generiert Dovecot und Postfix SNI-Konfigurationen für Multi-Domain TLS.
# Liest die vorhandenen Domains aus den DMS Accounts und erstellt:
# - docker-data/dms/config/dovecot-sni.cf (Dovecot SNI pro Domain)
# - docker-data/dms/config/postfix-main.cf (Postfix SNI Map + TLS Chain)
#
# Voraussetzung:
# - Caddy hat Wildcard-Certs gezogen (z.B. *.andreasknuth.de)
# - Cert-Verzeichnis ist gemountet unter /etc/mail/certs im Container
# - Konvention Cert-Pfad: /etc/mail/certs/DOMAIN_NAME/*.DOMAIN_NAME.crt|.key
#
# Usage:
# DMS_CONTAINER=mailserver ./setup-dms-tls.sh
# DMS_CONTAINER=mailserver DEFAULT_DOMAIN=email-srvr.com ./setup-dms-tls.sh
set -e
DMS_CONTAINER=${DMS_CONTAINER:-"mailserver"}
CONFIG_DIR=${CONFIG_DIR:-"./docker-data/dms/config"}
CERTS_BASE_PATH=${CERTS_BASE_PATH:-"/etc/mail/certs"}
# Die Default-Domain für DMS hostname/domainname (bleibt email-srvr.com)
DEFAULT_DOMAIN=${DEFAULT_DOMAIN:-"email-srvr.com"}
echo "============================================================"
echo " 🔐 DMS TLS SNI Setup (Multi-Domain)"
echo " Container: $DMS_CONTAINER"
echo " Config Dir: $CONFIG_DIR"
echo " Certs Base: $CERTS_BASE_PATH"
echo " Default Domain: $DEFAULT_DOMAIN"
echo "============================================================"
# --- Alle Domains aus DMS Accounts 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 im DMS gefunden!"
echo " Bitte zuerst Accounts anlegen: ./manage_mail_user.sh add user@domain.com PW"
exit 1
fi
echo " Gefundene Domains:"
for d in $DOMAINS; do echo " - $d"; done
# --- Cert-Verfügbarkeit prüfen ---
echo ""
echo "🔍 Prüfe Zertifikat-Verfügbarkeit (im Container)..."
DOMAINS_WITH_CERTS=""
DOMAINS_WITHOUT_CERTS=""
for domain in $DOMAINS; do
# Caddy speichert Wildcard-Certs als: *.domain.tld/
# Pfad im Container (über den Volume-Mount): /etc/mail/certs/*.domain.tld/
CERT_PATH="$CERTS_BASE_PATH/*.$domain/*.$domain.crt"
KEY_PATH="$CERTS_BASE_PATH/*.$domain/*.$domain.key"
# Prüfe ob die Datei im Container existiert
if docker exec "$DMS_CONTAINER" test -f "$CERT_PATH" 2>/dev/null; then
echo "$domain → Cert gefunden"
DOMAINS_WITH_CERTS="$DOMAINS_WITH_CERTS $domain"
else
echo " ⚠️ $domain → KEIN Cert unter $CERT_PATH"
echo " Caddy-Block '*.${domain}' eintragen und Caddy neu starten!"
DOMAINS_WITHOUT_CERTS="$DOMAINS_WITHOUT_CERTS $domain"
fi
done
if [ -n "$DOMAINS_WITHOUT_CERTS" ]; then
echo ""
echo "⚠️ WARNUNG: Fehlende Certs für:$DOMAINS_WITHOUT_CERTS"
echo " Diese Domains werden NICHT in die SNI-Configs eingetragen."
echo " Bitte Certs erzeugen und Script erneut ausführen."
echo ""
fi
if [ -z "$DOMAINS_WITH_CERTS" ]; then
echo "❌ Kein einziges Zertifikat gefunden! Abbruch."
exit 1
fi
# ================================================================
# DOVECOT SNI Konfiguration generieren
# ================================================================
DOVECOT_CFG="$CONFIG_DIR/dovecot-sni.cf"
echo ""
echo "📝 Generiere Dovecot SNI Konfiguration: $DOVECOT_CFG"
cat > "$DOVECOT_CFG" << 'HEADER'
# dovecot-sni.cf - Automatisch generiert von setup-dms-tls.sh
# SNI-basierte TLS-Konfiguration für mehrere Domains.
# Dovecot wählt das Zertifikat anhand des SNI-Hostnamens des Clients.
# Dieses File wird via Volume-Mount in den Container eingebunden.
#
# Gemounteter Pfad: /tmp/docker-mailserver/dovecot-sni.cf
# In DMS docker-compose.yml volumes Sektion:
# - ./docker-data/dms/config/dovecot-sni.cf:/tmp/docker-mailserver/dovecot-sni.cf:ro
HEADER
for domain in $DOMAINS_WITH_CERTS; do
CERT_PATH="$CERTS_BASE_PATH/*.$domain/*.$domain.crt"
KEY_PATH="$CERTS_BASE_PATH/*.$domain/*.$domain.key"
cat >> "$DOVECOT_CFG" << EOF
# Domain: $domain
local_name mail.$domain {
ssl_cert = <$CERT_PATH
ssl_key = <$KEY_PATH
}
local_name imap.$domain {
ssl_cert = <$CERT_PATH
ssl_key = <$KEY_PATH
}
local_name smtp.$domain {
ssl_cert = <$CERT_PATH
ssl_key = <$KEY_PATH
}
local_name pop.$domain {
ssl_cert = <$CERT_PATH
ssl_key = <$KEY_PATH
}
EOF
done
echo "$DOVECOT_CFG erstellt ($(echo $DOMAINS_WITH_CERTS | wc -w) Domains)"
# ================================================================
# POSTFIX SNI Konfiguration generieren
# ================================================================
POSTFIX_CFG="$CONFIG_DIR/postfix-main.cf"
echo ""
echo "📝 Generiere Postfix SNI Konfiguration: $POSTFIX_CFG"
# Prüfe ob postfix-main.cf schon existiert und sichere sie
if [ -f "$POSTFIX_CFG" ]; then
cp "$POSTFIX_CFG" "${POSTFIX_CFG}.bak.$(date +%Y%m%d%H%M%S)"
echo " Backup erstellt: ${POSTFIX_CFG}.bak.*"
fi
# TLS Chain Files für Postfix aufbauen
# Postfix unterstützt smtpd_tls_chain_files mit mehreren Key/Cert Paaren
CHAIN_FILES=""
for domain in $DOMAINS_WITH_CERTS; do
KEY_PATH="$CERTS_BASE_PATH/*.$domain/*.$domain.key"
CERT_PATH="$CERTS_BASE_PATH/*.$domain/*.$domain.crt"
if [ -z "$CHAIN_FILES" ]; then
CHAIN_FILES=" $KEY_PATH, $CERT_PATH"
else
CHAIN_FILES="$CHAIN_FILES,\n $KEY_PATH, $CERT_PATH"
fi
done
cat > "$POSTFIX_CFG" << POSTFIX_CONF
# postfix-main.cf - Automatisch generiert von setup-dms-tls.sh
# Postfix SNI-Konfiguration für mehrere Domains.
# DMS lädt dieses File automatisch beim Start via /tmp/docker-mailserver/
# ------------------------------------------------------------------
# TLS Chain Files (Key + Cert pro Domain)
# Postfix wählt das passende Paar automatisch per SNI
# ------------------------------------------------------------------
smtpd_tls_chain_files =
$(printf '%b' "$CHAIN_FILES")
POSTFIX_CONF
echo "$POSTFIX_CFG erstellt"
# ================================================================
# Hinweise für docker-compose.yml
# ================================================================
echo ""
echo "============================================================"
echo "📋 Nächste Schritte:"
echo ""
echo "1. Volume-Mounts in DMS docker-compose.yml hinzufügen:"
echo ""
echo " volumes:"
echo " # Bestehend (Caddy Certs - gesamtes Verzeichnis):"
echo " - /var/lib/docker/volumes/caddy_data/_data/caddy/certificates/"
echo " acme-v02.api.letsencrypt.org-directory:/etc/mail/certs:ro"
echo ""
echo " # NEU - Dovecot SNI:"
echo " - ./docker-data/dms/config/dovecot-sni.cf:/tmp/docker-mailserver/dovecot-sni.cf:ro"
echo ""
echo " # Postfix-main.cf wird von DMS automatisch geladen wenn sie liegt unter:"
echo " - ./docker-data/dms/config/postfix-main.cf:/tmp/docker-mailserver/postfix-main.cf:ro"
echo ""
echo "2. DMS neu starten:"
echo " docker compose restart mailserver"
echo ""
echo "3. TLS testen:"
for domain in $DOMAINS_WITH_CERTS; do
echo " openssl s_client -connect mail.$domain:993 -servername mail.$domain"
done
echo "============================================================"