mailwolt-installer/scripts/21-le-deploy-hook.sh

460 lines
16 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
# Persistente Installer-Variablen (werden vom Wrapper gelesen)
install -d -m 0755 /etc/mailwolt
cat >/etc/mailwolt/installer.env <<EOF
UI_HOST=${UI_HOST}
WEBMAIL_HOST=${WEBMAIL_HOST}
MAIL_HOSTNAME=${MAIL_HOSTNAME}
BASE_DOMAIN=${BASE_DOMAIN}
LE_EMAIL=${LE_EMAIL:-admin@${BASE_DOMAIN}}
SYSMAIL_SUB="${SYSMAIL_SUB}"
SYSMAIL_DOMAIN="${SYSMAIL_DOMAIN}"
DKIM_ENABLE="${DKIM_ENABLE}"
DKIM_SELECTOR="${DKIM_SELECTOR}"
DKIM_GENERATE="${DKIM_GENERATE}"
APP_ENV=${APP_ENV:-production}
EOF
log "Let's Encrypt Deploy-Hooks und Wrapper anlegen …"
# 1) Wrapper, den Certbot bei Issue/Renew aufruft
cat >/usr/local/sbin/mw-deploy.sh <<'WRAP'
#!/usr/bin/env bash
set -euo pipefail
# Installer-Variablen laden
set +u
[ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env
set -u
UI_HOST="${UI_HOST:-}"
WEBMAIL_HOST="${WEBMAIL_HOST:-}"
MAIL_HOSTNAME="${MAIL_HOSTNAME:-}"
# --- Kopieren statt Symlinks (damit Laravel lesen kann) ---------------------
copy_cert() {
local le_base="$1" target_dir="$2"
local cert="${le_base}/fullchain.pem"
local key="${le_base}/privkey.pem"
[[ -s "$cert" && -s "$key" ]] || return 0
install -d -m 0755 "$target_dir"
# Vorhandene Symlinks entfernen, sonst kopierst du in die LE-Datei hinein
[ -L "${target_dir}/fullchain.pem" ] && rm -f "${target_dir}/fullchain.pem"
[ -L "${target_dir}/privkey.pem" ] && rm -f "${target_dir}/privkey.pem"
# Echte Dateien ablegen
install -m 0644 "$cert" "${target_dir}/fullchain.pem"
install -m 0600 "$key" "${target_dir}/privkey.pem"
echo "[+] Copied ${target_dir}/fullchain.pem und privkey.pem ← ${le_base}"
}
# Nur Domains bearbeiten, die in diesem Lauf betroffen sind.
# Bei manchen Distros ist RENEWED_DOMAINS auf Erst-issue leer -> Fallback nutzen.
RDOMS=" ${RENEWED_DOMAINS:-} "
did_any=0
maybe_copy_for() {
local host="$1" dir="$2"
[[ -z "$host" ]] && return 0
if [[ "$RDOMS" == *" ${host} "* ]]; then
copy_cert "/etc/letsencrypt/live/${host}" "${dir}"
did_any=1
fi
}
# 1) Normalfall: nur die vom Certbot gemeldeten Hosts kopieren
maybe_copy_for "$UI_HOST" "/etc/ssl/ui"
maybe_copy_for "$WEBMAIL_HOST" "/etc/ssl/webmail"
maybe_copy_for "$MAIL_HOSTNAME" "/etc/ssl/mail"
# 2) Fallback: Beim Erstlauf/Edge-Cases alles kopieren, was bereits existiert
if [[ "$did_any" -eq 0 ]]; then
[[ -n "$UI_HOST" && -d "/etc/letsencrypt/live/${UI_HOST}" ]] && copy_cert "/etc/letsencrypt/live/${UI_HOST}" "/etc/ssl/ui"
[[ -n "$WEBMAIL_HOST" && -d "/etc/letsencrypt/live/${WEBMAIL_HOST}" ]] && copy_cert "/etc/letsencrypt/live/${WEBMAIL_HOST}" "/etc/ssl/webmail"
[[ -n "$MAIL_HOSTNAME" && -d "/etc/letsencrypt/live/${MAIL_HOSTNAME}"]] && copy_cert "/etc/letsencrypt/live/${MAIL_HOSTNAME}"/etc/ssl/mail
fi
# Optional: TLSA via Laravel (tolerant, falls App noch nicht gebaut)
if command -v php >/dev/null 2>&1 && [ -d /var/www/mailwolt ] && [ -f /var/www/mailwolt/artisan ]; then
(cd /var/www/mailwolt && php artisan dns:tlsa:refresh) || true
fi
# Nginx nur neu laden, wenn aktiv
if systemctl is-active --quiet nginx; then
systemctl reload nginx || true
fi
WRAP
chmod +x /usr/local/sbin/mw-deploy.sh
# 2) Certbot-Deploy-Hook: ruft den Wrapper bei jeder erfolgreichen Ausstellung/Renew auf
install -d -m 0755 /etc/letsencrypt/renewal-hooks/deploy
cat >/etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-certs.sh <<'HOOK'
#!/usr/bin/env bash
exec /usr/local/sbin/mw-deploy.sh
HOOK
chmod +x /etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-certs.sh
log "[✓] MailWolt Deploy-Hook eingerichtet"
##!/usr/bin/env bash
#set -euo pipefail
#source ./lib.sh
#
## Persistente Installer-Variablen (werden vom Wrapper gelesen)
#install -d -m 0755 /etc/mailwolt
#cat >/etc/mailwolt/installer.env <<EOF
#UI_HOST=${UI_HOST}
#WEBMAIL_HOST=${WEBMAIL_HOST}
#MAIL_HOSTNAME=${MAIL_HOSTNAME}
#BASE_DOMAIN=${BASE_DOMAIN}
#LE_EMAIL=${LE_EMAIL:-admin@${BASE_DOMAIN}}
#APP_ENV=${APP_ENV:-production}
#EOF
#
#log "Let's Encrypt Deploy-Hooks und Wrapper anlegen …"
#
## 1) Wrapper, den Certbot bei Issue/Renew aufruft
#cat >/usr/local/sbin/mw-deploy.sh <<'WRAP'
##!/usr/bin/env bash
#set -euo pipefail
#
## Installer-Variablen laden
#set +u
#[ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env
#set -u
#
#UI_HOST="${UI_HOST:-}"
#WEBMAIL_HOST="${WEBMAIL_HOST:-}"
#MAIL_HOSTNAME="${MAIL_HOSTNAME:-}"
#
## --- Kopieren statt Symlinks (damit Laravel lesen kann) ---------------------
#copy_cert() {
# local le_base="$1" target_dir="$2"
# local cert="${le_base}/fullchain.pem"
# local key="${le_base}/privkey.pem"
#
# [[ -s "$cert" && -s "$key" ]] || return 0
#
# # Zielordner sicherstellen
# install -d -m 0755 "$target_dir"
#
# # Falls vorher Symlinks existieren → entfernen, sonst würde "install" das Ziel des Links überschreiben
# [ -L "${target_dir}/fullchain.pem" ] && rm -f "${target_dir}/fullchain.pem"
# [ -L "${target_dir}/privkey.pem" ] && rm -f "${target_dir}/privkey.pem"
#
# # KOPIEREN mit sauberen Rechten (Chain world-readable, Key nur root)
# install -m 0644 "$cert" "${target_dir}/fullchain.pem"
# install -m 0600 "$key" "${target_dir}/privkey.pem"
#
# echo "[+] Copied ${target_dir}/fullchain.pem und privkey.pem ← ${le_base}"
#}
#
## Nur für Domains arbeiten, die in diesem Lauf betroffen sind
#RDOMS=" ${RENEWED_DOMAINS:-} "
#
## UI
#if [[ -n "$UI_HOST" && "$RDOMS" == *" ${UI_HOST} "* ]]; then
# copy_cert "/etc/letsencrypt/live/${UI_HOST}" "/etc/ssl/ui"
#fi
## Webmail
#if [[ -n "$WEBMAIL_HOST" && "$RDOMS" == *" ${WEBMAIL_HOST} "* ]]; then
# copy_cert "/etc/letsencrypt/live/${WEBMAIL_HOST}" "/etc/ssl/webmail"
#fi
## MX
#if [[ -n "$MAIL_HOSTNAME" && "$RDOMS" == *" ${MAIL_HOSTNAME} "* ]]; then
# copy_cert "/etc/letsencrypt/live/${MAIL_HOSTNAME}" "/etc/ssl/mail"
#fi
#
## Optional: TLSA via Laravel (still tolerant, falls App noch nicht gebaut)
#if command -v php >/dev/null 2>&1 && [ -d /var/www/mailwolt ] && [ -f /var/www/mailwolt/artisan ]; then
# (cd /var/www/mailwolt && php artisan dns:tlsa:refresh) || true
#fi
#
## Nginx nur neu laden, wenn aktiv
#if systemctl is-active --quiet nginx; then
# systemctl reload nginx || true
#fi
#WRAP
#chmod +x /usr/local/sbin/mw-deploy.sh
#
## 2) Certbot-Deploy-Hook: ruft den Wrapper bei jeder erfolgreichen Ausstellung/Renew auf
#install -d -m 0755 /etc/letsencrypt/renewal-hooks/deploy
#cat >/etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-symlinks.sh <<'HOOK'
##!/usr/bin/env bash
#exec /usr/local/sbin/mw-deploy.sh
#HOOK
#chmod +x /etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-symlinks.sh
#
#log "[✓] MailWolt Deploy-Hook eingerichtet"
##!/usr/bin/env bash
#set -euo pipefail
#source ./lib.sh
#
#install -d -m 0755 /etc/mailwolt
#cat >/etc/mailwolt/installer.env <<EOF
#UI_HOST=${UI_HOST}
#WEBMAIL_HOST=${WEBMAIL_HOST}
#MAIL_HOSTNAME=${MAIL_HOSTNAME}
#BASE_DOMAIN=${BASE_DOMAIN}
#LE_EMAIL=${LE_EMAIL:-admin@${BASE_DOMAIN}}
#APP_ENV=${APP_ENV:-production}
#EOF
#
#log "Let's Encrypt Deploy-Hooks und Wrapper anlegen …"
#
## 1) Wrapper, den Certbot bei Issue/Renew aufruft
#cat >/usr/local/sbin/mw-deploy.sh <<'WRAP'
##!/usr/bin/env bash
#set -euo pipefail
#
## Installer-Variablen laden (UI_HOST, WEBMAIL_HOST, MAIL_HOSTNAME, optional LE_EMAIL etc.)
#set +u
#[ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env
#set -u
#
#UI_HOST="${UI_HOST:-}"
#WEBMAIL_HOST="${WEBMAIL_HOST:-}"
#MAIL_HOSTNAME="${MAIL_HOSTNAME:-}"
#
#link_if() {
# local le_base="$1" target_dir="$2"
# local cert="${le_base}/fullchain.pem"
# local key="${le_base}/privkey.pem"
# [[ -s "$cert" && -s "$key" ]] || return 0
# install -d -m 0755 "$target_dir"
# ln -sf "$cert" "${target_dir}/fullchain.pem"
# ln -sf "$key" "${target_dir}/privkey.pem"
# chmod 644 "${target_dir}/fullchain.pem" 2>/dev/null || true
# chmod 600 "${target_dir}/privkey.pem" 2>/dev/null || true
# echo "[+] Linked ${target_dir} -> ${le_base}"
#}
#
## Nur für Domains arbeiten, die im aktuellen Lauf erneuert/ausgestellt wurden
#RDOMS=" ${RENEWED_DOMAINS:-} "
#
## UI
#if [[ -n "$UI_HOST" && "$RDOMS" == *" ${UI_HOST} "* ]]; then
# link_if "/etc/letsencrypt/live/${UI_HOST}" "/etc/ssl/ui"
#fi
## Webmail
#if [[ -n "$WEBMAIL_HOST" && "$RDOMS" == *" ${WEBMAIL_HOST} "* ]]; then
# link_if "/etc/letsencrypt/live/${WEBMAIL_HOST}" "/etc/ssl/webmail"
#fi
## MX
#if [[ -n "$MAIL_HOSTNAME" && "$RDOMS" == *" ${MAIL_HOSTNAME} "* ]]; then
# link_if "/etc/letsencrypt/live/${MAIL_HOSTNAME}" "/etc/ssl/mail"
#fi
#
## Optional: TLSA via Laravel, falls App schon vorhanden (sonst still überspringen)
#if command -v php >/dev/null 2>&1 && [ -d /var/www/mailwolt ]; then
# (cd /var/www/mailwolt && php artisan dns:tlsa:refresh) || true
#fi
#
## Nginx nur neu laden, wenn aktiv
#if systemctl is-active --quiet nginx; then
# systemctl reload nginx || true
#fi
#WRAP
#chmod +x /usr/local/sbin/mw-deploy.sh
#
## 2) Certbot-Deploy-Hooks einrichten (ruft nur den Wrapper auf)
#install -d -m 0755 /etc/letsencrypt/renewal-hooks/deploy
#cat >/etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-symlinks.sh <<'HOOK'
##!/usr/bin/env bash
#exec /usr/local/sbin/mw-deploy.sh
#HOOK
#chmod +x /etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-symlinks.sh
#
#log "[✓] MailWolt Deploy-Hook eingerichtet"
##!/usr/bin/env bash
#set -euo pipefail
#source ./lib.sh
#
#log "Let's Encrypt Deploy-Hooks und Wrapper anlegen …"
#
## 1) Wrapper-Skript, das Symlinks setzt und Nginx reloaded
#cat >/usr/local/sbin/mw-deploy.sh <<'WRAP'
##!/usr/bin/env bash
#set -euo pipefail
#
#link_if() {
# local le_base="$1" target_dir="$2"
# local cert="${le_base}/fullchain.pem"
# local key="${le_base}/privkey.pem"
# [[ -s "$cert" && -s "$key" ]] || return 0
# install -d -m 0755 "$target_dir"
# ln -sf "$cert" "${target_dir}/fullchain.pem"
# ln -sf "$key" "${target_dir}/privkey.pem"
# chmod 644 "${target_dir}/fullchain.pem" 2>/dev/null || true
# chmod 600 "${target_dir}/privkey.pem" 2>/dev/null || true
# echo "[+] Linked ${target_dir} -> ${le_base}"
#}
#
#UI_HOST="${UI_HOST:-}"
#WEBMAIL_HOST="${WEBMAIL_HOST:-}"
#MAIL_HOSTNAME="${MAIL_HOSTNAME:-}"
#
#[[ -n "$UI_HOST" ]] && link_if "/etc/letsencrypt/live/${UI_HOST}" "/etc/ssl/ui"
#[[ -n "$WEBMAIL_HOST" ]] && link_if "/etc/letsencrypt/live/${WEBMAIL_HOST}" "/etc/ssl/webmail"
#[[ -n "$MAIL_HOSTNAME" ]] && link_if "/etc/letsencrypt/live/${MAIL_HOSTNAME}" "/etc/ssl/mail"
#
#if systemctl is-active --quiet nginx; then
# systemctl reload nginx || true
#fi
#WRAP
#
#chmod +x /usr/local/sbin/mw-deploy.sh
#
## 2) Certbot Deploy-Hook-Verzeichnis + Symlink für Renewals
#install -d -m 0755 /etc/letsencrypt/renewal-hooks/deploy
#cat >/etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-symlinks.sh <<'HOOK'
##!/usr/bin/env bash
#exec /usr/local/sbin/mw-deploy.sh
#HOOK
#chmod +x /etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-symlinks.sh
#
#log "[✓] MailWolt Deploy-Hook eingerichtet"
#
###!/usr/bin/env bash
##set -euo pipefail
##source ./lib.sh
##
### ────────────────────────────────────────────────────────────────────────────
### 21-le-deploy-hook.sh
### • legt /etc/mailwolt/installer.env an (falls fehlt)
### • erzeugt Deploy-Hooks:
### - 50-mailwolt-symlinks.sh → verlinkt LE-Zerts nach /etc/ssl/{ui,webmail,mail}
### - 60-mailwolt-tlsa.sh → aktualisiert TLSA (3 1 1) für MX bei jedem Renew
### • KEIN Reload von Postfix/Dovecot (kommt später im Installer)
### ────────────────────────────────────────────────────────────────────────────
##
### 0) Hostnamen persistent speichern (für spätere Deploys)
##install -d -m 0755 /etc/mailwolt
##if [[ ! -f /etc/mailwolt/installer.env ]]; then
## cat >/etc/mailwolt/installer.env <<EOF
##UI_HOST=${UI_HOST}
##WEBMAIL_HOST=${WEBMAIL_HOST}
##MAIL_HOSTNAME=${MAIL_HOSTNAME}
##EOF
## echo "[+] /etc/mailwolt/installer.env erstellt."
##fi
##
### 1) Deploy-Hooks-Verzeichnis anlegen
##install -d -m 0755 /etc/letsencrypt/renewal-hooks/deploy
##
### ────────────────────────────────────────────────────────────────────────────
### 2) 50-mailwolt-symlinks.sh
### ────────────────────────────────────────────────────────────────────────────
##cat >/etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-symlinks.sh <<HOOK
###!/usr/bin/env bash
##set -euo pipefail
##
##UI_LE="/etc/letsencrypt/live/${UI_HOST}"
##WEBMAIL_LE="/etc/letsencrypt/live/${WEBMAIL_HOST}"
##MX_LE="/etc/letsencrypt/live/${MAIL_HOSTNAME}"
##
##UI_SSL_DIR="/etc/ssl/ui"
##WEBMAIL_SSL_DIR="/etc/ssl/webmail"
##MAIL_SSL_DIR="/etc/ssl/mail"
##
### Zielverzeichnisse anlegen (einmalig)
##install -d -m 0755 "\$UI_SSL_DIR" "\$WEBMAIL_SSL_DIR" "\$MAIL_SSL_DIR"
##
##link_if() {
## local le_base="\$1" target_dir="\$2"
## local cert="\${le_base}/fullchain.pem"
## local key="\${le_base}/privkey.pem"
## [[ -s "\$cert" && -s "\$key" ]] || return 0
## ln -sf "\$cert" "\${target_dir}/fullchain.pem"
## ln -sf "\$key" "\${target_dir}/privkey.pem"
## chmod 644 "\${target_dir}/fullchain.pem" 2>/dev/null || true
## chmod 600 "\${target_dir}/privkey.pem" 2>/dev/null || true
## echo "[+] Linked \${target_dir} -> \${le_base}"
##}
##
### Verlinken (nur wenn Host konfiguriert)
##[[ -n "${UI_HOST}" ]] && link_if "\$UI_LE" "\$UI_SSL_DIR"
##[[ -n "${WEBMAIL_HOST}" ]] && link_if "\$WEBMAIL_LE" "\$WEBMAIL_SSL_DIR"
##[[ -n "${MAIL_HOSTNAME}" ]] && link_if "\$MX_LE" "\$MAIL_SSL_DIR"
##
### Nur reloaden, wenn Nginx aktiv ist (Installer startet ihn später erst)
##if systemctl is-active --quiet nginx; then
## systemctl reload nginx || true
##fi
##HOOK
##chmod +x /etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-symlinks.sh
##
### ────────────────────────────────────────────────────────────────────────────
### 3) 60-mailwolt-tlsa.sh
### → nutzt Laravel, falls vorhanden; sonst Fallback mit OpenSSL.
### → schreibt nur, wenn sich der Hash geändert hat (idempotent)
### ────────────────────────────────────────────────────────────────────────────
##cat >/etc/letsencrypt/renewal-hooks/deploy/60-mailwolt-tlsa.sh <<'HOOK'
###!/usr/bin/env bash
##set -euo pipefail
##
### installer.env lesen
##set +u
##[ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env
##set -u
##
##APP_ENV_VAL="${APP_ENV:-production}"
##BASE_DOMAIN_VAL="${BASE_DOMAIN:-example.com}"
##
##case "$APP_ENV_VAL" in
## local|dev|development) exit 0 ;;
##esac
##[ "$BASE_DOMAIN_VAL" = "example.com" ] && exit 0
##
##MX_HOST="${MAIL_HOSTNAME:-}"
##SERVICE="_25._tcp"
##DNS_DIR="/etc/mailwolt/dns"
##OUT_FILE="${DNS_DIR}/${MX_HOST}.tlsa.txt"
##
### Nur reagieren, wenn MX-Zertifikat betroffen war
##case " ${RENEWED_DOMAINS:-} " in
## *" ${MX_HOST} "*) ;;
## *) exit 0 ;;
##esac
##
##CERT="${RENEWED_LINEAGE}/fullchain.pem"
##[ -s "$CERT" ] || exit 0
##
### Wenn Laravel vorhanden ist → interner Command (DB + Datei idempotent)
##if command -v php >/dev/null 2>&1 && [ -d /var/www/mailwolt ]; then
## cd /var/www/mailwolt || exit 0
## php artisan dns:tlsa:refresh || true
## exit 0
##fi
##
### Fallback: nur Datei aktualisieren, wenn Hash sich ändert
##HASH="$(openssl x509 -in "$CERT" -noout -pubkey \
## | openssl pkey -pubin -outform DER \
## | openssl dgst -sha256 | sed 's/^.*= //')"
##NEW_LINE="${SERVICE}.${MX_HOST}. IN TLSA 3 1 1 ${HASH}"
##
##mkdir -p "$DNS_DIR"
##
##if [ -r "$OUT_FILE" ] && grep -q "IN TLSA" "$OUT_FILE"; then
## if grep -q "$HASH" "$OUT_FILE"; then
## echo "[TLSA] Unverändert kein Update nötig."
## exit 0
## fi
##fi
##
##echo "$NEW_LINE" > "$OUT_FILE"
##echo "[TLSA] Aktualisiert: $NEW_LINE"
##HOOK
##chmod +x /etc/letsencrypt/renewal-hooks/deploy/60-mailwolt-tlsa.sh
##
### ────────────────────────────────────────────────────────────────────────────
##echo "[✓] Deploy-Hooks installiert."