320 lines
11 KiB
Bash
320 lines
11 KiB
Bash
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
source ./lib.sh
|
||
|
||
log "Rspamd + OpenDKIM einrichten …"
|
||
|
||
# ──────────────────────────────────────────────────────────────
|
||
# 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}}" # z.B. sysmail.example.com
|
||
DKIM_ENABLE="${DKIM_ENABLE:-1}" # 1=OpenDKIM aktiv
|
||
DKIM_SELECTOR="${DKIM_SELECTOR:-mwl1}" # z.B. mwl1
|
||
DKIM_GENERATE="${DKIM_GENERATE:-0}" # 1=Key generieren, falls fehlt
|
||
RSPAMD_CONTROLLER_PASSWORD="${RSPAMD_CONTROLLER_PASSWORD:-admin}"
|
||
|
||
# ──────────────────────────────────────────────────────────────
|
||
# Rspamd (Controller + Milter)
|
||
# ──────────────────────────────────────────────────────────────
|
||
install -d -m 0750 /etc/rspamd/local.d
|
||
|
||
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 <<CONF
|
||
worker "controller" {
|
||
bind_socket = "127.0.0.1:11334";
|
||
password = "${RSPAMD_HASH}";
|
||
}
|
||
CONF
|
||
|
||
cat >/etc/rspamd/local.d/statistic.conf <<CONF
|
||
classifier "bayes" {
|
||
backend = "redis";
|
||
autolearn = true;
|
||
autolearn_threshold = 6.0;
|
||
ham_symbols = ["BAYES_HAM"];
|
||
spam_symbols = ["BAYES_SPAM"];
|
||
min_learns = 10;
|
||
store_tokens = true;
|
||
per_user = false;
|
||
}
|
||
CONF
|
||
|
||
cat >/etc/rspamd/local.d/worker-proxy.inc <<'CONF'
|
||
worker "proxy" {
|
||
bind_socket = "127.0.0.1:11332";
|
||
milter = yes;
|
||
timeout = 120s;
|
||
|
||
upstream "scan" {
|
||
default = yes;
|
||
self_scan = yes;
|
||
servers = "127.0.0.1:11333";
|
||
}
|
||
}
|
||
CONF
|
||
|
||
cat >/etc/rspamd/local.d/worker-normal.inc <<'CONF'
|
||
worker "normal" {
|
||
bind_socket = "127.0.0.1:11333";
|
||
}
|
||
CONF
|
||
|
||
cat >/etc/rspamd/local.d/milter_headers.conf <<'CONF'
|
||
use = ["authentication-results"];
|
||
header = "Authentication-Results";
|
||
CONF
|
||
|
||
cat >/etc/rspamd/local.d/options.inc <<'CONF'
|
||
dns {
|
||
servers = ["9.9.9.9:53", "1.1.1.1:53"];
|
||
timeout = 5s;
|
||
retransmits = 2;
|
||
}
|
||
CONF
|
||
|
||
# ──────────────────────────────────────────────────────────────
|
||
# Rspamd Redis-Konfiguration
|
||
# ──────────────────────────────────────────────────────────────
|
||
log "Rspamd Redis konfigurieren …"
|
||
|
||
: "${REDIS_PASS:=}"
|
||
|
||
cat >/etc/rspamd/local.d/redis.conf <<CONF
|
||
servers = "127.0.0.1:6379";
|
||
${REDIS_PASS:+password = "${REDIS_PASS}";}
|
||
db = 0;
|
||
CONF
|
||
|
||
# Eigentümer und Rechte setzen
|
||
chown root:_rspamd /etc/rspamd/local.d /etc/rspamd/local.d/redis.conf
|
||
chmod 750 /etc/rspamd/local.d
|
||
chmod 640 /etc/rspamd/local.d/redis.conf
|
||
|
||
# Testweise prüfen, ob Redis erreichbar ist (nicht kritisch)
|
||
if command -v redis-cli >/dev/null 2>&1; then
|
||
if [[ -n "${REDIS_PASS}" ]]; then
|
||
if redis-cli -h 127.0.0.1 -p 6379 -a "${REDIS_PASS}" ping >/dev/null 2>&1; then
|
||
log "[✓] Redis erreichbar und Passwort akzeptiert."
|
||
else
|
||
log "[!] Warnung: Redis antwortet nicht oder Passwort falsch."
|
||
fi
|
||
else
|
||
if redis-cli -h 127.0.0.1 -p 6379 ping >/dev/null 2>&1; then
|
||
log "[✓] Redis erreichbar (ohne Passwort)."
|
||
else
|
||
log "[!] Warnung: Redis antwortet nicht."
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
systemctl enable --now rspamd || true
|
||
|
||
# ──────────────────────────────────────────────────────────────
|
||
# OpenDKIM – nur wenn DKIM_ENABLE=1
|
||
# ──────────────────────────────────────────────────────────────
|
||
|
||
if [[ "${DKIM_ENABLE}" != "1" ]]; then
|
||
log "DKIM_ENABLE=0 → OpenDKIM wird übersprungen."
|
||
/usr/sbin/postconf -e "milter_default_action = accept"
|
||
/usr/sbin/postconf -e "milter_protocol = 6"
|
||
/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"
|
||
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
|
||
|
||
# TrustedHosts
|
||
cat >/etc/opendkim/TrustedHosts <<'CONF'
|
||
127.0.0.1
|
||
::1
|
||
localhost
|
||
CONF
|
||
chown opendkim:opendkim /etc/opendkim/TrustedHosts
|
||
chmod 640 /etc/opendkim/TrustedHosts
|
||
|
||
# ── Key-Verzeichnis für SYSMAIL_DOMAIN vorbereiten ───────────────────────────
|
||
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}"
|
||
|
||
# ── Key optional generieren (nur wenn gewünscht) ─────────────────────────────
|
||
if [[ ! -s "${KEY_PRIV}" && "${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_DIR}/${DKIM_SELECTOR}.private" || true
|
||
chmod 600 "${KEY_DIR}/${DKIM_SELECTOR}.private" || true
|
||
else
|
||
echo "[!] opendkim-genkey fehlt – kann DKIM-Key nicht generieren."
|
||
fi
|
||
fi
|
||
|
||
# ── Key-/SigningTable nur anlegen, nicht leeren ───────────────────────────────
|
||
touch /etc/opendkim/KeyTable /etc/opendkim/SigningTable
|
||
chown opendkim:opendkim /etc/opendkim/KeyTable /etc/opendkim/SigningTable
|
||
chmod 640 /etc/opendkim/KeyTable /etc/opendkim/SigningTable
|
||
|
||
if [[ -s "${KEY_PRIV}" && "${BASE_DOMAIN}" != "example.com" ]]; then
|
||
LINE_KT="${DKIM_SELECTOR}._domainkey.${SYSMAIL_DOMAIN} ${SYSMAIL_DOMAIN}:${DKIM_SELECTOR}:${KEY_PRIV}"
|
||
LINE_ST="*@${SYSMAIL_DOMAIN} ${DKIM_SELECTOR}._domainkey.${SYSMAIL_DOMAIN}"
|
||
grep -Fqx "$LINE_KT" /etc/opendkim/KeyTable || echo "$LINE_KT" >> /etc/opendkim/KeyTable
|
||
grep -Fqx "$LINE_ST" /etc/opendkim/SigningTable || echo "$LINE_ST" >> /etc/opendkim/SigningTable
|
||
else
|
||
echo "[i] Kein Private Key unter ${KEY_PRIV} – App-Helper trägt später ein."
|
||
fi
|
||
|
||
# ── Hauptkonfiguration ───────────────────────────────────────────────────────
|
||
cat >/etc/opendkim.conf <<'CONF'
|
||
Syslog yes
|
||
UMask 002
|
||
Mode sv
|
||
Socket inet:8891@127.0.0.1
|
||
PidFile /run/opendkim/opendkim.pid
|
||
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
|
||
SyslogSuccess yes
|
||
CONF
|
||
|
||
# ── systemd Drop-in: /run/opendkim sicherstellen ─────────────────────────────
|
||
install -d -m 0755 /etc/systemd/system/opendkim.service.d
|
||
cat >/etc/systemd/system/opendkim.service.d/override.conf <<'EOF'
|
||
[Service]
|
||
RuntimeDirectory=opendkim
|
||
RuntimeDirectoryMode=0755
|
||
EOF
|
||
|
||
install -d -o opendkim -g opendkim -m 0755 /run/opendkim
|
||
|
||
# ──────────────────────────────────────────────────────────────
|
||
# Root-Helper: DKIM installieren / entfernen + sudoers-Regel
|
||
# ──────────────────────────────────────────────────────────────
|
||
install -d -m 0750 /usr/local/sbin
|
||
|
||
# --- mailwolt-install-dkim ------------------------------------
|
||
cat > /usr/local/sbin/mailwolt-install-dkim <<'EOSH'
|
||
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
DOMAIN="$1"
|
||
SELECTOR="$2"
|
||
SRC_PRIV="$3"
|
||
SRC_TXT="${4:-}"
|
||
|
||
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 "${SRC_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}"
|
||
LINE_ST="*@${DOMAIN} ${SELECTOR}._domainkey.${DOMAIN}"
|
||
|
||
grep -Fqx "$LINE_KT" "$KT" || echo "$LINE_KT" >> "$KT"
|
||
grep -Fqx "$LINE_ST" "$ST" || echo "$LINE_ST" >> "$ST"
|
||
|
||
if [[ -n "${SRC_TXT}" && -s "${SRC_TXT}" ]]; then
|
||
install -d -m 0755 /etc/mailwolt/dns
|
||
cp -f "${SRC_TXT}" "/etc/mailwolt/dns/dkim-${DOMAIN}.txt"
|
||
fi
|
||
|
||
systemctl is-active --quiet opendkim && systemctl reload opendkim || true
|
||
echo "OK"
|
||
EOSH
|
||
chmod 0750 /usr/local/sbin/mailwolt-install-dkim
|
||
chown root:root /usr/local/sbin/mailwolt-install-dkim
|
||
|
||
# --- 2) mailwolt-remove-dkim ----------------------------------
|
||
cat >/usr/local/sbin/mailwolt-remove-dkim <<'EOSH'
|
||
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
DOMAIN="$1" # z.B. kunden.tld oder sysmail.example.com
|
||
SELECTOR="$2" # z.B. mwl1
|
||
|
||
OKDIR="/etc/opendkim"
|
||
KEYDIR="${OKDIR}/keys/${DOMAIN}"
|
||
KEYPRI="${KEYDIR}/${SELECTOR}.private"
|
||
KT="${OKDIR}/KeyTable"
|
||
ST="${OKDIR}/SigningTable"
|
||
|
||
# Key-Datei löschen (falls vorhanden)
|
||
[[ -f "${KEYPRI}" ]] && rm -f "${KEYPRI}"
|
||
|
||
# Zeilen aus KeyTable und SigningTable entfernen
|
||
if [[ -f "$KT" ]]; then
|
||
tmp="$(mktemp)"; grep -v -F "${SELECTOR}._domainkey.${DOMAIN} ${DOMAIN}:${SELECTOR}:" "$KT" >"$tmp" && mv "$tmp" "$KT"
|
||
chown opendkim:opendkim "$KT"; chmod 0640 "$KT"
|
||
fi
|
||
if [[ -f "$ST" ]]; then
|
||
tmp="$(mktemp)"; grep -v -F "*@${DOMAIN} ${SELECTOR}._domainkey.${DOMAIN}" "$ST" >"$tmp" && mv "$tmp" "$ST"
|
||
chown opendkim:opendkim "$ST"; chmod 0640 "$ST"
|
||
fi
|
||
|
||
# Verzeichnis ggf. aufräumen
|
||
rmdir "${KEYDIR}" 2>/dev/null || true
|
||
|
||
# Dienst neu laden, falls aktiv
|
||
if systemctl is-active --quiet opendkim; then
|
||
systemctl reload opendkim || true
|
||
fi
|
||
|
||
echo "OK"
|
||
EOSH
|
||
chown root:root /usr/local/sbin/mailwolt-remove-dkim
|
||
chmod 0750 /usr/local/sbin/mailwolt-remove-dkim
|
||
|
||
# ── Dienst + Postfix-Milter aktivieren ─────────────────────────
|
||
systemctl daemon-reload
|
||
systemctl enable opendkim || true
|
||
|
||
touch /run/mailwolt.need-apply-milters || true
|
||
|
||
chgrp _rspamd /etc/rspamd/local.d/*.inc /etc/rspamd/local.d/*.conf || true
|
||
chmod 0640 /etc/rspamd/local.d/*.inc /etc/rspamd/local.d/*.conf || true
|
||
|
||
#/usr/sbin/postconf -e "smtpd_milters = inet:127.0.0.1:11332, inet:127.0.0.1:8891"
|
||
#/usr/sbin/postconf -e "non_smtpd_milters = inet:127.0.0.1:11332, inet:127.0.0.1:8891"
|
||
|
||
log "[✓] Rspamd + OpenDKIM eingerichtet (läuft; signiert, sobald Keys vorhanden sind)."
|