rspamd
This commit is contained in:
@@ -26,7 +26,13 @@ services:
|
|||||||
- ./docker-data/dms/mail-state/:/var/mail-state/
|
- ./docker-data/dms/mail-state/:/var/mail-state/
|
||||||
- ./docker-data/dms/mail-logs/:/var/log/mail/
|
- ./docker-data/dms/mail-logs/:/var/log/mail/
|
||||||
- ./docker-data/dms/config/:/tmp/docker-mailserver/
|
- ./docker-data/dms/config/:/tmp/docker-mailserver/
|
||||||
- ./docker-data/dms/config/dovecot/conf.d/95-sieve-redirect.conf:/etc/dovecot/conf.d/95-sieve-redirect.conf:ro
|
# ENTFERNT: Mount von dovecot/conf.d/95-sieve-redirect.conf
|
||||||
|
# Der Host-Pfad existiert nicht, Docker hat daraufhin ein VERZEICHNIS
|
||||||
|
# unter /etc/dovecot/conf.d/95-sieve-redirect.conf angelegt (nachweisbar
|
||||||
|
# per `docker exec mailserver cat ...` -> "Is a directory"). Der Mount war
|
||||||
|
# also wirkungslos. Falls dort spaeter wirklich etwas gebraucht wird
|
||||||
|
# (z.B. sieve_redirect_envelope_from), erst die Datei auf dem Host
|
||||||
|
# anlegen, dann den Mount wieder aufnehmen.
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
- ./sync_dynamodb_to_sieve.py:/scripts/sync.py:ro
|
- ./sync_dynamodb_to_sieve.py:/scripts/sync.py:ro
|
||||||
- ./sieve-cron:/etc/cron.d/sieve-sync:ro
|
- ./sieve-cron:/etc/cron.d/sieve-sync:ro
|
||||||
@@ -65,7 +71,12 @@ services:
|
|||||||
- SSL_KEY_PATH=/etc/mail/certs/${NODE_HOSTNAME}/${NODE_HOSTNAME}.key
|
- SSL_KEY_PATH=/etc/mail/certs/${NODE_HOSTNAME}/${NODE_HOSTNAME}.key
|
||||||
|
|
||||||
# SPAM / Rspamd
|
# SPAM / Rspamd
|
||||||
- ENABLE_OPENDKIM=1
|
# OpenDKIM deaktiviert: es liegen keine Keys unter config/opendkim/, der
|
||||||
|
# Milter hat also nie etwas signiert. Ausgehende Mail wird von Amazon SES
|
||||||
|
# signiert (Easy DKIM), eingehende DKIM-Pruefung macht rspamd selbst.
|
||||||
|
# DMS warnt beim Start ausdruecklich davor, OpenDKIM parallel zu rspamd
|
||||||
|
# zu betreiben.
|
||||||
|
- ENABLE_OPENDKIM=0
|
||||||
- ENABLE_OPENDMARC=0
|
- ENABLE_OPENDMARC=0
|
||||||
- ENABLE_POLICYD_SPF=0
|
- ENABLE_POLICYD_SPF=0
|
||||||
- ENABLE_RSPAMD=1
|
- ENABLE_RSPAMD=1
|
||||||
|
|||||||
80
DMS/docker-data/dms/config/rspamd/append.d/settings.conf
Normal file
80
DMS/docker-data/dms/config/rspamd/append.d/settings.conf
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# DMS-CUSTOM-APPEND
|
||||||
|
# ===========================================================================
|
||||||
|
# WICHTIG: Diese Datei wird von user-patches.sh an /etc/rspamd/local.d/settings.conf
|
||||||
|
# ANGEHAENGT und nicht darueber kopiert. DMS legt in dieser Datei selbst eine
|
||||||
|
# Regel fuer authentifizierte User ab (DMS::SED_TAG::1), die erhalten bleiben muss.
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# Hintergrund
|
||||||
|
# -----------
|
||||||
|
# Externe Mail erreicht DMS nie direkt: SES -> S3/SQS -> email-worker -> SMTP.
|
||||||
|
# Rspamd sieht als Client-IP daher immer den Worker-Container (172.x) statt des
|
||||||
|
# echten Absender-Servers. Alle verbindungsbezogenen Pruefungen messen damit
|
||||||
|
# unsere eigene Infrastruktur und liefern systematisch Strafpunkte:
|
||||||
|
#
|
||||||
|
# HFILTER_HOSTNAME_UNKNOWN 6.0 (kein PTR fuer 172.x -> exakt die add_header-Schwelle)
|
||||||
|
# R_SPF_FAIL / R_SPF_SOFTFAIL 4.5 / 2.5
|
||||||
|
# R_DKIM_NA / R_DKIM_PERMFAIL 1.0 / 4.5
|
||||||
|
#
|
||||||
|
# Diese Gruppen werden fuer Einlieferungen aus dem Docker-Netz deaktiviert.
|
||||||
|
# Inhaltsbezogene Pruefungen (Bayes, Fuzzy, URL-/Surbl-Blocklisten, MIME,
|
||||||
|
# Attachment-Checks) bleiben vollstaendig aktiv - echter Spam wird also weiter
|
||||||
|
# erkannt, nur eben anhand des Inhalts statt anhand einer Transportstrecke,
|
||||||
|
# die rspamd hier gar nicht beurteilen kann.
|
||||||
|
#
|
||||||
|
# SPF/DKIM/DMARC gehen dadurch nicht verloren: SES prueft sie bereits mit der
|
||||||
|
# echten Absender-IP. Das Ergebnis liegt im SQS-Payload (receipt.spamVerdict,
|
||||||
|
# spfVerdict, dkimVerdict, dmarcVerdict). Sobald der Worker diese Verdicts als
|
||||||
|
# Header stempelt, koennen sie hier per multimap wieder bepunktet werden.
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 1) Einlieferungen des email-workers (externe Mail + dessen Forwards/OOO)
|
||||||
|
#
|
||||||
|
# Der Worker setzt X-SES-Worker-Processed auf JEDER Mail, die er einliefert:
|
||||||
|
# delivered = Originalmail an das lokale Postfach
|
||||||
|
# forwarded = neu komponierte Weiterleitung (rules-processor.ts)
|
||||||
|
# ooo-reply = Abwesenheitsantwort
|
||||||
|
#
|
||||||
|
# Die IP-Bedingung ist die Absicherung: ohne sie koennte ein externer Absender
|
||||||
|
# den Header selbst setzen und die Auth-Pruefungen abschalten. Beide
|
||||||
|
# Bedingungen werden von rspamd implizit mit UND verknuepft.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
ses_worker_injected {
|
||||||
|
priority = 10;
|
||||||
|
ip = ["172.16.0.0/12", "127.0.0.0/8"];
|
||||||
|
header = {
|
||||||
|
"X-SES-Worker-Processed" = true;
|
||||||
|
}
|
||||||
|
apply {
|
||||||
|
groups_disabled = ["spf", "dkim", "dmarc", "hfilter"];
|
||||||
|
symbols_disabled = ["RDNS_NONE"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 2) Lokale Re-Injection ohne Worker-Header
|
||||||
|
#
|
||||||
|
# Betrifft:
|
||||||
|
# - Sieve-Redirects fuer INTERNE Mail (accounting@ -> support@ -> Forwards).
|
||||||
|
# Diese Mail laeuft nie ueber SES/Worker, hat also keinen Worker-Header.
|
||||||
|
# - Roundcube, das ohne SASL-Auth aus dem Docker-Netz einliefert
|
||||||
|
# (ROUNDCUBEMAIL_SMTP_USER ist bewusst leer).
|
||||||
|
#
|
||||||
|
# Beides wurde bisher von der DOCKER_WL-Whitelist (-50) aufgefangen. Diese
|
||||||
|
# Regel ersetzt sie - deutlich enger gefasst, weil sie an das Docker-Netz
|
||||||
|
# gebunden ist statt an eine faelschbare Absenderdomain.
|
||||||
|
#
|
||||||
|
# Niedrigere Prioritaet als Regel 1: rspamd wertet Regeln nach Prioritaet aus
|
||||||
|
# und nimmt den ersten Treffer, Worker-Mail landet also nie hier.
|
||||||
|
#
|
||||||
|
# ACHTUNG: Diese Regel setzt voraus, dass Port 25 NICHT oeffentlich erreichbar
|
||||||
|
# ist (docker-compose.yml bindet ihn auf 127.0.0.1). Wird das je geaendert,
|
||||||
|
# muss diese Regel weg - sonst umgeht jeder externe Absender die Pruefung.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
local_reinjection {
|
||||||
|
priority = 5;
|
||||||
|
ip = ["172.16.0.0/12", "127.0.0.0/8"];
|
||||||
|
apply {
|
||||||
|
groups_enabled = ["dkim"];
|
||||||
|
}
|
||||||
|
}
|
||||||
19
DMS/docker-data/dms/config/rspamd/local.d/logging.inc
Normal file
19
DMS/docker-data/dms/config/rspamd/local.d/logging.inc
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# documentation: https://rspamd.com/doc/configuration/logging.html
|
||||||
|
#
|
||||||
|
# Uebersteuert den DMS-Default (level = "silent"), bei dem rspamd ueberhaupt
|
||||||
|
# nichts protokolliert und Spam-Scores nicht nachvollziehbar sind.
|
||||||
|
#
|
||||||
|
# type = "console" bleibt bewusst stehen: Supervisor leitet stdout/stderr von
|
||||||
|
# rspamd bereits nach /var/log/mail/rspamd.log um (siehe dms-services.conf).
|
||||||
|
# Ein eigenes type = "file" mit demselben Pfad haette zwei Schreiber auf
|
||||||
|
# derselben Datei zur Folge.
|
||||||
|
#
|
||||||
|
# Mit level = "info" schreibt rspamd pro Mail eine Zeile mit Aktion, Score und
|
||||||
|
# allen ausgeloesten Symbolen samt Einzelgewicht:
|
||||||
|
#
|
||||||
|
# docker exec mailserver sh -c 'grep rspamd_task_write_log /var/log/mail/rspamd.log | tail -20'
|
||||||
|
|
||||||
|
type = "console";
|
||||||
|
level = "info";
|
||||||
|
color = false;
|
||||||
|
systemd = false;
|
||||||
@@ -1,8 +1,18 @@
|
|||||||
DOCKER_WL {
|
# documentation: https://rspamd.com/doc/modules/multimap.html
|
||||||
type = "from";
|
#
|
||||||
filter = "email:domain";
|
# Die fruehere Regel DOCKER_WL (-50 Punkte fuer jede Mail, deren Envelope-From
|
||||||
map = "/etc/rspamd/override.d/docker_whitelist.map";
|
# auf eine unserer eigenen Domains zeigt) ist bewusst entfernt worden:
|
||||||
symbol = "DOCKER_WHITELIST";
|
#
|
||||||
description = "Whitelist fuer eigene Domains";
|
# 1. Sie war ein Spoofing-Loch. Mit SPOOF_PROTECTION=0 genuegte einem
|
||||||
score = -50.0;
|
# beliebigen externen Absender ein "MAIL FROM: <x@bayarea-cc.com>", um
|
||||||
}
|
# -50 Punkte plus das erzwungene "no action" aus force_actions.conf zu
|
||||||
|
# bekommen - also garantierte Zustellung in die Inbox.
|
||||||
|
# 2. Sie hat echten Spam an weitergeleitete Adressen durchgereicht, weil der
|
||||||
|
# email-worker seine Weiterleitungen mit Envelope-From = Empfaengeradresse
|
||||||
|
# (also eigene Domain) einliefert.
|
||||||
|
# 3. Sie hat nur ein Symptom kompensiert: die falschen Auth-/Hostname-Scores,
|
||||||
|
# die entstehen, weil alle Mail aus dem Worker-Container kommt. Das wird
|
||||||
|
# jetzt an der Ursache geloest - siehe rspamd/append.d/settings.conf.
|
||||||
|
#
|
||||||
|
# Die Datei bleibt (leer) bestehen, damit user-patches.sh sie beim Start ueber
|
||||||
|
# eine evtl. noch im Container liegende alte Version kopiert.
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
rules {
|
# documentation: https://rspamd.com/doc/modules/force_actions.html
|
||||||
DOCKER_WHITELIST_FORCE {
|
#
|
||||||
action = "no action";
|
# Die Regel DOCKER_WHITELIST_FORCE ("no action" sobald DOCKER_WHITELIST greift)
|
||||||
expression = "DOCKER_WHITELIST";
|
# ist entfernt. Sie hat die Spam-Entscheidung fuer jede Mail mit eigener
|
||||||
}
|
# Absenderdomain hart ueberschrieben - inklusive echtem Spam an weitergeleitete
|
||||||
}
|
# Adressen. Das dazugehoerige Symbol existiert nicht mehr, siehe
|
||||||
|
# rspamd/local.d/multimap.conf.
|
||||||
|
#
|
||||||
|
# Keine rules{}-Sektion = force_actions ist wirkungslos. Datei bleibt bestehen,
|
||||||
|
# damit DMS sie beim Start ueber eine alte Version im Container kopiert.
|
||||||
|
|||||||
@@ -1,47 +1,61 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# user-patches.sh laeuft bei jedem Start von DMS automatisch
|
# user-patches.sh laeuft bei jedem Start von DMS automatisch,
|
||||||
|
# nach dem Setup und bevor die Daemons gestartet werden.
|
||||||
|
|
||||||
ACCOUNTS_FILE="/tmp/docker-mailserver/postfix-accounts.cf"
|
SRC_BASE="/tmp/docker-mailserver/rspamd"
|
||||||
WHITELIST_FILE="/etc/rspamd/override.d/docker_whitelist.map"
|
LOCAL_D="/etc/rspamd/local.d"
|
||||||
|
|
||||||
# --- Rspamd Whitelist generieren ---
|
# ---------------------------------------------------------------------------
|
||||||
STATIC_DOMAINS=(
|
# 1) local.d configs kopieren
|
||||||
"bayarea-cc.com"
|
# DMS kopiert nur rspamd/override.d automatisch, local.d nicht.
|
||||||
"ruehrgedoens.de"
|
# ---------------------------------------------------------------------------
|
||||||
"annavillesda.org"
|
|
||||||
"bizmatch.net"
|
|
||||||
"biz-match.com"
|
|
||||||
"qrmaster.net"
|
|
||||||
"nqsltd.com"
|
|
||||||
"iitwelders.com"
|
|
||||||
)
|
|
||||||
|
|
||||||
echo "Patching: Generiere Rspamd Whitelist aus Accounts + statischen Domains..."
|
|
||||||
|
|
||||||
{
|
|
||||||
for domain in "${STATIC_DOMAINS[@]}"; do
|
|
||||||
echo "$domain"
|
|
||||||
done
|
|
||||||
if [ -f "$ACCOUNTS_FILE" ]; then
|
|
||||||
awk -F'|' '{print $1}' "$ACCOUNTS_FILE" | cut -d'@' -f2
|
|
||||||
fi
|
|
||||||
} | sort | uniq > "$WHITELIST_FILE"
|
|
||||||
|
|
||||||
chmod 644 "$WHITELIST_FILE"
|
|
||||||
chown _rspamd:_rspamd "$WHITELIST_FILE" 2>/dev/null || true
|
|
||||||
echo "Whitelist erstellt:"
|
|
||||||
cat "$WHITELIST_FILE"
|
|
||||||
|
|
||||||
# --- local.d configs manuell kopieren (DMS kopiert local.d nicht automatisch) ---
|
|
||||||
echo "Patching: Kopiere custom rspamd local.d configs..."
|
echo "Patching: Kopiere custom rspamd local.d configs..."
|
||||||
SRC="/tmp/docker-mailserver/rspamd/local.d"
|
if [ -d "${SRC_BASE}/local.d" ]; then
|
||||||
DST="/etc/rspamd/local.d"
|
for f in "${SRC_BASE}/local.d"/*; do
|
||||||
if [ -d "$SRC" ]; then
|
|
||||||
for f in "$SRC"/*; do
|
|
||||||
[ -f "$f" ] || continue
|
[ -f "$f" ] || continue
|
||||||
cp "$f" "$DST/$(basename "$f")"
|
base=$(basename "$f")
|
||||||
chown root:root "$DST/$(basename "$f")"
|
cp "$f" "${LOCAL_D}/${base}"
|
||||||
chmod 644 "$DST/$(basename "$f")"
|
chown root:root "${LOCAL_D}/${base}"
|
||||||
echo " Kopiert: $(basename "$f") -> $DST/"
|
chmod 644 "${LOCAL_D}/${base}"
|
||||||
|
echo " Kopiert: ${base} -> ${LOCAL_D}/"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 2) append.d: an bestehende local.d-Dateien ANHAENGEN statt sie zu ersetzen
|
||||||
|
#
|
||||||
|
# Zwingend fuer settings.conf: DMS legt dort selbst die Regel fuer
|
||||||
|
# authentifizierte User ab (DMS::SED_TAG::1). Ein cp darueber wuerde sie
|
||||||
|
# loeschen und RSPAMD_CHECK_AUTHENTICATED=0 wirkungslos machen.
|
||||||
|
#
|
||||||
|
# Der Marker DMS-CUSTOM-APPEND macht das Anhaengen idempotent - /etc/rspamd
|
||||||
|
# liegt im Container-Dateisystem und ueberlebt einen `docker restart`.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
echo "Patching: Haenge custom rspamd Snippets an local.d configs an..."
|
||||||
|
if [ -d "${SRC_BASE}/append.d" ]; then
|
||||||
|
for f in "${SRC_BASE}/append.d"/*; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
base=$(basename "$f")
|
||||||
|
target="${LOCAL_D}/${base}"
|
||||||
|
|
||||||
|
if grep -q 'DMS-CUSTOM-APPEND' "$target" 2>/dev/null; then
|
||||||
|
echo " Bereits vorhanden, uebersprungen: ${base}"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '\n' >>"$target"
|
||||||
|
cat "$f" >>"$target"
|
||||||
|
chown root:root "$target"
|
||||||
|
chmod 644 "$target"
|
||||||
|
echo " Angehaengt: ${base} -> ${target}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# HINWEIS: Die frueher hier erzeugte Rspamd-Whitelist
|
||||||
|
# (/etc/rspamd/override.d/docker_whitelist.map aus postfix-accounts.cf +
|
||||||
|
# statischer Domainliste) ist entfernt. Die zugehoerige multimap-Regel
|
||||||
|
# DOCKER_WL (-50) und das erzwungene "no action" aus force_actions.conf gibt
|
||||||
|
# es nicht mehr - sie waren ein Spoofing-Loch und haben echten Spam an
|
||||||
|
# weitergeleitete Adressen durchgereicht. Ersatz: rspamd/append.d/settings.conf.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user