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

205 lines
6.6 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
# Gehört ins Root-Verzeichnis des DMS (neben docker-compose.yml).
#
# Generiert Dovecot- und Postfix-SNI-Konfigurationen für Multi-Domain TLS.
# Liest Domains aus dem laufenden DMS und erstellt:
# - docker-data/dms/config/dovecot-sni.cf
# - docker-data/dms/config/postfix-main.cf
#
# Cert-Konvention (Caddy Wildcard):
# /etc/mail/certs/*.domain.tld/*.domain.tld.crt
# /etc/mail/certs/*.domain.tld/*.domain.tld.key
#
# Usage:
# ./setup-dms-tls.sh
# DMS_CONTAINER=mailserver NODE_HOSTNAME=node1.email-srvr.com ./setup-dms-tls.sh
set -e
DMS_CONTAINER=${DMS_CONTAINER:-"mailserver"}
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$SCRIPT_DIR/docker-data/dms/config"
CERTS_BASE_PATH=${CERTS_BASE_PATH:-"/etc/mail/certs"}
# Node-Hostname: Fallback-Cert für DMS (kein Wildcard, direktes Cert)
# Muss mit dem 'hostname' in docker-compose.yml übereinstimmen.
NODE_HOSTNAME=${NODE_HOSTNAME:-"node1.email-srvr.com"}
echo "============================================================"
echo " 🔐 DMS TLS SNI Setup (Multi-Domain)"
echo " DMS Container: $DMS_CONTAINER"
echo " Config Dir: $CONFIG_DIR"
echo " Certs Base: $CERTS_BASE_PATH"
echo " Node Hostname: $NODE_HOSTNAME"
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 im DMS gefunden!"
echo " Bitte zuerst 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 im Container prüfen ---
echo ""
echo "🔍 Prüfe Zertifikat-Verfügbarkeit..."
DOMAINS_OK=""
DOMAINS_MISSING=""
for domain in $DOMAINS; do
CERT_PATH="$CERTS_BASE_PATH/*.$domain/*.$domain.crt"
KEY_PATH="$CERTS_BASE_PATH/*.$domain/*.$domain.key"
if docker exec "$DMS_CONTAINER" test -f "$CERT_PATH" 2>/dev/null; then
echo "$domain → Cert vorhanden"
DOMAINS_OK="$DOMAINS_OK $domain"
else
echo " ⚠️ $domain → KEIN Cert unter $CERT_PATH"
echo " → update-caddy-certs.sh ausführen + caddy reload!"
DOMAINS_MISSING="$DOMAINS_MISSING $domain"
fi
done
# Node-Hostname Cert prüfen (direktes Cert, kein Wildcard)
NODE_CERT_PATH="$CERTS_BASE_PATH/$NODE_HOSTNAME/$NODE_HOSTNAME.crt"
NODE_KEY_PATH="$CERTS_BASE_PATH/$NODE_HOSTNAME/$NODE_HOSTNAME.key"
if docker exec "$DMS_CONTAINER" test -f "$NODE_CERT_PATH" 2>/dev/null; then
echo "$NODE_HOSTNAME → Cert vorhanden (Node Default)"
NODE_CERT_OK=true
else
echo " ⚠️ $NODE_HOSTNAME → KEIN Cert! Caddy-Block im Caddyfile prüfen."
NODE_CERT_OK=false
fi
if [ -n "$DOMAINS_MISSING" ]; then
echo ""
echo " ⚠️ Fehlende Certs:$DOMAINS_MISSING"
echo " Diese Domains werden NICHT in SNI-Config eingetragen."
fi
if [ -z "$DOMAINS_OK" ]; then
echo "❌ Kein einziges Kundendomain-Cert gefunden!"
echo " Bitte zuerst update-caddy-certs.sh ausführen + caddy reload abwarten."
exit 1
fi
# ================================================================
# DOVECOT SNI Konfiguration
# ================================================================
DOVECOT_CFG="$CONFIG_DIR/dovecot-sni.cf"
echo ""
echo "📝 Generiere: $DOVECOT_CFG"
cat > "$DOVECOT_CFG" << 'HEADER'
# dovecot-sni.cf - Automatisch generiert von setup-dms-tls.sh
# SNI-basierte Zertifikat-Auswahl für Dovecot (IMAP/POP3).
# Dovecot liest dieses File über den Volume-Mount in /tmp/docker-mailserver/
# und wendet es automatisch an.
#
# Volume-Mount in docker-compose.yml:
# - ./docker-data/dms/config/dovecot-sni.cf:/tmp/docker-mailserver/dovecot-sni.cf:ro
HEADER
for domain in $DOMAINS_OK; do
CERT_PATH="$CERTS_BASE_PATH/*.$domain/*.$domain.crt"
KEY_PATH="$CERTS_BASE_PATH/*.$domain/*.$domain.key"
cat >> "$DOVECOT_CFG" << EOF
# $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 SNI: $(echo $DOMAINS_OK | wc -w) Domain(s)"
# ================================================================
# POSTFIX SNI Konfiguration
# ================================================================
POSTFIX_CFG="$CONFIG_DIR/postfix-main.cf"
echo ""
echo "📝 Generiere: $POSTFIX_CFG"
# Backup falls vorhanden
if [ -f "$POSTFIX_CFG" ]; then
cp "$POSTFIX_CFG" "${POSTFIX_CFG}.bak.$(date +%Y%m%d%H%M%S)"
echo " Backup: ${POSTFIX_CFG}.bak.*"
fi
# smtpd_tls_chain_files aufbauen: Key + Cert Paar pro Domain
# Postfix wählt automatisch per SNI das passende Paar
CHAIN_LINES=""
for domain in $DOMAINS_OK; do
KEY_PATH="$CERTS_BASE_PATH/*.$domain/*.$domain.key"
CERT_PATH="$CERTS_BASE_PATH/*.$domain/*.$domain.crt"
if [ -z "$CHAIN_LINES" ]; then
CHAIN_LINES=" $KEY_PATH, $CERT_PATH"
else
CHAIN_LINES="$CHAIN_LINES,\n $KEY_PATH, $CERT_PATH"
fi
done
cat > "$POSTFIX_CFG" << POSTFIX_EOF
# postfix-main.cf - Automatisch generiert von setup-dms-tls.sh
# Postfix SNI-Konfiguration: pro Kundendomain ein Key/Cert-Paar.
# Postfix wählt beim TLS-Handshake das passende Paar per SNI.
# DMS lädt dieses File automatisch beim Start.
# TLS Chain: Key + Cert Paare (Postfix >= 3.4)
smtpd_tls_chain_files =
$(printf '%b' "$CHAIN_LINES")
POSTFIX_EOF
echo " ✅ Postfix SNI: $(echo $DOMAINS_OK | wc -w) Domain(s)"
# ================================================================
# Zusammenfassung
# ================================================================
echo ""
echo "============================================================"
echo "✅ Konfigurationen generiert."
echo ""
echo "📋 Nächste Schritte:"
echo ""
echo "1. DMS neu starten:"
echo " docker compose restart mailserver"
echo ""
echo "2. TLS testen (SNI):"
for domain in $DOMAINS_OK; do
echo " openssl s_client -connect mail.$domain:993 -servername mail.$domain 2>/dev/null | grep 'subject\|issuer'"
done
echo ""
echo "3. Bei neuen Domains:"
echo " a) Accounts anlegen: ./manage_mail_user.sh add user@newdomain.com PW"
echo " b) Im Caddy-Dir: ./update-caddy-certs.sh && docker exec caddy caddy reload ..."
echo " c) Warten bis Cert generiert (~30s)"
echo " d) Dieses Script erneut ausführen"
echo " e) docker compose restart mailserver"
echo "============================================================"