mailwolt-installer/scripts/75-le-issue.sh

121 lines
4.3 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
set -euo pipefail
source ./lib.sh
ACME_WEBROOT="/var/www/letsencrypt"
install -d -m 0755 "${ACME_WEBROOT}/.well-known/acme-challenge"
# Staging optional (verbraucht kein Live-Limit)
CERTBOT_EXTRA=()
LE_STAGING="${LE_STAGING:-0}"
[[ "$LE_STAGING" = "1" ]] && CERTBOT_EXTRA+=(--test-cert)
# Einheitliche LE-Mail (Fallback)
LE_MAIL="${LE_EMAIL:-admin@${BASE_DOMAIN}}"
resolve_ok() {
local host="$1"
local pats=()
[[ -n "${SERVER_PUBLIC_IPV4:-}" ]] && pats+=("${SERVER_PUBLIC_IPV4//./\\.}")
[[ -n "${SERVER_PUBLIC_IPV6:-}" ]] && pats+=("${SERVER_PUBLIC_IPV6//:/\\:}")
[[ ${#pats[@]} -eq 0 ]] && return 0
getent ahosts "$host" | awk '{print $1}' | sort -u \
| grep -Eq "^($(IFS='|'; echo "${pats[*]}"))$"
}
probe_http() {
local host="$1"
echo test > "${ACME_WEBROOT}/.well-known/acme-challenge/_probe"
curl -fsS --max-time 5 -4 "http://${host}/.well-known/acme-challenge/_probe" >/dev/null \
|| curl -fsS --max-time 5 -6 "http://${host}/.well-known/acme-challenge/_probe" >/dev/null
}
issue() {
local host="${1:-}"
[[ -z "$host" ]] && return 0
echo "[i] Versuche LE für ${host}"
if ! resolve_ok "$host"; then
echo "[!] DNS zeigt (noch) nicht hierher überspringe: ${host}"
return 0
fi
if ! probe_http "$host"; then
echo "[!] ACME-HTTP-Check für ${host} fehlgeschlagen (Port 80/IPv6/Firewall/Nginx prüfen)."
# wir versuchen trotzdem Certbot meldet sich, falls es scheitert
fi
EXTRA_ARGS=()
# Für MX den Key wiederverwenden → stabiler TLSA (3 1 1)
[[ "$host" == "${MAIL_HOSTNAME}" ]] && EXTRA_ARGS+=(--reuse-key)
# WICHTIG: Deploy-Wrapper anhängen, damit Symlinks/Nginx gesetzt werden
certbot certonly \
--agree-tos -m "${LE_MAIL}" --non-interactive \
--webroot -w "${ACME_WEBROOT}" -d "${host}" \
--deploy-hook /usr/local/sbin/mailwolt-deploy.sh \
"${EXTRA_ARGS[@]}" "${CERTBOT_EXTRA[@]}" || true
}
if [[ "${BASE_DOMAIN}" != "example.com" ]]; then
issue "${UI_HOST:-}"
issue "${WEBMAIL_HOST:-}"
issue "${MAIL_HOSTNAME:-}"
# Nginx nur neu laden, wenn aktiv
if systemctl is-active --quiet nginx; then
systemctl reload nginx || true
fi
else
echo "[i] BASE_DOMAIN=example.com LE wird übersprungen."
fi
# ──────────────────────────────────────────────────────────────────────────────
# FIX: Validierung & Reparatur des Mail-Zertifikats
# ──────────────────────────────────────────────────────────────────────────────
MAIL_SSL_DIR="/etc/ssl/mail"
install -d -m 0755 "$MAIL_SSL_DIR"
MAIL_CERT="${MAIL_SSL_DIR}/fullchain.pem"
MAIL_KEY="${MAIL_SSL_DIR}/privkey.pem"
HOST="${MAIL_HOSTNAME:-}"
LE_DIR=""
[[ -n "$HOST" ]] && LE_DIR="/etc/letsencrypt/live/${HOST}"
need_fix=0
# Ist der vorhandene Key gültig? (leer/nicht vorhanden/ungültig -> fix)
if [[ ! -s "$MAIL_KEY" ]] || ! openssl pkey -in "$MAIL_KEY" -noout >/dev/null 2>&1; then
need_fix=1
fi
# Wenn Fix nötig: aus Let's Encrypt Live kopieren
if [[ $need_fix -eq 1 ]]; then
echo "[!] Ungültiger oder fehlender Mail-Private-Key versuche Reparatur …"
if [[ -n "$LE_DIR" && -r "${LE_DIR}/privkey.pem" && -r "${LE_DIR}/fullchain.pem" ]]; then
cp -f "${LE_DIR}/privkey.pem" "$MAIL_KEY"
cp -f "${LE_DIR}/fullchain.pem" "$MAIL_CERT"
chown root:root "$MAIL_CERT" "$MAIL_KEY"
chmod 600 "$MAIL_KEY"
chmod 644 "$MAIL_CERT"
echo "[+] Zertifikate neu kopiert aus ${LE_DIR}."
# Reload NICHT sofort flaggen für 90-services
touch /run/mailwolt.need-dovecot-reload
else
echo "[!] Konnte ${LE_DIR}/privkey.pem oder fullchain.pem nicht lesen bitte prüfen."
fi
else
echo "[✓] Mail-Zertifikat & -Key sind gültig."
fi
# Optionaler Live-Check (nur wenn Host gesetzt)
if [[ -n "$HOST" ]]; then
if openssl s_client -connect "${HOST}:993" -servername "${HOST}" </dev/null 2>/dev/null \
| grep -q "Verify return code: 0"; then
echo "[✓] TLS-Handshake erfolgreich auf imaps://${HOST}:993."
else
echo "[!] TLS-Handshake auf imaps://${HOST}:993 fehlgeschlagen (Dovecot Reload folgt in 90-services, falls Flag gesetzt)."
fi
fi