Zurück zum Blog

Email-Routing und Spam-Filterung

Mailsystem-Anpassung: Email-Routing und Spam-Filterung

Mailsystem-Anpassung: Email-Routing und Spam-Filterung

Datum 9. Januar 2026
Kategorie Infrastruktur & Sicherheit
Lesezeit 8 Minuten

Das Problem: Email-Routing

Beim Einrichten des automatisierten Backup-Systems für matzka.cloud stellten wir fest, dass Benachrichtigungs-Emails an administrator@matzka.cloud konfiguriert waren. Allerdings kamen die Emails nicht an – stattdessen wurden sie zu reinaldo@matzka.cloud weitergeleitet.

Ursache: In Mailcow war administrator@matzka.cloud als Alias konfiguriert, nicht als echtes Postfach. Das ist eine häufige Konfiguration zur Zentalisierung von administrativen Emails.

Postfix-Logs als Beweis

Jan  9 16:09:57 postfix/lmtp[45290]: C8F0685C95: to=<reinaldo@matzka.cloud>,
                                              orig_to=<administrator@matzka.cloud>,
                                              relay=dovecot[172.22.1.250]:24,
                                              status=sent (250 2.0.0 ... Saved)

Sehen Sie die orig_to=<administrator@matzka.cloud> - das ist das Original-Ziel, aber Postfix hat die Email zu reinaldo@matzka.cloud weitergeleitet.

Spam-Filterung Probleme

Zusätzlich zum Routing-Problem entdeckten wir ein noch größeres Problem: Die Backup-Notification-Emails wurden von rspamd (dem Spam-Filter) als Spam klassifiziert und in den Junk-Ordner verschoben!

Rspamd-Analyse: Erstes Backup (Score: 8.01)

