email-amazon/DMS/setup-dms-tls.sh

202 lines
7.0 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 "============================================================"