Debian-Mailserver 2026

Postfix, Dovecot, Rspamd und Nginx unter Debian 13

Mein ursprüngliches Mailserver-How-to stammte aus dem Jahr 2009. Damals bestand der Aufbau aus Postfix, Cyrus IMAP, Amavis, SpamAssassin, Razor, Pyzor und DCC. Viele der dort verwendeten Paketnamen, Konfigurationsparameter und Sicherheitsannahmen sind heute nicht mehr gültig.

Diese Anleitung beschreibt deshalb keine schrittweise Reparatur des alten Systems, sondern einen aktuellen Neuaufbau unter Debian 13 „Trixie“:

  • Postfix übernimmt den SMTP-Verkehr.
  • Dovecot stellt IMAP, die Benutzerauthentifizierung und die lokale Zustellung über LMTP bereit.
  • Rspamd prüft Nachrichten auf Spam, Reputation und E-Mail-Authentifizierung und signiert ausgehende Nachrichten mit DKIM.
  • Redis speichert Statistik-, Lern- und Reputationsdaten für Rspamd.
  • Nginx stellt den ACME-Webroot und einen TLS-geschützten Reverse Proxy für die Rspamd-Weboberfläche bereit.
  • Die Postfächer werden als Maildir in den Home-Verzeichnissen lokaler Linux-Benutzer gespeichert.
  • Der Server empfängt E-Mails direkt aus dem Internet und versendet sie ebenfalls selbst.

Die Anleitung richtet sich an einen einzelnen Server und eine primäre Maildomain. Für viele Domains, Selbstbedienungsportale oder eine größere Benutzerzahl sind virtuelle Benutzer mit SQL oder LDAP besser geeignet.

Wichtiger Hinweis

Ein eigener Mailserver ist kein einmaliges Installationsprojekt. Er benötigt dauerhafte Pflege, Sicherheitsupdates, Überwachung, Backups und eine korrekt gepflegte DNS- und IP-Reputation. Viele Internetprovider sperren ausgehenden TCP-Port 25 oder stellen keine geeigneten PTR-Einträge bereit. Diese Voraussetzungen müssen vor der Installation geklärt sein.

Alle in dieser Anleitung verwendeten Namen und Adressen sind Platzhalter:

PlatzhalterBedeutungBeispiel
example.comprimäre Maildomaineigene Domain
mail.example.comvollständiger Hostname des Mailserverseigener FQDN
203.0.113.10öffentliche IPv4-Adresseeigene feste IPv4-Adresse
2001:db8::10öffentliche IPv6-Adressenur bei vollständig funktionierendem IPv6
alicelokaler Linux- und Mailbenutzergewünschter Benutzername

Vor dem Einsatz müssen alle Platzhalter ersetzt werden.

1. Voraussetzungen

Für den direkten Betrieb als Internet-Mailserver werden mindestens benötigt:

  • Debian 13 mit aktuellen Sicherheitsupdates,
  • eine feste öffentliche IPv4-Adresse,
  • optional eine vollständig funktionierende feste IPv6-Adresse,
  • freier eingehender und ausgehender TCP-Port 25,
  • Kontrolle über die DNS-Zone der Maildomain,
  • ein zum Hostnamen passender PTR-Eintrag beim Anschluss- oder Hostingprovider,
  • erreichbare Ports 25, 587 und 993,
  • Port 80 oder ein DNS-API-Zugang für die ACME-Zertifikatsvalidierung,
  • ein separater administrativer SSH-Zugang.

Eine IPv6-Adresse darf nur veröffentlicht werden, wenn der Server darüber dauerhaft erreichbar ist, ausgehend versenden kann und ein passender IPv6-PTR-Eintrag existiert. Eine unvollständige IPv6-Konfiguration verschlechtert die Zustellbarkeit.

2. Zielarchitektur

Der Nachrichtenfluss ist bewusst einfach:

Architektur des Mailservers: Nginx verarbeitet ausschließlich HTTP/HTTPS für ACME und Administration. Der SMTP- und IMAP-Verkehr läuft direkt über Postfix beziehungsweise Dovecot.

Mailprogramme senden nicht über Port 25. Sie verwenden den Submission-Port 587 mit verpflichtendem STARTTLS und Dovecot-SASL. Rspamd prüft auch diese ausgehenden Nachrichten und versieht sie mit einer DKIM-Signatur.

3. System vorbereiten

Zunächst wird das System aktualisiert:

sudo apt update
sudo apt full-upgrade

Falls dabei ein neuer Kernel oder andere zentrale Systemkomponenten installiert wurden, wird der Server kontrolliert neu gestartet:

