From 77bcb271088d87e0ef5c921c719c5f3c2820e96d Mon Sep 17 00:00:00 2001 From: boksbc Date: Fri, 17 Oct 2025 21:10:38 +0200 Subject: [PATCH] Laudende Default seite entfernen --- scripts/10-provision.sh | 13 + scripts/21-le-deploy-hook.sh | 5 + scripts/22-dkim-helper.sh | 50 +++ scripts/60-rspamd-opendkim.sh | 610 +++++++++++++++++++++++++--------- scripts/80-app.sh | 42 +++ scripts/bootstrap.sh | 6 + scripts/lib.sh | 28 +- 7 files changed, 589 insertions(+), 165 deletions(-) create mode 100644 scripts/22-dkim-helper.sh diff --git a/scripts/10-provision.sh b/scripts/10-provision.sh index e13df75..05f4ded 100644 --- a/scripts/10-provision.sh +++ b/scripts/10-provision.sh @@ -30,6 +30,19 @@ usermod -a -G "$APP_GROUP" "$APP_USER" || true install -d -m 0755 -o root -g root /var/www install -d -m 0775 -o "$APP_USER" -g "$APP_GROUP" "$APP_DIR" +SUDOERS_DKIM="/etc/sudoers.d/mailwolt-dkim" +cat > "${SUDOERS_DKIM}" </dev/null 2>&1; then + echo "[!] Ungültiger sudoers-Eintrag in ${SUDOERS_DKIM} – entferne Datei." + rm -f "${SUDOERS_DKIM}" +fi + log "MariaDB include-fix …" mkdir -p /etc/mysql/mariadb.conf.d [[ -f /etc/mysql/mariadb.cnf ]] || echo '!include /etc/mysql/mariadb.conf.d/*.cnf' > /etc/mysql/mariadb.cnf diff --git a/scripts/21-le-deploy-hook.sh b/scripts/21-le-deploy-hook.sh index 5d95e8a..57bfb3a 100644 --- a/scripts/21-le-deploy-hook.sh +++ b/scripts/21-le-deploy-hook.sh @@ -10,6 +10,11 @@ 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 diff --git a/scripts/22-dkim-helper.sh b/scripts/22-dkim-helper.sh new file mode 100644 index 0000000..9bf3c16 --- /dev/null +++ b/scripts/22-dkim-helper.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +set -euo pipefail +source ./lib.sh + +log "Installiere DKIM-Helper …" + +install -d -m 0755 /usr/local/sbin + +cat >/usr/local/sbin/mailwolt-install-dkim <<'EOF' +#!/usr/bin/env bash +set -euo pipefail + +DOMAIN="$1" # z.B. sysmail.toastra.com +SELECTOR="${2:-mwl1}" + +[[ -n "$DOMAIN" ]] || { echo "Usage: $0 [selector]"; exit 2; } + +KEYDIR="/etc/opendkim/keys/${DOMAIN}" +PRIV="${KEYDIR}/${SELECTOR}.private" +TXT="${KEYDIR}/${SELECTOR}.txt" + +install -d -m 0750 -o opendkim -g opendkim "$KEYDIR" + +if [[ ! -s "$PRIV" ]]; then + opendkim-genkey -b 2048 -s "$SELECTOR" -d "$DOMAIN" -D "$KEYDIR" + chown opendkim:opendkim "$PRIV" + chmod 600 "$PRIV" +fi + +grep -q "^${SELECTOR}\._domainkey\.${DOMAIN} " /etc/opendkim/KeyTable 2>/dev/null \ + || echo "${SELECTOR}._domainkey.${DOMAIN} ${DOMAIN}:${SELECTOR}:${PRIV}" >> /etc/opendkim/KeyTable + +grep -q "^\*@${DOMAIN} " /etc/opendkim/SigningTable 2>/dev/null \ + || echo "*@${DOMAIN} ${SELECTOR}._domainkey.${DOMAIN}" >> /etc/opendkim/SigningTable + +install -d -m 0755 /etc/mailwolt/dns +[[ -s "$TXT" ]] && cp -f "$TXT" "/etc/mailwolt/dns/dkim-${DOMAIN}.txt" || true + +systemctl restart opendkim +EOF + +chmod 750 /usr/local/sbin/mailwolt-install-dkim +chown root:root /usr/local/sbin/mailwolt-install-dkim + +# Sudo-Berechtigung für den App-User (meist www-data) +APP_USER="${APP_USER:-www-data}" +echo "${APP_USER} ALL=(root) NOPASSWD: /usr/local/sbin/mailwolt-install-dkim *" >/etc/sudoers.d/mailwolt-dkim +chmod 440 /etc/sudoers.d/mailwolt-dkim + +log "[✓] DKIM-Helper installiert: /usr/local/sbin/mailwolt-install-dkim" \ No newline at end of file diff --git a/scripts/60-rspamd-opendkim.sh b/scripts/60-rspamd-opendkim.sh index ad2dde5..b45200f 100644 --- a/scripts/60-rspamd-opendkim.sh +++ b/scripts/60-rspamd-opendkim.sh @@ -4,24 +4,25 @@ source ./lib.sh log "Rspamd + OpenDKIM einrichten …" -# ────────────────────────────────────────────────────────────────────────────── -# Variablen / Defaults -# ────────────────────────────────────────────────────────────────────────────── +# ────────────────────────────────────────────────────────────── +# ENV laden +# ────────────────────────────────────────────────────────────── set +u [ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env set -u BASE_DOMAIN="${BASE_DOMAIN:-example.com}" +SYSMAIL_DOMAIN="${SYSMAIL_DOMAIN:-sysmail.${BASE_DOMAIN}}" +DKIM_ENABLE="${DKIM_ENABLE:-1}" DKIM_SELECTOR="${DKIM_SELECTOR:-mwl1}" -DKIM_GENERATE="${DKIM_GENERATE:-0}" # 1 = Key erzeugen, falls fehlt +DKIM_GENERATE="${DKIM_GENERATE:-1}" RSPAMD_CONTROLLER_PASSWORD="${RSPAMD_CONTROLLER_PASSWORD:-admin}" -# ────────────────────────────────────────────────────────────────────────────── -# Rspamd: Controller + Milter -# ────────────────────────────────────────────────────────────────────────────── +# ────────────────────────────────────────────────────────────── +# Rspamd +# ────────────────────────────────────────────────────────────── install -d -m 0755 /etc/rspamd/local.d -# Controller-Passwort (gehasht, sonst Klartext als Fallback) if command -v rspamadm >/dev/null 2>&1; then RSPAMD_HASH="$(rspamadm pw -p "${RSPAMD_CONTROLLER_PASSWORD}")" else @@ -33,12 +34,10 @@ password = "${RSPAMD_HASH}"; bind_socket = "127.0.0.1:11334"; CONF -# Normal-Worker (Milter-Port für Postfix) cat >/etc/rspamd/local.d/worker-normal.inc <<'CONF' bind_socket = "127.0.0.1:11332"; CONF -# Authentication-Results Header (hilfreich zum Debuggen) cat >/etc/rspamd/local.d/milter_headers.conf <<'CONF' use = ["authentication-results"]; header = "Authentication-Results"; @@ -46,15 +45,24 @@ CONF systemctl enable --now rspamd || true -# ────────────────────────────────────────────────────────────────────────────── -# OpenDKIM Grund-Setup -# ────────────────────────────────────────────────────────────────────────────── +# ────────────────────────────────────────────────────────────── +# OpenDKIM – nur wenn DKIM_ENABLE=1 +# ────────────────────────────────────────────────────────────── +if [[ "${DKIM_ENABLE}" != "1" ]]; then + log "DKIM_ENABLE=0 → OpenDKIM wird übersprungen." + # Stelle sicher, dass Postfix nur Rspamd nutzt: + /usr/sbin/postconf -e "smtpd_milters = inet:127.0.0.1:11332" + /usr/sbin/postconf -e "non_smtpd_milters = inet:127.0.0.1:11332" + systemctl reload postfix || true + exit 0 +fi + install -d -m 0755 /etc/opendkim install -d -m 0750 /etc/opendkim/keys chown -R opendkim:opendkim /etc/opendkim chmod 750 /etc/opendkim/keys -# Trusted Hosts (wer signieren darf) +# TrustedHosts cat >/etc/opendkim/TrustedHosts <<'CONF' 127.0.0.1 ::1 @@ -63,30 +71,34 @@ CONF chown opendkim:opendkim /etc/opendkim/TrustedHosts chmod 640 /etc/opendkim/TrustedHosts -# Key-/Signing-Tabellen -KEY_DIR="/etc/opendkim/keys/${BASE_DOMAIN}" +KEY_DIR="/etc/opendkim/keys/${SYSMAIL_DOMAIN}" KEY_PRIV="${KEY_DIR}/${DKIM_SELECTOR}.private" +KEY_DNSTXT="${KEY_DIR}/${DKIM_SELECTOR}.txt" + install -d -m 0750 -o opendkim -g opendkim "${KEY_DIR}" -# Optional: Key erzeugen, falls gewünscht und nicht vorhanden -if [[ "${DKIM_GENERATE}" = "1" && ! -s "${KEY_PRIV}" ]]; then - if command -v opendkim-genkey >/dev/null 2>&1; then - opendkim-genkey -b 2048 -s "${DKIM_SELECTOR}" -d "${BASE_DOMAIN}" -D "${KEY_DIR}" - chown opendkim:opendkim "${KEY_DIR}/${DKIM_SELECTOR}.private" || true - chmod 600 "${KEY_DIR}/${DKIM_SELECTOR}.private" || true +# Key erzeugen, wenn gewünscht/fehlend +if [[ ! -s "${KEY_PRIV}" ]]; then + if [[ "${DKIM_GENERATE}" = "1" ]]; then + if command -v opendkim-genkey >/dev/null 2>&1; then + opendkim-genkey -b 2048 -s "${DKIM_SELECTOR}" -d "${SYSMAIL_DOMAIN}" -D "${KEY_DIR}" + chown opendkim:opendkim "${KEY_PRIV}" || true + chmod 600 "${KEY_PRIV}" || true + else + echo "[!] opendkim-genkey fehlt – kann DKIM-Key nicht generieren." + fi fi fi -# KeyTable +# Tabellen schreiben (zeigen auf SYSMAIL_DOMAIN) cat >/etc/opendkim/KeyTable </etc/opendkim/SigningTable < /usr/local/sbin/mailwolt-install-dkim <<'EOSH' +#!/usr/bin/env bash +set -euo pipefail -# ────────────────────────────────────────────────────────────────────────────── -# Postfix: Milter-Anbindung (nur setzen, wenn leer) -# ────────────────────────────────────────────────────────────────────────────── -need_set() { - local key="$1" - local cur - cur="$(postconf -h "$key" 2>/dev/null || true)" - [[ -z "$cur" ]] -} +DOMAIN="$1" # z.B. thinkidoo.at +SELECTOR="$2" # z.B. dkim / mwl1 +TMP_PRIV="$3" # Pfad: Private-Key PEM (von der App erzeugt) +TMP_PUBTXT="${4:-}" # optional: Datei mit fertigem DNS-TXT -if need_set smtpd_milters; then +OKDIR="/etc/opendkim" +KEYDIR="${OKDIR}/keys/${DOMAIN}" +KEYPRI="${KEYDIR}/${SELECTOR}.private" + +install -d -m 0750 -o opendkim -g opendkim "${KEYDIR}" +install -m 0600 -o opendkim -g opendkim "${TMP_PRIV}" "${KEYPRI}" + +kt="${OKDIR}/KeyTable" +st="${OKDIR}/SigningTable" +touch "$kt" "$st" +chown opendkim:opendkim "$kt" "$st" +chmod 0640 "$kt" "$st" + +line_kt="${SELECTOR}._domainkey.${DOMAIN} ${DOMAIN}:${SELECTOR}:${KEYPRI}" +grep -Fqx "$line_kt" "$kt" || echo "$line_kt" >> "$kt" + +line_st="*@${DOMAIN} ${SELECTOR}._domainkey.${DOMAIN}" +grep -Fqx "$line_st" "$st" || echo "$line_st" >> "$st" + +if [[ -n "${TMP_PUBTXT}" && -s "${TMP_PUBTXT}" ]]; then + install -d -m 0755 /etc/mailwolt/dns + cp -f "${TMP_PUBTXT}" "/etc/mailwolt/dns/dkim-${DOMAIN}.txt" +fi + +systemctl restart opendkim +echo "OK" +EOSH +chown root:root /usr/local/sbin/mailwolt-install-dkim +chmod 0750 /usr/local/sbin/mailwolt-install-dkim + +# Nur starten, wenn der Private Key existiert +if [[ -s "${KEY_PRIV}" ]]; then + systemctl enable --now opendkim || true + systemctl restart opendkim || true + + # Postfix an beide Milters hängen /usr/sbin/postconf -e "smtpd_milters = inet:127.0.0.1:11332, inet:127.0.0.1:8891" -fi -if need_set non_smtpd_milters; then /usr/sbin/postconf -e "non_smtpd_milters = inet:127.0.0.1:11332, inet:127.0.0.1:8891" + systemctl reload postfix || true + + # DNS-Export ablegen (für UI/Hinweis) + install -d -m 0755 /etc/mailwolt/dns + [[ -s "${KEY_DNSTXT}" ]] && cp -f "${KEY_DNSTXT}" "/etc/mailwolt/dns/dkim-${SYSMAIL_DOMAIN}.txt" || true + + echo "[✓] OpenDKIM aktiv für ${SYSMAIL_DOMAIN} (Selector: ${DKIM_SELECTOR})" + echo " DNS: ${DKIM_SELECTOR}._domainkey.${SYSMAIL_DOMAIN} (siehe ${KEY_DNSTXT})" +else + echo "[!] Kein Private Key: ${KEY_PRIV}" + echo " - Setze DKIM_GENERATE=1 ODER lege Key-Datei manuell ab (opendkim:opendkim, 600)." + echo " - Postfix bleibt bis dahin nur mit Rspamd-Milter verbunden." + /usr/sbin/postconf -e "smtpd_milters = inet:127.0.0.1:11332" + /usr/sbin/postconf -e "non_smtpd_milters = inet:127.0.0.1:11332" + systemctl reload postfix || true fi -systemctl reload postfix || true - -# ────────────────────────────────────────────────────────────────────────────── -# Hinweis -# ────────────────────────────────────────────────────────────────────────────── -if [[ ! -s "${KEY_PRIV}" ]]; then - echo "[!] OpenDKIM: Kein Private Key gefunden unter: ${KEY_PRIV}" - echo " - Lege dort den Private Key ab (opendkim:opendkim, 600) ODER" - echo " - setze DKIM_GENERATE=1 und starte dieses Skript erneut." -fi - -echo "[✓] Rspamd + OpenDKIM fertig. Postfix ist an Rspamd (11332) und OpenDKIM (8891) angebunden." ##!/usr/bin/env bash #set -euo pipefail #source ./lib.sh # -#log "Rspamd + OpenDKIM einrichten …" +#log "Rspamd + OpenDKIM vorbereiten …" # -## --------------------------- +## ────────────────────────────────────────────────────────────────────────────── ## Variablen / Defaults -## --------------------------- -## Installer-Variablen laden, falls vorhanden +## ────────────────────────────────────────────────────────────────────────────── #set +u #[ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env #set -u # #BASE_DOMAIN="${BASE_DOMAIN:-example.com}" #DKIM_SELECTOR="${DKIM_SELECTOR:-mwl1}" -#DKIM_GENERATE="${DKIM_GENERATE:-0}" # 1 = Key erzeugen, falls fehlt #RSPAMD_CONTROLLER_PASSWORD="${RSPAMD_CONTROLLER_PASSWORD:-admin}" # -## --------------------------- -## Rspamd: Controller + Milter -## --------------------------- +## ────────────────────────────────────────────────────────────────────────────── +## Rspamd +## ────────────────────────────────────────────────────────────────────────────── #install -d -m 0755 /etc/rspamd/local.d # -## Controller-Passwort gehasht schreiben #if command -v rspamadm >/dev/null 2>&1; then # RSPAMD_HASH="$(rspamadm pw -p "${RSPAMD_CONTROLLER_PASSWORD}")" #else -# # Fallback: falls rspamadm noch nicht verfügbar ist (sollte selten sein) -# # schreibe Klartext, damit Rspamd danach startbar ist; Hashen kann im nächsten Lauf erfolgen. # RSPAMD_HASH="${RSPAMD_CONTROLLER_PASSWORD}" #fi # @@ -192,12 +232,10 @@ echo "[✓] Rspamd + OpenDKIM fertig. Postfix ist an Rspamd (11332) und OpenDKIM #bind_socket = "127.0.0.1:11334"; #CONF # -## Normal-Worker (Milter-Port für Postfix) #cat >/etc/rspamd/local.d/worker-normal.inc <<'CONF' #bind_socket = "127.0.0.1:11332"; #CONF # -## Authentication-Results Header schreiben (praktisch zum Debuggen) #cat >/etc/rspamd/local.d/milter_headers.conf <<'CONF' #use = ["authentication-results"]; #header = "Authentication-Results"; @@ -205,15 +243,14 @@ echo "[✓] Rspamd + OpenDKIM fertig. Postfix ist an Rspamd (11332) und OpenDKIM # #systemctl enable --now rspamd || true # -## --------------------------- -## OpenDKIM Grund-Setup -## --------------------------- +## ────────────────────────────────────────────────────────────────────────────── +## OpenDKIM – nur vorbereiten, nicht starten +## ────────────────────────────────────────────────────────────────────────────── #install -d -m 0755 /etc/opendkim #install -d -m 0750 /etc/opendkim/keys #chown -R opendkim:opendkim /etc/opendkim #chmod 750 /etc/opendkim/keys # -## TrustedHosts (wer signieren darf) #cat >/etc/opendkim/TrustedHosts <<'CONF' #127.0.0.1 #::1 @@ -222,59 +259,22 @@ echo "[✓] Rspamd + OpenDKIM fertig. Postfix ist an Rspamd (11332) und OpenDKIM #chown opendkim:opendkim /etc/opendkim/TrustedHosts #chmod 640 /etc/opendkim/TrustedHosts # -## Key-/Signing-Tabellen vorbereiten -#KEY_DIR="/etc/opendkim/keys/${BASE_DOMAIN}" -#KEY_PRIV="${KEY_DIR}/${DKIM_SELECTOR}.private" -# -#install -d -m 0750 -o opendkim -g opendkim "${KEY_DIR}" -# -## Falls gewünscht: fehlenden Key erzeugen -#if [[ "${DKIM_GENERATE}" = "1" && ! -s "${KEY_PRIV}" ]]; then -# if command -v opendkim-genkey >/dev/null 2>&1; then -# opendkim-genkey -b 2048 -s "${DKIM_SELECTOR}" -d "${BASE_DOMAIN}" -D "${KEY_DIR}" -# # opendkim legt .private und .txt an (Selector.*) -# chown opendkim:opendkim "${KEY_DIR}/${DKIM_SELECTOR}.private" || true -# chmod 600 "${KEY_DIR}/${DKIM_SELECTOR}.private" || true -# fi -#fi -# -## KeyTable (Selector → Keydatei) -#cat >/etc/opendkim/KeyTable </etc/opendkim/SigningTable </etc/opendkim.conf <<'CONF' #Syslog yes #UMask 002 #Mode sv #Socket inet:8891@127.0.0.1 #Canonicalization relaxed/simple -# -## Nicht blockieren, wenn mal was fehlt #On-BadSignature accept #On-Default accept #On-KeyNotFound accept #On-NoSignature accept -# #LogWhy yes #OversignHeaders From -# -## Tabellen/Listen #KeyTable /etc/opendkim/KeyTable #SigningTable refile:/etc/opendkim/SigningTable #ExternalIgnoreList /etc/opendkim/TrustedHosts #InternalHosts /etc/opendkim/TrustedHosts -# #UserID opendkim:opendkim #AutoRestart yes #AutoRestartRate 10/1h @@ -283,66 +283,364 @@ echo "[✓] Rspamd + OpenDKIM fertig. Postfix ist an Rspamd (11332) und OpenDKIM #SignatureAlgorithm rsa-sha256 #CONF # -#systemctl enable --now opendkim || true -#systemctl restart opendkim || true -#systemctl restart rspamd || true +#cat >/etc/default/opendkim <<'CONF' +#RUNDIR=/run/opendkim +#SOCKET="inet:8891@127.0.0.1" +#USER=opendkim +#GROUP=opendkim +#PIDFILE=/run/opendkim/opendkim.pid +#CONF # -## --------------------------- -## Postfix: Milter-Anbindung prüfen/setzen (nur ergänzen, nicht zerstören) -## --------------------------- -## Diese Werte setzt dein Postfix-Skript normalerweise bereits. -## Hier nur als Absicherung, falls noch leer. -#need_set() { -# local key="$1" -# local cur -# cur="$(postconf -h "$key" 2>/dev/null || true)" -# [[ -z "$cur" ]] -#} +#systemctl disable --now opendkim >/dev/null 2>&1 || true # -#if need_set smtpd_milters; then -# /usr/sbin/postconf -e "smtpd_milters = inet:127.0.0.1:11332, inet:127.0.0.1:8891" -#fi -#if need_set non_smtpd_milters; then -# /usr/sbin/postconf -e "non_smtpd_milters = inet:127.0.0.1:11332, inet:127.0.0.1:8891" -#fi -# -#systemctl reload postfix || true -# -## --------------------------- -## Hinweise (einmalig, nicht kritisch) -## --------------------------- -#if [[ ! -s "${KEY_PRIV}" ]]; then -# echo "[!] OpenDKIM: Kein Private Key gefunden unter: ${KEY_PRIV}" -# echo " - Wenn deine App die Keys verwaltet, lege die Private-Key-Datei genau dort ab" -# echo " (Owner: opendkim:opendkim, Mode: 600) und passe ggf. DKIM_SELECTOR/BASIS_DOMAIN an." -# echo " - Oder setze DKIM_GENERATE=1 und starte dieses Skript erneut, um einen Key zu erzeugen." -#fi -# -#echo "[✓] Rspamd + OpenDKIM fertig. Postfix ist an Rspamd (11332) und OpenDKIM (8891) angebunden." +#echo "[i] OpenDKIM wurde vorbereitet, aber nicht gestartet." +#echo "[i] Es wird nach dem Seeder aktiviert, sobald der erste DKIM-Key existiert." # ###!/usr/bin/env bash ##set -euo pipefail ##source ./lib.sh ## -##log "Rspamd + OpenDKIM …" +##log "Rspamd + OpenDKIM einrichten …" ## -##cat > /etc/rspamd/local.d/worker-controller.inc <<'CONF' -##password = "admin"; +### ────────────────────────────────────────────────────────────────────────────── +### Variablen / Defaults +### ────────────────────────────────────────────────────────────────────────────── +##set +u +##[ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env +##set -u +## +##BASE_DOMAIN="${BASE_DOMAIN:-example.com}" +##DKIM_SELECTOR="${DKIM_SELECTOR:-mwl1}" +##DKIM_GENERATE="${DKIM_GENERATE:-0}" # 1 = Key erzeugen, falls fehlt +##RSPAMD_CONTROLLER_PASSWORD="${RSPAMD_CONTROLLER_PASSWORD:-admin}" +## +### ────────────────────────────────────────────────────────────────────────────── +### Rspamd: Controller + Milter +### ────────────────────────────────────────────────────────────────────────────── +##install -d -m 0755 /etc/rspamd/local.d +## +### Controller-Passwort (gehasht, sonst Klartext als Fallback) +##if command -v rspamadm >/dev/null 2>&1; then +## RSPAMD_HASH="$(rspamadm pw -p "${RSPAMD_CONTROLLER_PASSWORD}")" +##else +## RSPAMD_HASH="${RSPAMD_CONTROLLER_PASSWORD}" +##fi +## +##cat >/etc/rspamd/local.d/worker-controller.inc </etc/rspamd/local.d/worker-normal.inc <<'CONF' +##bind_socket = "127.0.0.1:11332"; +##CONF +## +### Authentication-Results Header (hilfreich zum Debuggen) +##cat >/etc/rspamd/local.d/milter_headers.conf <<'CONF' +##use = ["authentication-results"]; +##header = "Authentication-Results"; +##CONF +## ##systemctl enable --now rspamd || true ## -##cat > /etc/opendkim.conf <<'CONF' -##Syslog yes -##UMask 002 -##Mode sv -##Socket inet:8891@127.0.0.1 -##Canonicalization relaxed/simple -##On-BadSignature accept -##On-Default accept -##On-KeyNotFound accept -##On-NoSignature accept -##LogWhy yes -##OversignHeaders From +### ────────────────────────────────────────────────────────────────────────────── +### OpenDKIM Grund-Setup +### ────────────────────────────────────────────────────────────────────────────── +##install -d -m 0755 /etc/opendkim +##install -d -m 0750 /etc/opendkim/keys +##chown -R opendkim:opendkim /etc/opendkim +##chmod 750 /etc/opendkim/keys +## +### Trusted Hosts (wer signieren darf) +##cat >/etc/opendkim/TrustedHosts <<'CONF' +##127.0.0.1 +##::1 +##localhost ##CONF +##chown opendkim:opendkim /etc/opendkim/TrustedHosts +##chmod 640 /etc/opendkim/TrustedHosts +## +### Key-/Signing-Tabellen +##KEY_DIR="/etc/opendkim/keys/${BASE_DOMAIN}" +##KEY_PRIV="${KEY_DIR}/${DKIM_SELECTOR}.private" +##install -d -m 0750 -o opendkim -g opendkim "${KEY_DIR}" +## +### Optional: Key erzeugen, falls gewünscht und nicht vorhanden +##if [[ "${DKIM_GENERATE}" = "1" && ! -s "${KEY_PRIV}" ]]; then +## if command -v opendkim-genkey >/dev/null 2>&1; then +## opendkim-genkey -b 2048 -s "${DKIM_SELECTOR}" -d "${BASE_DOMAIN}" -D "${KEY_DIR}" +## chown opendkim:opendkim "${KEY_DIR}/${DKIM_SELECTOR}.private" || true +## chmod 600 "${KEY_DIR}/${DKIM_SELECTOR}.private" || true +## fi +##fi +## +### KeyTable +##cat >/etc/opendkim/KeyTable </etc/opendkim/SigningTable </etc/opendkim.conf <<'CONF' +##Syslog yes +##UMask 002 +##Mode sv +##Socket inet:8891@127.0.0.1 +##Canonicalization relaxed/simple +## +##On-BadSignature accept +##On-Default accept +##On-KeyNotFound accept +##On-NoSignature accept +## +##LogWhy yes +##OversignHeaders From +## +##KeyTable /etc/opendkim/KeyTable +##SigningTable refile:/etc/opendkim/SigningTable +##ExternalIgnoreList /etc/opendkim/TrustedHosts +##InternalHosts /etc/opendkim/TrustedHosts +## +##UserID opendkim:opendkim +##AutoRestart yes +##AutoRestartRate 10/1h +##Background yes +##DNSTimeout 5 +##SignatureAlgorithm rsa-sha256 +##CONF +## ##systemctl enable --now opendkim || true +##systemctl restart opendkim || true +##systemctl restart rspamd || true +## +### ────────────────────────────────────────────────────────────────────────────── +### Postfix: Milter-Anbindung (nur setzen, wenn leer) +### ────────────────────────────────────────────────────────────────────────────── +##need_set() { +## local key="$1" +## local cur +## cur="$(postconf -h "$key" 2>/dev/null || true)" +## [[ -z "$cur" ]] +##} +## +##if need_set smtpd_milters; then +## /usr/sbin/postconf -e "smtpd_milters = inet:127.0.0.1:11332, inet:127.0.0.1:8891" +##fi +##if need_set non_smtpd_milters; then +## /usr/sbin/postconf -e "non_smtpd_milters = inet:127.0.0.1:11332, inet:127.0.0.1:8891" +##fi +## +##systemctl reload postfix || true +## +### ────────────────────────────────────────────────────────────────────────────── +### Hinweis +### ────────────────────────────────────────────────────────────────────────────── +##if [[ ! -s "${KEY_PRIV}" ]]; then +## echo "[!] OpenDKIM: Kein Private Key gefunden unter: ${KEY_PRIV}" +## echo " - Lege dort den Private Key ab (opendkim:opendkim, 600) ODER" +## echo " - setze DKIM_GENERATE=1 und starte dieses Skript erneut." +##fi +## +##echo "[✓] Rspamd + OpenDKIM fertig. Postfix ist an Rspamd (11332) und OpenDKIM (8891) angebunden." +## +####!/usr/bin/env bash +###set -euo pipefail +###source ./lib.sh +### +###log "Rspamd + OpenDKIM einrichten …" +### +#### --------------------------- +#### Variablen / Defaults +#### --------------------------- +#### Installer-Variablen laden, falls vorhanden +###set +u +###[ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env +###set -u +### +###BASE_DOMAIN="${BASE_DOMAIN:-example.com}" +###DKIM_SELECTOR="${DKIM_SELECTOR:-mwl1}" +###DKIM_GENERATE="${DKIM_GENERATE:-0}" # 1 = Key erzeugen, falls fehlt +###RSPAMD_CONTROLLER_PASSWORD="${RSPAMD_CONTROLLER_PASSWORD:-admin}" +### +#### --------------------------- +#### Rspamd: Controller + Milter +#### --------------------------- +###install -d -m 0755 /etc/rspamd/local.d +### +#### Controller-Passwort gehasht schreiben +###if command -v rspamadm >/dev/null 2>&1; then +### RSPAMD_HASH="$(rspamadm pw -p "${RSPAMD_CONTROLLER_PASSWORD}")" +###else +### # Fallback: falls rspamadm noch nicht verfügbar ist (sollte selten sein) +### # schreibe Klartext, damit Rspamd danach startbar ist; Hashen kann im nächsten Lauf erfolgen. +### RSPAMD_HASH="${RSPAMD_CONTROLLER_PASSWORD}" +###fi +### +###cat >/etc/rspamd/local.d/worker-controller.inc </etc/rspamd/local.d/worker-normal.inc <<'CONF' +###bind_socket = "127.0.0.1:11332"; +###CONF +### +#### Authentication-Results Header schreiben (praktisch zum Debuggen) +###cat >/etc/rspamd/local.d/milter_headers.conf <<'CONF' +###use = ["authentication-results"]; +###header = "Authentication-Results"; +###CONF +### +###systemctl enable --now rspamd || true +### +#### --------------------------- +#### OpenDKIM Grund-Setup +#### --------------------------- +###install -d -m 0755 /etc/opendkim +###install -d -m 0750 /etc/opendkim/keys +###chown -R opendkim:opendkim /etc/opendkim +###chmod 750 /etc/opendkim/keys +### +#### TrustedHosts (wer signieren darf) +###cat >/etc/opendkim/TrustedHosts <<'CONF' +###127.0.0.1 +###::1 +###localhost +###CONF +###chown opendkim:opendkim /etc/opendkim/TrustedHosts +###chmod 640 /etc/opendkim/TrustedHosts +### +#### Key-/Signing-Tabellen vorbereiten +###KEY_DIR="/etc/opendkim/keys/${BASE_DOMAIN}" +###KEY_PRIV="${KEY_DIR}/${DKIM_SELECTOR}.private" +### +###install -d -m 0750 -o opendkim -g opendkim "${KEY_DIR}" +### +#### Falls gewünscht: fehlenden Key erzeugen +###if [[ "${DKIM_GENERATE}" = "1" && ! -s "${KEY_PRIV}" ]]; then +### if command -v opendkim-genkey >/dev/null 2>&1; then +### opendkim-genkey -b 2048 -s "${DKIM_SELECTOR}" -d "${BASE_DOMAIN}" -D "${KEY_DIR}" +### # opendkim legt .private und .txt an (Selector.*) +### chown opendkim:opendkim "${KEY_DIR}/${DKIM_SELECTOR}.private" || true +### chmod 600 "${KEY_DIR}/${DKIM_SELECTOR}.private" || true +### fi +###fi +### +#### KeyTable (Selector → Keydatei) +###cat >/etc/opendkim/KeyTable </etc/opendkim/SigningTable </etc/opendkim.conf <<'CONF' +###Syslog yes +###UMask 002 +###Mode sv +###Socket inet:8891@127.0.0.1 +###Canonicalization relaxed/simple +### +#### Nicht blockieren, wenn mal was fehlt +###On-BadSignature accept +###On-Default accept +###On-KeyNotFound accept +###On-NoSignature accept +### +###LogWhy yes +###OversignHeaders From +### +#### Tabellen/Listen +###KeyTable /etc/opendkim/KeyTable +###SigningTable refile:/etc/opendkim/SigningTable +###ExternalIgnoreList /etc/opendkim/TrustedHosts +###InternalHosts /etc/opendkim/TrustedHosts +### +###UserID opendkim:opendkim +###AutoRestart yes +###AutoRestartRate 10/1h +###Background yes +###DNSTimeout 5 +###SignatureAlgorithm rsa-sha256 +###CONF +### +###systemctl enable --now opendkim || true +###systemctl restart opendkim || true +###systemctl restart rspamd || true +### +#### --------------------------- +#### Postfix: Milter-Anbindung prüfen/setzen (nur ergänzen, nicht zerstören) +#### --------------------------- +#### Diese Werte setzt dein Postfix-Skript normalerweise bereits. +#### Hier nur als Absicherung, falls noch leer. +###need_set() { +### local key="$1" +### local cur +### cur="$(postconf -h "$key" 2>/dev/null || true)" +### [[ -z "$cur" ]] +###} +### +###if need_set smtpd_milters; then +### /usr/sbin/postconf -e "smtpd_milters = inet:127.0.0.1:11332, inet:127.0.0.1:8891" +###fi +###if need_set non_smtpd_milters; then +### /usr/sbin/postconf -e "non_smtpd_milters = inet:127.0.0.1:11332, inet:127.0.0.1:8891" +###fi +### +###systemctl reload postfix || true +### +#### --------------------------- +#### Hinweise (einmalig, nicht kritisch) +#### --------------------------- +###if [[ ! -s "${KEY_PRIV}" ]]; then +### echo "[!] OpenDKIM: Kein Private Key gefunden unter: ${KEY_PRIV}" +### echo " - Wenn deine App die Keys verwaltet, lege die Private-Key-Datei genau dort ab" +### echo " (Owner: opendkim:opendkim, Mode: 600) und passe ggf. DKIM_SELECTOR/BASIS_DOMAIN an." +### echo " - Oder setze DKIM_GENERATE=1 und starte dieses Skript erneut, um einen Key zu erzeugen." +###fi +### +###echo "[✓] Rspamd + OpenDKIM fertig. Postfix ist an Rspamd (11332) und OpenDKIM (8891) angebunden." +### +#####!/usr/bin/env bash +####set -euo pipefail +####source ./lib.sh +#### +####log "Rspamd + OpenDKIM …" +#### +####cat > /etc/rspamd/local.d/worker-controller.inc <<'CONF' +####password = "admin"; +####bind_socket = "127.0.0.1:11334"; +####CONF +####systemctl enable --now rspamd || true +#### +####cat > /etc/opendkim.conf <<'CONF' +####Syslog yes +####UMask 002 +####Mode sv +####Socket inet:8891@127.0.0.1 +####Canonicalization relaxed/simple +####On-BadSignature accept +####On-Default accept +####On-KeyNotFound accept +####On-NoSignature accept +####LogWhy yes +####OversignHeaders From +####CONF +####systemctl enable --now opendkim || true diff --git a/scripts/80-app.sh b/scripts/80-app.sh index 92d264e..bce6769 100644 --- a/scripts/80-app.sh +++ b/scripts/80-app.sh @@ -81,6 +81,12 @@ upsert_env APP_FALLBACK_LOCALE "en" upsert_env SERVER_PUBLIC_IPV4 "${SERVER_PUBLIC_IPV4}" upsert_env SERVER_PUBLIC_IPV6 "${SERVER_PUBLIC_IPV6:-}" +upsert_env SYSMAIL_SUB "${SYSMAIL_SUB}" +upsert_env SYSMAIL_DOMAIN "${SYSMAIL_DOMAIN}" +upsert_env DKIM_ENABLE "${DKIM_ENABLE}" +upsert_env DKIM_SELECTOR "${DKIM_SELECTOR}" +upsert_env DKIM_GENERATE "${DKIM_GENERATE}" + upsert_env BASE_DOMAIN "${BASE_DOMAIN}" upsert_env UI_SUB "${UI_SUB}" upsert_env WEBMAIL_SUB "${WEBMAIL_SUB}" @@ -174,6 +180,42 @@ if [[ "${BASE_DOMAIN}" != "example.com" ]]; then sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan db:seed --class=SystemDomainSeeder --force" fi +set +u +[ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env +set -u + +# Defaults, falls was fehlt +DKIM_ENABLE="${DKIM_ENABLE:-1}" # 1=an, 0=aus +DKIM_SELECTOR="${DKIM_SELECTOR:-mwl1}" +SYSMAIL_DOMAIN="${SYSMAIL_DOMAIN:-sysmail.${BASE_DOMAIN}}" + +if [[ "${DKIM_ENABLE}" = "1" && -n "${SYSMAIL_DOMAIN}" ]]; then + log "Erzeuge/aktualisiere DKIM für ${SYSMAIL_DOMAIN} (Selector: ${DKIM_SELECTOR}) …" + + TMP_PRIV="$(mktemp -p /tmp dkim_priv_XXXXXX.pem)" + TMP_TXT="$(mktemp -p /tmp dkim_txt_XXXXXX.txt)" + + # Erzeuge Key via deinem bestehenden DkimService (idempotent in der App) + sudo -u "${APP_USER}" -H bash -lc "cd ${APP_DIR} && php -r ' + require \"vendor/autoload.php\"; + \$app = require \"bootstrap/app.php\"; + \$kernel = \$app->make(Illuminate\\Contracts\\Console\\Kernel::class); \$kernel->bootstrap(); + \$domain = App\\Models\\Domain::firstOrCreate([\"domain\"=>\"${SYSMAIL_DOMAIN}\"],[\"is_active\"=>1,\"is_system\"=>1]); + \$svc = app(App\\Services\\DkimService::class); + \$res = \$svc->generateForDomain(\$domain, 2048, \"${DKIM_SELECTOR}\"); + file_put_contents(\"${TMP_PRIV}\", \$res[\"private_pem\"]); + file_put_contents(\"${TMP_TXT}\", \$res[\"dns_txt\"]); + echo \"OK\\n\"; + '" + + # Root-Helper legt Key-Datei unter /etc/opendkim/… ab, schreibt Key-/SigningTable und restarts + sudo /usr/local/sbin/mailwolt-install-dkim "${SYSMAIL_DOMAIN}" "${DKIM_SELECTOR}" "${TMP_PRIV}" "${TMP_TXT}" || true + rm -f "${TMP_PRIV}" "${TMP_TXT}" || true +else + log "DKIM übersprungen (DKIM_ENABLE=${DKIM_ENABLE}, SYSMAIL_DOMAIN='${SYSMAIL_DOMAIN}')." +fi + + # --- TLSA aus App heraus (idempotent; läuft, wenn Zert lesbar ist) ---------- sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan dns:tlsa:refresh || true" diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh index 8494d3c..881e497 100644 --- a/scripts/bootstrap.sh +++ b/scripts/bootstrap.sh @@ -59,6 +59,11 @@ read -r -p "Webmail FQDN (z.B. webmail.domain.tld) [Enter=${WEBMAIL_SUB}. MTA_FQDN="${MTA_FQDN:-${MTA_SUB}.${BASE_DOMAIN}}" UI_FQDN="${UI_FQDN:-${UI_SUB}.${BASE_DOMAIN}}" WEBMAIL_FQDN="${WEBMAIL_FQDN:-${WEBMAIL_SUB}.${BASE_DOMAIN}}" +SYSMAIL_SUB="${SYSMAIL_SUB:-sysmail}" +SYSMAIL_DOMAIN="${SYSMAIL_SUB}.${BASE_DOMAIN}" +DKIM_ENABLE="${DKIM_ENABLE:-1}" +DKIM_SELECTOR="${DKIM_SELECTOR:-mwl1}" +DKIM_GENERATE="${DKIM_GENERATE:-1}" # BASE_DOMAIN und Sub-Labels aus MTA/UI/WEBMAIL ableiten (robust) if [[ "$MTA_FQDN" =~ ^([^.]+)\.(.+)$ ]]; then @@ -85,6 +90,7 @@ APP_LOCALE="${APP_LOCALE:-$DEFAULT_LOCALE}" # ── Variablen exportieren ─────────────────────────────────────────────────── export APP_NAME APP_USER APP_GROUP APP_USER_PREFIX APP_DIR export BASE_DOMAIN UI_SUB WEBMAIL_SUB MTA_SUB +export SYSMAIL_SUB SYSMAIL_DOMAIN DKIM_ENABLE DKIM_SELECTOR DKIM_GENERATE export UI_HOST WEBMAIL_HOST MAIL_HOSTNAME export DB_NAME DB_USER DB_PASS export SERVER_PUBLIC_IPV4 SERVER_PUBLIC_IPV6 APP_TZ APP_LOCALE diff --git a/scripts/lib.sh b/scripts/lib.sh index fc16c62..0ea34ed 100644 --- a/scripts/lib.sh +++ b/scripts/lib.sh @@ -55,15 +55,25 @@ load_env_file(){ } header(){ echo -e "${CYAN}${BAR}${NC} -${CYAN} 888b d888 d8b 888 888 888 888 888 -${CYAN} 8888b d8888 Y8P 888 888 o 888 888 888 -${CYAN} 88888b.d88888 888 888 d8b 888 888 888 -${CYAN} 888Y88888P888 8888b. 888 888 888 d888b 888 .d88b. 888 888888 -${CYAN} 888 Y888P 888 '88b 888 888 888d88888b888 d88''88b 888 888 -${CYAN} 888 Y8P 888 .d888888 888 888 88888P Y88888 888 888 888 888 -${CYAN} 888 ' 888 888 888 888 888 8888P Y8888 Y88..88P 888 Y88b. -${CYAN} 888 888 'Y888888 888 888 888P Y888 'Y88P' 888 'Y888 -${CYAN}${BAR}${NC}\n"; } +${CYAN} :::: :::: ::: ::::::::::: ::: ::: ::: :::::::: ::: ::::::::::: +${CYAN} +:+:+: :+:+:+ :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: +${CYAN} +:+ +:+:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +${CYAN} +#+ +:+ +#+ +#++:++#++: +#+ +#+ +#+ +:+ +#+ +#+ +:+ +#+ +#+ +${CYAN} +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+#+ +#+ +#+ +#+ +#+ +#+ +${CYAN} #+# #+# #+# #+# #+# #+# #+#+# #+#+# #+# #+# #+# #+# +${CYAN} ### ### ### ### ########### ########## ### ### ######## ########## ### +${CYAN} ${CYAN}${BAR}${NC}\n"; } + +#header(){ echo -e "${CYAN}${BAR}${NC} +#${CYAN} 888b d888 d8b 888 888 888 888 888 +#${CYAN} 8888b d8888 Y8P 888 888 o 888 888 888 +#${CYAN} 88888b.d88888 888 888 d8b 888 888 888 +#${CYAN} 888Y88888P888 8888b. 888 888 888 d888b 888 .d88b. 888 888888 +#${CYAN} 888 Y888P 888 '88b 888 888 888d88888b888 d88''88b 888 888 +#${CYAN} 888 Y8P 888 .d888888 888 888 88888P Y88888 888 888 888 888 +#${CYAN} 888 ' 888 888 888 888 888 8888P Y8888 Y88..88P 888 Y88b. +#${CYAN} 888 888 'Y888888 888 888 888P Y888 'Y88P' 888 'Y888 +#${CYAN}${BAR}${NC}\n"; } detect_ip(){ local ip