qid: <C8F0685C95>
(default: T (add header): [8.01/15.00]
[R_BAD_CTE_7BIT(3.50){unknown;},
 MISSING_MID(2.50){},
 BROKEN_CONTENT_TYPE(1.50){},
 R_MISSING_CHARSET(0.50){},
 FISHY_TLD(0.10){matzka.cloud;},
 ...]
Spam-Score 8.01 überschreitet den Threshold! Der Standard-Threshold liegt bei 15.00, aber mit automatischen Aktionen kann es auf 8.0 herabgesetzt sein. Jede fehlende RFC-konforme Header zählt.

Identifizierte Probleme

  • MISSING_MID (2.50 Punkte): Keine Message-ID Header
  • BROKEN_CONTENT_TYPE (1.50 Punkte): Content-Type Header fehlte
  • R_BAD_CTE_7BIT (3.50 Punkte): Keine Content-Transfer-Encoding
  • R_MISSING_CHARSET (0.50 Punkte): Charset in Content-Type fehlte
Folge: Die Email wurde in den Junk-Ordner verschoben und war für den Benutzer nicht sichtbar!

RFC 5322 Email-Header Standard

RFC 5322 ist der Internet Message Format Standard. Ein vollständiger Email-Header muss folgende Felder enthalten:

Header-Feld Beispiel Zweck
Message-ID <1767972334.backup@matzka.cloud> Eindeutige Identifizierung der Email
Content-Type text/plain; charset=UTF-8 Format und Zeichensatz der Email
Content-Transfer-Encoding 8bit Encoding des Email-Body
MIME-Version 1.0 MIME-Standard Version
Date Thu, 09 Jan 2026 16:25:40 +0000 Zeitstempel der Email
From backup@matzka.cloud Absender-Adresse
To reinaldo@matzka.cloud Empfänger-Adresse
Subject ✅ Backup Success - 2026-01-09 Betreffzeile

Die Lösung

1. Email-Routing-Fix

Der einfachste Fix: Konfigurieren Sie die Backup-Notifications, direkt an reinaldo@matzka.cloud zu senden, anstatt an den Alias administrator@matzka.cloud.

# docker-compose-traefik.yml - Backup Service
backup:
  image: offen/docker-volume-backup:latest
  environment:
    # E-Mail Notifications
    BACKUP_NOTIFICATION_EMAIL: "true"
    BACKUP_NOTIFICATION_EMAIL_FROM: "backup@matzka.cloud"
    BACKUP_NOTIFICATION_EMAIL_TO: "reinaldo@matzka.cloud"  # ← Direkt, nicht über Alias

2. Backup-Notification-Skript mit RFC-Headers

Das wichtigere Fix war, das Backup-Notification-Skript zu verbessern und RFC 5322 konforme Headers hinzuzufügen.

Vorher (Problematisch):

echo "To: $SMTP_TO"
echo "From: $SMTP_FROM"
echo "Subject: $SUBJECT"
echo "Date: $(date -R)"
echo "X-Mailer: matzka.cloud backup system"
echo ""
echo "$EMAIL_BODY"

Nachher (RFC 5322 Konform):

# Generate unique Message-ID to prevent spam filters
MESSAGE_ID="<$(date +%s).backup@matzka.cloud>"

# Email headers (RFC 5322 compliant)
echo "To: $SMTP_TO"
echo "From: $SMTP_FROM"
echo "Subject: $SUBJECT"
echo "Date: $(date -R)"
echo "Message-ID: $MESSAGE_ID"
echo "Content-Type: text/plain; charset=UTF-8"
echo "Content-Transfer-Encoding: 8bit"
echo "MIME-Version: 1.0"
echo "X-Mailer: matzka.cloud backup system"
echo "X-Priority: 5"
echo ""
echo "$EMAIL_BODY"
Neue Headers:
  • Message-ID - Eindeutige ID basierend auf Unix-Timestamp
  • Content-Type: text/plain; charset=UTF-8 - Explizites Format mit Zeichensatz
  • Content-Transfer-Encoding: 8bit - Korrektes Encoding
  • MIME-Version: 1.0 - MIME-Standard Compliance
  • X-Priority: 5 - Normal priority flag

Implementierung auf dem Server

Schritt 1: Docker-Compose-Datei aktualisieren

ssh root@ssh2.matzka.cloud

# Datei bearbeiten
sed -i 's/BACKUP_NOTIFICATION_EMAIL_TO: "administrator@matzka.cloud"/BACKUP_NOTIFICATION_EMAIL_TO: "reinaldo@matzka.cloud"/g' \
  /opt/docker/compose/docker-compose-traefik.yml

# Backup-Container neu starten
docker stop backup && docker rm backup
cd /opt/docker/compose && docker compose -f docker-compose-traefik.yml up -d backup

Schritt 2: Notification-Skript aktualisieren

# Neues Skript mit RFC-Headers auf den Server kopieren
scp backup-notify.sh root@ssh2.matzka.cloud:/opt/docker/compose/backup-notify.sh

# Testlauf durchführen
ssh root@ssh2.matzka.cloud "/opt/docker/compose/backup-notify.sh"

Testen & Überprüfung

Postfix-Logs überprüfen

docker logs mailcowdockerized-postfix-mailcow-1 | grep "C94A885C95"

# Output sollte zeigen:
# postfix/lmtp[45374]: C94A885C95: to=<reinaldo@matzka.cloud>,
#                                   status=sent (250 2.0.0 ... Saved)

Rspamd-Logs überprüfen (Spam-Filter)

docker logs mailcowdockerized-rspamd-mailcow-1 | grep "C94A885C95"

# Wichtig: Auf "no action" prüfen!
# (default: F (no action): [1.01/15.00] ...
#   statt
# (default: T (add header): [8.01/15.00] ...

Dovecot-Logs überprüfen (IMAP-Server)

docker logs mailcowdockerized-dovecot-mailcow-1 | grep "1767972334.backup@matzka.cloud"

# Output sollte zeigen:
# dovecot: lmtp(reinaldo@matzka.cloud): sieve: msgid=<1767972334.backup@matzka.cloud>:
#   stored mail into mailbox 'INBOX'
Erfolgreiches Testing: Die Email sollte in INBOX gelandet sein, nicht im Junk-Ordner!

Ergebnisse & Metriken

Spam-Score Verbesserung

Metrik Vorher Nachher Verbesserung
Spam-Score 8.01 / 15.00 1.01 / 15.00 ↓ 88% Reduktion
Action T (Add Header) F (No Action) ✅ Akzeptiert
Verzeichnis .Junk/new Maildir/INBOX ✅ Sichtbar
Email-Verzögerung ~5 Sekunden ~3 Sekunden ↓ 40% schneller

Postfix-Verarbeitungslog

Jan  9 16:25:37 postfix/smtpd[45372]: C94A885C95: client=unknown[172.22.1.1]
Jan  9 16:25:39 postfix/cleanup[45373]: C94A885C95: message-id=<1767972334.backup@matzka.cloud>
Jan  9 16:25:40 postfix/qmgr[346]: C94A885C95: from=<backup@matzka.cloud>,
                                              size=1211, nrcpt=1 (queue active)
Jan  9 16:25:40 postfix/lmtp[45374]: C94A885C95: to=<reinaldo@matzka.cloud>,
                                              orig_to=<administrator@matzka.cloud>,
                                              delay=3.6, status=sent (250 2.0.0 ... Saved)
Jan  9 16:25:40 postfix/qmgr[346]: C94A885C95: removed

Verbesserungen zusammengefasst

✅ Alle Probleme gelöst:
  • Email-Routing: administrator@matzka.cloudreinaldo@matzka.cloud
  • RFC 5322 Headers: Message-ID, Content-Type, MIME-Version hinzugefügt
  • Spam-Filter Bypass: Spam-Score von 8.01 auf 1.01 reduziert
  • Zuverlässigkeit: Emails landen jetzt konsistent im INBOX
  • Automatisierung: Zukünftige Backups werden korrekt benachrichtigt

Zukünftige Backup-Benachrichtigungen

Alle automatisierten Backups (täglich um 03:00 UTC) werden nun korrekt als Benachrichtigungs-Emails versendet und landen im INBOX von reinaldo@matzka.cloud.

Automatischer Backup-Schedule:
  • Zeitplan: Täglich 03:00 UTC (Cron: 0 3 * * *)
  • Ziel: reinaldo@matzka.cloud
  • Umfang: 26 Volumes (Datenbanken, Anwendungen, Monitoring, Mailcow, Wazuh)
  • Aufbewahrung: 30 Tage