sudo reboot

Danach werden Hostname und vollständiger Domainname gesetzt:

sudo hostnamectl set-hostname mail.example.com
hostname --fqdn

Die Ausgabe muss mail.example.com lauten. Falls nicht, müssen /etc/hostname, /etc/hosts und die DNS-Auflösung geprüft werden. Der Hostname darf nicht nur in /etc/hosts korrekt aussehen, sondern muss auch extern auf die öffentliche Adresse auflösen.

4. DNS vor der Installation

Mindestens folgende DNS-Einträge werden benötigt:

mail.example.com.    IN A       203.0.113.10
example.com.         IN MX 10   mail.example.com.

IPv6 wird nur ergänzt, wenn es vollständig funktioniert:

mail.example.com.    IN AAAA    2001:db8::10

Der PTR-Eintrag wird normalerweise beim Server- oder Anschlussprovider gesetzt:

203.0.113.10 → mail.example.com

Vorwärts- und Rückwärtsauflösung müssen zusammenpassen:

dig +short A mail.example.com
dig +short AAAA mail.example.com
dig +short MX example.com
dig +short -x 203.0.113.10

Ein erster SPF-Eintrag kann so aussehen:

example.com. IN TXT "v=spf1 mx -all"

DKIM und DMARC werden später ergänzt.

5. Pakete installieren

Debian 13 enthält Postfix 3.10, Dovecot 2.4, Rspamd 3.12, Redis 8 und Nginx 1.26. Für dieses How-to werden ausschließlich die Debian-Pakete verwendet:

sudo apt install \
  postfix \
  postfix-pcre \
  dovecot-core \
  dovecot-imapd \
  dovecot-lmtpd \
  dovecot-sieve \
  rspamd \
  redis-server \
  nginx \
  certbot \
  ca-certificates \
  swaks \
  s-nail

Bei der Postfix-Paketabfrage wird „Internet Site“ gewählt. Als System-Mailname wird example.com eingetragen. Die Konfiguration wird anschließend vollständig geprüft und angepasst.

Die Dienste werden aktiviert:

sudo systemctl enable postfix dovecot rspamd redis-server nginx
sudo systemctl start redis-server rspamd

Redis darf nicht aus dem Internet erreichbar sein:

sudo ss -lntp | grep 6379
redis-cli ping

Erwartet wird PONG und eine Bindung ausschließlich an lokale Adressen.

6. Nginx und TLS-Zertifikat

Nginx übernimmt in diesem Aufbau keine Mailprotokolle. Er stellt zwei klar begrenzte Funktionen bereit:

  • den Webroot für automatische ACME-HTTP-01-Prüfungen,
  • einen HTTPS-Reverse-Proxy für die lokal gebundene Rspamd-Weboberfläche.

Zuerst wird der ACME-Webroot angelegt:

sudo install -d -o www-data -g www-data -m 0755 /var/www/acme/.well-known/acme-challenge

Vor der ersten Zertifikatsanforderung enthält /etc/nginx/sites-available/mailserver nur den HTTP-Server:

server {
    listen 80;
    listen [::]:80;
    server_name mail.example.com;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/acme;
        default_type text/plain;
        try_files $uri =404;
    }

    location / {
        return 404;
    }
}

Die Standardseite wird deaktiviert und die neue Konfiguration aktiviert:

sudo rm -f /etc/nginx/sites-enabled/default
sudo ln -s /etc/nginx/sites-available/mailserver /etc/nginx/sites-enabled/mailserver
sudo nginx -t
sudo systemctl restart nginx

Für Postfix, Dovecot und Nginx wird ein öffentlich vertrauenswürdiges Zertifikat für mail.example.com verwendet. Nginx liefert dazu die ACME-Prüfdateien über Port 80 aus:

sudo certbot certonly --webroot -w /var/www/acme -d mail.example.com

Die Zertifikate liegen anschließend unter:

/etc/letsencrypt/live/mail.example.com/fullchain.pem
/etc/letsencrypt/live/mail.example.com/privkey.pem

Der Webroot-Modus benötigt keinen Neustart von Nginx und kann unbeaufsichtigt verlängert werden. Falls Port 80 nicht genutzt werden kann, sollte ein zum DNS-Provider passendes Certbot-DNS-Plugin eingesetzt werden. Eine manuelle DNS-Challenge ist für unbeaufsichtigte Verlängerungen ungeeignet.

Nach erfolgreicher Ausstellung wird /etc/nginx/sites-available/mailserver um HTTPS und den Reverse Proxy ergänzt:

server {
    listen 80;
    listen [::]:80;
    server_name mail.example.com;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/acme;
        default_type text/plain;
        try_files $uri =404;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name mail.example.com;

    ssl_certificate /etc/letsencrypt/live/mail.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mail.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_timeout 1d;
    ssl_session_cache shared:MailTLS:10m;
    server_tokens off;

    location /rspamd/ {
        allow 203.0.113.50;
        deny all;

        proxy_pass http://127.0.0.1:11334/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For "";
    }

    location / {
        return 404;
    }
}

203.0.113.50 ist ein Platzhalter für die feste administrative Quelladresse und muss ersetzt werden. Ohne bekannte feste Administrationsadresse sollte die Weboberfläche nicht allgemein veröffentlicht werden. Dann bleibt nur der lokale Zugriff über einen SSH-Tunnel.

Die Konfiguration wird vor dem Reload geprüft:

sudo nginx -t
sudo systemctl reload nginx

Die Rspamd-Weboberfläche ist danach unter https://mail.example.com/rspamd/ erreichbar – zusätzlich geschützt durch das Rspamd-Passwort.

Nach jeder erfolgreichen Zertifikatserneuerung müssen Postfix, Dovecot und Nginx die Dateien neu laden. Dazu wird /etc/letsencrypt/renewal-hooks/deploy/reload-mail-services angelegt:

#!/bin/sh
systemctl reload postfix
systemctl reload dovecot
systemctl reload nginx

Das Skript erhält Ausführungsrechte:

sudo chmod 0755 /etc/letsencrypt/renewal-hooks/deploy/reload-mail-services
sudo certbot renew --dry-run

7. Dovecot 2.4 konfigurieren

Dovecot 2.4 verwendet gegenüber älteren Anleitungen teilweise eine neue Konfigurationssyntax. Konfigurationen für Dovecot 2.3 sollten nicht unverändert übernommen werden.

Die vorhandene Konfiguration wird zunächst gesichert:

sudo cp -a /etc/dovecot /etc/dovecot.backup

Für den überschaubaren Einzelserver wird eine zusammenhängende /etc/dovecot/dovecot.conf verwendet:

dovecot_config_version = 2.4.0
dovecot_storage_version = 2.4.0

protocols {
  imap = yes
  lmtp = yes
}

mail_driver = maildir
mail_path = ~/Maildir

first_valid_uid = 1000

namespace inbox {
  inbox = yes
  separator = /
}

passdb pam {
}

auth_mechanisms = plain login
auth_allow_cleartext = no

ssl = required
ssl_server_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_server_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem

service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
}

service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}

protocol lmtp {
  postmaster_address = postmaster@example.com

  mail_plugins {
    sieve = yes
  }
}

Diese Konfiguration verwendet PAM für die Anmeldung der Linux-Systembenutzer. PLAIN und LOGIN sind nur innerhalb einer TLS-geschützten Verbindung erlaubt. ssl = required schützt die gesamte IMAP-Verbindung.

Die PAM-Datei /etc/pam.d/dovecot muss mindestens enthalten:

auth      required    pam_unix.so
account   required    pam_unix.so

Die Konfiguration wird vor jedem Neustart geprüft:

sudo doveconf -n
sudo dovecot -n
sudo systemctl restart dovecot
sudo systemctl status dovecot

8. Mailbenutzer anlegen

Bei diesem Aufbau entspricht der lokale Teil einer Mailadresse dem Linux-Benutzernamen:

alice@example.com → Linux-Benutzer alice

Der Benutzer wird mit Home-Verzeichnis, aber ohne nutzbare Login-Shell angelegt:

sudo adduser --disabled-password --gecos "" --shell /usr/sbin/nologin alice
sudo passwd alice

Das Passwort gilt bei dieser Architektur sowohl für PAM als auch für IMAP und SMTP-Submission. Deshalb darf für den Benutzer kein SSH- oder Konsolenzugang freigeschaltet werden.

Die Authentifizierung wird lokal getestet:

sudo doveadm auth test alice
sudo doveadm user alice

Das Maildir wird bei der ersten Zustellung automatisch angelegt. Alternativ:

sudo -u alice mkdir -p /home/alice/Maildir/{cur,new,tmp}

Wichtige Standardaliase werden in /etc/aliases gepflegt:

postmaster: root
abuse: root
root: alice

Anschließend:

sudo newaliases

9. Postfix konfigurieren

Vor der Änderung wird auch Postfix gesichert:

sudo cp -a /etc/postfix /etc/postfix.backup

Die Datei /etc/postfix/main.cf erhält folgende Basiskonfiguration:

compatibility_level = 3.10

myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain

inet_interfaces = all
inet_protocols = all

mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
relay_domains =

mynetworks = 127.0.0.0/8, [::1]/128

alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

mailbox_transport = lmtp:unix:private/dovecot-lmtp

smtpd_banner = $myhostname ESMTP
disable_vrfy_command = yes
biff = no
append_dot_mydomain = no
readme_directory = no

message_size_limit = 52428800
mailbox_size_limit = 0
recipient_delimiter = +

smtpd_relay_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  defer_unauth_destination

smtpd_recipient_restrictions =
  reject_non_fqdn_recipient,
  reject_unknown_recipient_domain,
  reject_unauth_pipelining

smtpd_tls_security_level = may
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
smtpd_tls_received_header = yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache

smtp_tls_security_level = may
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = no
smtpd_sasl_security_options = noanonymous

smtpd_milters = inet:127.0.0.1:11332
non_smtpd_milters = inet:127.0.0.1:11332
milter_protocol = 6
milter_default_action = tempfail
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}

mynetworks enthält absichtlich nur Loopback. Ganze Heim-, Firmen- oder Providernetze sollten hier nicht pauschal als vertrauenswürdig eingetragen werden.

milter_default_action = tempfail verzögert die Annahme, wenn Rspamd nicht verfügbar ist. Dadurch werden Nachrichten nicht ungeprüft angenommen. Wer höhere Verfügbarkeit gegenüber einer zwingenden Filterung priorisiert, kann bewusst accept verwenden.

Die Postfix-Konfiguration wird geprüft:

sudo postfix check
sudo postconf -n

10. Submission-Port 587

SMTP-Authentifizierung wird nicht auf dem öffentlichen Port 25 aktiviert. Mailprogramme verwenden ausschließlich den Submission-Dienst auf Port 587.

In /etc/postfix/master.cf wird folgender Dienst ergänzt oder der vorhandene Submission-Abschnitt entsprechend angepasst:

submission inet n - y - - smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth
  -o smtpd_sasl_security_options=noanonymous
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
  -o smtpd_sender_restrictions=reject_non_fqdn_sender

STARTTLS ist auf Port 587 verpflichtend. Eine Anmeldung ohne verschlüsselte Verbindung wird nicht akzeptiert.

Optional kann zusätzlich Port 465 mit implizitem TLS angeboten werden:

submissions inet n - y - - smtpd
  -o syslog_name=postfix/submissions
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth
  -o smtpd_sasl_security_options=noanonymous
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject

Danach:

sudo postfix check
sudo systemctl restart postfix
sudo systemctl status postfix

11. Rspamd und Redis konfigurieren

Rspamd verarbeitet SPF, DKIM und DMARC, verschiedene Reputations- und Blocklisten, statistische Merkmale, neuronale Klassifikatoren sowie benutzerdefinierte Regeln. Redis wird für Statistik, Bayes-Lernen, Greylisting und weitere Zustandsdaten benötigt.

Redis wird in /etc/rspamd/local.d/redis.conf eingetragen:

servers = "127.0.0.1:6379";
timeout = 1s;

Der Proxy-Worker für Postfix wird in /etc/rspamd/local.d/worker-proxy.inc konfiguriert:

bind_socket = "127.0.0.1:11332";
milter = yes;
timeout = 120s;

upstream "local" {
  default = yes;
  self_scan = yes;
}

Für den Anfang werden konservative Standardwerte in /etc/rspamd/local.d/actions.conf verwendet:

reject = 15;
add_header = 6;
greylist = 4;

Nachrichten mit einem hohen Score werden abgewiesen, verdächtige Nachrichten markiert und Nachrichten im Greylisting-Bereich temporär zurückgestellt. Die Werte sollten erst nach Auswertung realer Nachrichten verändert werden.

Die Weboberfläche bleibt ausschließlich lokal erreichbar. Zunächst wird ein Passwort-Hash erzeugt:

sudo rspamadm pw

Der erzeugte Hash wird in /etc/rspamd/local.d/worker-controller.inc eingetragen:

bind_socket = "127.0.0.1:11334";
password = "$2$ERZEUGTER_HASH";

Für den Zugriff wird ein SSH-Tunnel verwendet:

ssh -L 11334:127.0.0.1:11334 admin@mail.example.com

Direkt ist die Oberfläche nur lokal unter http://127.0.0.1:11334 erreichbar. Von außen erfolgt der Zugriff ausschließlich über Nginx unter https://mail.example.com/rspamd/ und nur von der freigegebenen Administrationsadresse. Port 11334 wird nicht in der öffentlichen Firewall geöffnet.

Rspamd wird geprüft und neu gestartet:

sudo rspamadm configtest
sudo systemctl restart rspamd
sudo systemctl status rspamd
sudo rspamc stat

12. DKIM-Signierung

Rspamd signiert authentifiziert eingelieferte Nachrichten. Der private Schlüssel verbleibt auf dem Mailserver; der öffentliche Schlüssel wird im DNS veröffentlicht.

Schlüsselverzeichnis und 2048-Bit-RSA-Schlüssel werden erstellt:

sudo install -d -o _rspamd -g _rspamd -m 0750 /etc/rspamd/dkim
cd /etc/rspamd/dkim
sudo rspamadm dkim_keygen -b 2048 -s mail -d example.com -k mail.key
sudo chown _rspamd:_rspamd mail.key mail.txt
sudo chmod 0600 mail.key
sudo chmod 0644 mail.txt

Die Datei /etc/rspamd/local.d/dkim_signing.conf erhält:

enabled = true;

domain {
  example.com {
    selector = "mail";
    path = "/etc/rspamd/dkim/mail.key";
  }
}

sign_authenticated = true;
sign_local = true;
sign_inbound = false;
use_esld = true;
check_pubkey = true;

Der Inhalt von mail.txt wird als TXT-Record veröffentlicht:

mail._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=ÖFFENTLICHER_SCHLÜSSEL"

Nach der DNS-Veröffentlichung:

dig +short TXT mail._domainkey.example.com
sudo rspamadm configtest
sudo systemctl restart rspamd

Der private DKIM-Schlüssel gehört zwingend in das Backup, darf aber niemals veröffentlicht werden.

13. DMARC veröffentlichen

DMARC sollte stufenweise eingeführt werden. Während der Beobachtungsphase:

_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com; adkim=s; aspf=s"

Erst wenn alle legitimen Absender SPF- oder DKIM-aligned sind und die Berichte ausgewertet wurden, wird die Richtlinie verschärft:

_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:dmarc@example.com; adkim=s; aspf=s"

Später kann p=reject verwendet werden. Eine ungeprüfte sofortige Umstellung auf reject kann legitime Absender der eigenen Domain blockieren.

Der Alias für die Berichte wird ergänzt:

dmarc: alice

Anschließend erneut:

sudo newaliases

14. Optionaler Virenscanner

Rspamd ist ein Spam- und Policy-System, aber kein vollständiger Virenscanner. Falls serverseitiges Malware-Scanning gewünscht ist, kann ClamAV angebunden werden:

sudo apt install clamav-daemon clamav-freshclam
sudo systemctl enable --now clamav-freshclam clamav-daemon

Die genaue Socket-Adresse wird geprüft:

sudo ss -lx | grep clam

Erst danach wird /etc/rspamd/local.d/antivirus.conf passend zur tatsächlich vorhandenen Socket-Adresse angelegt. Beispiel:

clamav {
  type = "clamav";
  servers = "/run/clamav/clamd.ctl";
  symbol = "CLAM_VIRUS";
  action = "reject";
}

Danach:

sudo rspamadm configtest
sudo systemctl restart rspamd

Das bloße Installieren von ClamAV reicht nicht aus. Signaturstand, Dienststatus und echte Scan-Funktion müssen überwacht werden.

15. Firewall

Öffentlich erreichbar sein müssen:

PortProtokollZweck
25/TCPSMTPServer-zu-Server-Zustellung
587/TCPSubmissionauthentifizierter Mailversand
993/TCPIMAPSverschlüsselter IMAP-Zugriff
465/TCPSubmissionsoptionaler Versand mit implizitem TLS
80/TCPHTTPACME HTTP-01 und Weiterleitung auf HTTPS
443/TCPHTTPSadministrativer Nginx-Zugang zu Rspamd

Nicht öffentlich erreichbar sein dürfen insbesondere:

  • Redis 6379,
  • Rspamd Proxy 11332,
  • Rspamd Worker 11333,
  • Rspamd Weboberfläche 11334.

Die Firewallregeln müssen sowohl für IPv4 als auch IPv6 geprüft werden.

16. Funktionstests

Zunächst werden alle Konfigurationen lokal geprüft:

sudo postfix check
sudo postconf -n
sudo doveconf -n
sudo rspamadm configtest
redis-cli ping

Die Listener werden kontrolliert:

sudo ss -lntp

IMAPS

openssl s_client \
  -connect mail.example.com:993 \
  -servername mail.example.com

Zertifikatsname und Zertifikatskette müssen korrekt sein.

Submission

openssl s_client \
  -starttls smtp \
  -connect mail.example.com:587 \
  -servername mail.example.com

Authentifizierter Versand

swaks \
  --server mail.example.com \
  --port 587 \
  --tls \
  --auth LOGIN \
  --auth-user alice \
  --auth-password 'PASSWORT' \
  --from alice@example.com \
  --to externe-adresse@example.net

Das Passwort sollte in einer gemeinsam genutzten Shell nicht direkt in der Kommandozeile angegeben werden, da es je nach Umgebung in Prozesslisten oder Shell-Historien erscheinen kann.

Relay-Test

Ein nicht authentifizierter externer Absender darf nicht über den Server an eine fremde Domain weiterleiten:

swaks \
  --server mail.example.com \
  --port 25 \
  --from outsider@example.net \
  --to recipient@example.org

Der Versuch muss mit „Relay access denied“ oder einer vergleichbaren 5xx-Antwort abgewiesen werden.

Rspamd

printf 'Subject: Test\n\nDies ist eine Testnachricht.\n' | rspamc
sudo rspamc stat

Bei extern zugestellten Testnachrichten werden anschließend die Header geprüft:

Authentication-Results:
DKIM-Signature:
X-Spamd-Result:
X-Rspamd-Server:

Für den DKIM-Test muss die Nachricht über Port 587 authentifiziert eingeliefert und an ein externes Postfach gesendet werden.

17. Rspamd lernen lassen

Rspamd benötigt eine ausreichende und ausgewogene Menge korrekt klassifizierter Nachrichten. Einzelne Nachrichten oder ausschließlich Spam zu trainieren verschlechtern das Ergebnis.

Manuelles Training

rspamc learn_spam /pfad/zu/spam.eml
rspamc learn_ham /pfad/zu/ham.eml
rspamc stat

Automatisches Lernen mit Dovecot IMAPSieve

Dovecot kann eine Nachricht beim Kopieren oder Verschieben in den serverseitigen Ordner Spam an rspamc learn_spam übergeben. Wird die Nachricht anschließend aus Spam nach INBOX zurückverschoben, wird sie mit rspamc learn_ham neu klassifiziert. Technisch verschiebt dabei nicht Rspamd die Nachricht: Der Benutzer korrigiert die Einordnung in seinem IMAP-Client.

Der Ordner trägt serverseitig den Namen Spam und die besondere Verwendung \Junk. Ein Client kann ihn deshalb in der Oberfläche auch als „Junk“ oder „Spam“ anzeigen. Es darf nicht zusätzlich ein zweiter Junk-Ordner angelegt werden.

Die folgenden Ereignisse werden bewusst ausgewertet:

IMAP-AktionLernvorgang
Nachricht nach Spam kopieren oder verschiebenlearn_spam
Nachricht aus Spam nach INBOX kopieren oder verschiebenlearn_ham
Nachricht aus Spam in Papierkorb, Archiv oder einen anderen Ordner verschiebenkein Lernen

Diese Automatik reagiert ausschließlich auf IMAP-Aktionen. Eine direkte Zustellung durch LMTP in den Spamordner löst sie nicht aus. Das ist beabsichtigt: Rspamd soll nicht seine eigene Klassifizierung ungeprüft als Trainingssignal verwenden.

Eigenes Controller-Passwort für Lernvorgänge

Das Lernen ist eine privilegierte Schreiboperation am Rspamd-Controller. Neben dem bereits eingerichteten WebUI-Passwort wird deshalb ein separates, langes Lernpasswort benötigt. Es wird nicht im Sieve-Skript selbst gespeichert.

Zunächst wird eine ausschließlich hierfür verwendete Gruppe angelegt:

sudo groupadd --system rspamd-learners

Das Klartextpasswort wird mit einem Passwortgenerator erzeugt und über sudoedit als einzige Zeile in /etc/rspamd/learn-password gespeichert:

sudo install -o root -g rspamd-learners -m 0640 /dev/null \
  /etc/rspamd/learn-password
sudoedit /etc/rspamd/learn-password

Für dasselbe Passwort wird interaktiv ein Rspamd-Hash erzeugt:

sudo rspamadm pw

Der bisherige Inhalt von /etc/rspamd/local.d/worker-controller.inc wird um enable_password ergänzt:

bind_socket = "127.0.0.1:11334";
password = "$2$HASH_DES_WEBUI_PASSWORTS";
enable_password = "$2$HASH_DES_LERNPASSWORTS";

password schützt den normalen WebUI-Zugriff. enable_password autorisiert Änderungen und Lernvorgänge. Das Klartext-Lernpasswort und das WebUI-Passwort sollten verschieden sein.

Dovecot konfigurieren

In /etc/dovecot/dovecot.conf wird der vorhandene Block namespace inbox um das Spam-Postfach ergänzt:

namespace inbox {
  inbox = yes
  separator = /

  mailbox Spam {
    auto = create
    special_use = \Junk
  }
}

Zusätzlich werden folgende Einstellungen auf oberster Ebene ergänzt:

protocol imap {
  mail_plugins {
    imap_sieve = yes
  }
}

sieve_plugins {
  sieve_imapsieve = yes
  sieve_extprograms = yes
}

sieve_global_extensions {
  vnd.dovecot.pipe = yes
  vnd.dovecot.environment = yes
}

sieve_pipe_bin_dir = /usr/lib/dovecot/sieve

mail_access_groups {
  rspamd-learners = yes
}

mailbox Spam {
  sieve_script report-spam {
    type = before
    cause = copy
    path = /etc/dovecot/report-spam.sieve
  }
}

imapsieve_from Spam {
  sieve_script report-ham {
    type = before
    cause = copy
    path = /etc/dovecot/report-ham.sieve
  }
}

mail_access_groups gibt den Dovecot-Mailprozessen nur Zugriff auf das Lernpasswort. Die Gruppe sollte keinen Zugriff auf andere Dateien erhalten.

Sieve-Regeln anlegen

/etc/dovecot/report-spam.sieve enthält:

require ["vnd.dovecot.pipe", "copy", "imapsieve"];

pipe :copy "rspamd-learn-spam.sh";

/etc/dovecot/report-ham.sieve lernt nur dann Ham, wenn das Ziel exakt INBOX ist:

require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment"];

if not environment :is "imap.mailbox" "INBOX" {
  stop;
}

pipe :copy "rspamd-learn-ham.sh";

INBOX wird absichtlich großgeschrieben, da dieser Name in IMAP eine Sonderstellung hat und Dovecot bei den übrigen Postfachnamen zwischen Groß- und Kleinschreibung unterscheiden kann.

Pipe-Skripte anlegen

Dovecot erlaubt hier nur Programme unterhalb von sieve_pipe_bin_dir. Das Skript /usr/lib/dovecot/sieve/rspamd-learn-spam.sh enthält:

#!/bin/sh
set -eu

IFS= read -r password < /etc/rspamd/learn-password
exec /usr/bin/rspamc \
  -h 127.0.0.1:11334 \
  -P "$password" \
  learn_spam

Das Skript /usr/lib/dovecot/sieve/rspamd-learn-ham.sh enthält:

#!/bin/sh
set -eu

IFS= read -r password < /etc/rspamd/learn-password
exec /usr/bin/rspamc \
  -h 127.0.0.1:11334 \
  -P "$password" \
  learn_ham

Beide Skripte müssen unveränderbar für Mailbenutzer, aber ausführbar sein:

sudo chown root:root \
  /usr/lib/dovecot/sieve/rspamd-learn-spam.sh \
  /usr/lib/dovecot/sieve/rspamd-learn-ham.sh
sudo chmod 0755 \
  /usr/lib/dovecot/sieve/rspamd-learn-spam.sh \
  /usr/lib/dovecot/sieve/rspamd-learn-ham.sh

Sieve-Regeln werden vor der Aktivierung kompiliert:

sudo sievec /etc/dovecot/report-spam.sieve
sudo sievec /etc/dovecot/report-ham.sieve

Konfiguration prüfen und Funktion testen

sudo doveconf -n
sudo rspamadm configtest
sudo systemctl restart rspamd
sudo systemctl restart dovecot
sudo journalctl -u dovecot -u rspamd --since "5 minutes ago"

Für IMAPSieve ist ein vollständiger Dovecot-Neustart erforderlich; ein Reload genügt nicht zuverlässig. Danach wird eine bekannte Testnachricht im IMAP-Client zunächst nach Spam und anschließend zurück nach INBOX verschoben. Die Lernvorgänge werden in den Protokollen und über die Statistik kontrolliert:

sudo journalctl -f -u dovecot -u rspamd
sudo rspamc stat

Rspamd kann eine bereits gelernte Nachricht beim Wechsel von Spam zu Ham neu lernen. Trotzdem darf die Automatik nur für vertrauenswürdige Benutzer aktiviert werden: Falsche oder missbräuchliche Ordnerbewegungen können die Bayes-Datenbank vergiften. Außerdem erzeugt jede Verschiebung einen synchronen Lernaufruf und kann bei großen Nachrichtenmengen spürbar Zeit kosten.

18. Protokolle und Überwachung

Die wichtigsten Status- und Logabfragen:

systemctl status postfix dovecot rspamd redis-server nginx
journalctl -u postfix -u dovecot -u rspamd -u redis-server -u nginx --since today
postqueue -p
mailq
rspamc stat
certbot certificates

Überwacht werden sollten mindestens:

  • Erreichbarkeit der Ports 25, 587 und 993,
  • Ablaufdatum und korrekter Name des TLS-Zertifikats,
  • Größe und Alter der Postfix-Queue,
  • fehlgeschlagene Dovecot-Anmeldungen,
  • Rspamd- und Redis-Verfügbarkeit,
  • DKIM-Signaturen ausgehender Nachrichten,
  • SPF-, DKIM- und DMARC-Ergebnisse,
  • freier Speicherplatz und Inodes,
  • ungewöhnliche Versandmengen je Benutzer,
  • ausstehende Sicherheitsupdates,
  • Blacklist- und Reputationsprobleme der öffentlichen IP-Adresse.

19. Backup und Wiederherstellung

Mindestens folgende Daten müssen gesichert werden:

/etc/postfix/
/etc/dovecot/
/etc/rspamd/
/etc/nginx/
/etc/letsencrypt/
/etc/aliases
/etc/passwd
/etc/shadow
/etc/group
/home/*/Maildir/
/var/lib/redis/

Zusätzlich gehören die DNS-Einträge, der PTR-Auftrag und die Firewallkonfiguration in die Dokumentation.

Eine Dateikopie ist noch kein belastbares Backup. Benötigt werden:

  • verschlüsselte Speicherung,
  • mindestens eine getrennte oder unveränderbare Kopie,
  • definierte Aufbewahrungsfristen,
  • regelmäßige Wiederherstellungstests,
  • dokumentierte Wiederanlaufreihenfolge.

Bei der Wiederherstellung werden zuerst Systemidentitäten und Konfiguration, danach Zertifikate, Maildirs und Rspamd-/Redis-Daten zurückgespielt. UID und GID der Benutzer müssen erhalten bleiben.

20. Updates und Wartung

Regelmäßig:

sudo apt update
apt list --upgradable
sudo apt upgrade
sudo postfix check
sudo doveconf -n
sudo rspamadm configtest
sudo certbot renew --dry-run

Vor größeren Versionswechseln müssen insbesondere die Release Notes von Debian, Dovecot, Postfix und Rspamd geprüft werden. Dovecot 2.4 hat gezeigt, dass selbst lange etablierte Konfigurationsparameter und Syntaxformen geändert werden können.

21. Grenzen dieses Aufbaus

Linux-Systembenutzer sind für einen kleinen Einzelserver nachvollziehbar, bringen aber Einschränkungen mit:

  • Mailpasswort und PAM-Passwort sind identisch.
  • Jeder Mailbenutzer benötigt einen lokalen Account und eine eigene UID.
  • Der lokale Teil der Mailadresse entspricht dem Benutzernamen.
  • Mehrere Domains und Aliase werden schnell unübersichtlich.
  • Automatisierte Benutzerverwaltung ist nur begrenzt vorhanden.

Für mehrere Domains, größere Benutzerzahlen oder administrative Portale sollte ein virtuelles Benutzerkonzept mit separater UID, SQL oder LDAP geplant werden.

Fazit

Postfix, Dovecot und Rspamd bilden unter Debian 13 einen schlanken und leistungsfähigen Mailserver. Der wesentliche Unterschied zu einem Aufbau aus dem Jahr 2009 liegt jedoch nicht nur in den ausgetauschten Programmen. Heute gehören TLS-geschützte Submission, eine eindeutige Relay-Policy, SPF, DKIM, DMARC, kontinuierliches Zertifikatsmanagement, Reputation, Überwachung und getestete Wiederherstellung zum Pflichtumfang.

Ein erfolgreicher Testversand bedeutet deshalb noch nicht, dass der Server produktionsbereit ist. Produktiv ist er erst dann, wenn Empfang, Versand, Authentifizierung, Filterung, DNS-Authentifizierung, Monitoring, Updates und Restore nachvollziehbar funktionieren.

Quellen und weiterführende Dokumentation