Files
mailsystem/README-install-SRS.md
T

29 KiB
Raw Blame History

README-install-SRS.md

Selektives SRS für Postfix – Installation und Integration

Stand: 17.10.2026
System: mx.warenform.de
Betriebssystem: Debian 13
Ziel: Selektives Sender Rewriting Scheme (SRS) nur für echte externe Alias-Weiterleitungen, ohne normale ausgehende Nachrichten, lokale Zustellungen oder intern erzeugte Benachrichtigungen unnötig umzuschreiben.


0. Das Grundproblem: Warum weitergeleitete E-Mails abgelehnt werden können

Moderne Mailserver – insbesondere große Provider wie Google/Gmail, Microsoft, GMX oder Yahoo – prüfen eingehende E-Mails sehr streng auf die Authentizität des Absenders.

Dabei spielen vor allem drei Verfahren eine Rolle:

SPF
DKIM
DMARC

Eine klassische E-Mail-Weiterleitung kann diese Prüfungen stören, obwohl die ursprüngliche E-Mail vollkommen legitim ist.

0.1 Beispiel einer normalen Weiterleitung

Eine Nachricht wird ursprünglich von:

ckubu@gmx.de

an:

test@warenform.de

gesendet.

Auf mx.warenform.de existiert für diese Adresse beispielsweise eine Weiterleitung:

test@warenform.de -> ckubu@gmail.com

Die ursprüngliche Nachricht kommt korrekt von einem GMX-Mailserver:

GMX
 |
 | MAIL FROM:<ckubu@gmx.de>
 |
 v
mx.warenform.de

Bis hierhin ist alles in Ordnung.

Der SPF-Test kann beispielsweise feststellen:

Absender-Domain: gmx.de
sendender Server: GMX-Mailserver
Ergebnis: SPF PASS

Das Problem entsteht bei der anschließenden Weiterleitung.

Ohne besondere Maßnahmen würde mx.warenform.de dieselbe Nachricht weiterleiten als:

mx.warenform.de
 |
 | MAIL FROM:<ckubu@gmx.de>
 |
 v
gmail.com

Für Gmail sieht die Situation nun so aus:

Envelope-Absender: ckubu@gmx.de
sendender Server:  mx.warenform.de

Gmail prüft deshalb den SPF-Eintrag von gmx.de.

Die entscheidende Frage lautet:

Darf die IP-Adresse von mx.warenform.de E-Mails für gmx.de versenden?

Die Antwort lautet: nein.

mx.warenform.de gehört nicht zur Mail-Infrastruktur von GMX und ist deshalb nicht im SPF-Record von gmx.de autorisiert.

Eine ursprünglich vollkommen legitime E-Mail kann durch die Weiterleitung daher plötzlich einen SPF FAIL oder zumindest einen ungünstigen SPF-Bewertungszustand erhalten.

0.2 Warum der empfangende Server die Weiterleitung nicht einfach „erkennen“ kann

Aus Sicht des empfangenden Servers besteht zunächst kein grundlegender Unterschied zwischen einem legitimen Weiterleitungsserver und einem fremden Server, der vorgibt, Mail für gmx.de zu versenden.

Beide Situationen sehen auf SMTP-Ebene zunächst ähnlich aus:

MAIL FROM:<ckubu@gmx.de>

aber die Verbindung kommt von einer IP-Adresse, die nicht zu GMX gehört.

Der empfangende Server kann deshalb den ursprünglichen SPF-Erfolg nicht einfach übernehmen. Er muss die Nachricht anhand der Verbindung prüfen, über die sie jetzt zugestellt wird.

0.3 DKIM kann das Problem teilweise auffangen

Neben SPF gibt es DKIM.

GMX versieht eine Nachricht beispielsweise mit einer kryptographischen Signatur:

DKIM-Signature:
    d=gmx.de

Diese Signatur wird über bestimmte Header und Teile des Nachrichteninhalts gebildet.

Wenn der Weiterleitungsserver die Nachricht nicht verändert, kann diese ursprüngliche DKIM-Signatur auch nach der Weiterleitung weiterhin gültig sein.

Der Zielserver kann dann DKIM PASS feststellen, obwohl der SPF-Test des ursprünglichen Absenders durch die Weiterleitung problematisch geworden ist.

Eine Weiterleitung darf deshalb möglichst keine Änderungen an den von DKIM signierten Bestandteilen der Nachricht vornehmen. Problematisch können zum Beispiel sein:

Änderung des Subject-Headers
Hinzufügen von Text zum Body
Änderung bestimmter signierter Header
Umformatierung des Nachrichteninhalts

Solche Änderungen können die ursprüngliche DKIM-Signatur ungültig machen.

0.4 DMARC verschärft das Problem

DMARC verbindet SPF und DKIM mit der sichtbaren Absenderadresse im From:-Header.

Bei unserer Beispielmail steht dort weiterhin:

From: ckubu@gmx.de

DMARC verlangt vereinfacht, dass mindestens einer der beiden Mechanismen SPF oder DKIM erfolgreich ist und dabei zur Domain im sichtbaren From:-Header passt.

Bei einer einfachen Weiterleitung kann folgende Situation entstehen:

From:       ckubu@gmx.de
SPF:        FAIL
DKIM:       PASS
DMARC:      PASS

Das funktioniert, solange die ursprüngliche DKIM-Signatur erhalten bleibt.

Wird dagegen auch DKIM durch die Weiterleitung beschädigt, kann das Ergebnis sein:

SPF:        FAIL
DKIM:       FAIL
DMARC:      FAIL

Wenn die Domain des ursprünglichen Absenders beispielsweise eine strenge DMARC-Policy wie p=reject veröffentlicht, kann der Zielserver die Nachricht vollständig ablehnen.

Auch ohne hartes reject verschlechtern fehlgeschlagene Authentifizierungsprüfungen die Bewertung einer Nachricht erheblich. Große Provider wie Gmail berücksichtigen zusätzlich Reputation, Nachrichtenhistorie und weitere Anti-Spam-Signale. Eine saubere SPF-/DKIM-/DMARC-Situation ist daher besonders wichtig.

0.5 Das Prinzip von SRS

Das Sender Rewriting Scheme (SRS) löst das SPF-Problem der Weiterleitung, indem der Envelope-Absender beim Weiterleiten umgeschrieben wird.

Aus:

MAIL FROM:<ckubu@gmx.de>

wird beispielsweise:

MAIL FROM:<SRS0=...=gmx.de=ckubu@srs.warenform.de>

Die sichtbare Absenderadresse der Nachricht bleibt dagegen unverändert:

From: ckubu@gmx.de

Der Zielserver prüft SPF nun nicht mehr für gmx.de, sondern für srs.warenform.de.

Damit lautet die SPF-Frage jetzt:

Darf mx.warenform.de Mail für srs.warenform.de versenden?

Diese Frage kann mit ja beantwortet werden. Das Ergebnis ist SPF PASS.

0.6 Warum DKIM trotz SRS weiterhin wichtig ist

Nach der SRS-Umschreibung gehört der Envelope-Absender beispielsweise zu:

srs.warenform.de

Der sichtbare Absender bleibt aber:

From: ckubu@gmx.de

Damit ist SPF zwar technisch erfolgreich, aber die SPF-Domain ist nicht mehr identisch mit der sichtbaren From:-Domain.

Für DMARC ist deshalb die weiterhin gültige ursprüngliche DKIM-Signatur besonders wichtig.

Im Idealfall ergibt sich nach der Weiterleitung:

Envelope-From:
    SRS0=...@srs.warenform.de

Header-From:
    ckubu@gmx.de

SPF:
    PASS für srs.warenform.de

DKIM:
    PASS für gmx.de

DMARC:
    PASS über DKIM

Genau dieses Verhalten wurde bei der hier beschriebenen Installation im abschließenden End-to-End-Test bestätigt.

0.7 Warum SRS nicht einfach global eingesetzt wird

SRS ist für diesen Zweck eine Lösung für weitergeleitete Nachrichten.

Es gibt keinen Grund, beispielsweise eine normale eigene ausgehende Nachricht oder eine lokale Zustellung ebenfalls mit SRS umzuschreiben.

Eine globale SRS-Umschreibung würde unnötige Komplexität erzeugen und könnte unerwünschte Nebenwirkungen haben.

Das Ziel dieser Installation lautet daher ausdrücklich:

SRS nur dort einsetzen,
wo eine fremde Nachricht tatsächlich
an einen externen Empfänger weitergeleitet wird.

Daraus ergibt sich die im weiteren Verlauf beschriebene selektive SRS-Architektur.


1. Ausgangssituation

Auf mx.warenform.de läuft ein produktives Mail-System mit:

  • Postfix
  • AmaViS
  • SpamAssassin
  • ClamAV
  • OpenDKIM
  • OpenDMARC
  • postfix-policyd-spf-python
  • Dovecot LMTP
  • virtuellen Domains und Aliasen über PostgreSQL/PostfixAdmin
  • lokalen Aliasen aus /etc/aliases
  • Dovecot/Sieve für lokale Zustellung und Benachrichtigungen

Der normale eingehende Mailpfad ist vereinfacht:

Internet
  |
  v
Postfix :25
  |
  v
AmaViS :10024
  |
  v
Postfix-Reinjection :10025
  |
  +--> lokale/virtuelle Zustellung via Dovecot LMTP
  |
  +--> externe Alias-Weiterleitung

Vor Einführung von SRS wurden externe Weiterleitungen mit dem ursprünglichen Envelope-Sender weitergesendet.

Beispiel:

MAIL FROM: <ckubu@gmx.de>
RCPT TO:   <test@warenform.de>

test@warenform.de enthält unter anderem die externe Zieladresse:

ckubu@oopen.de

Ohne SRS würde mx.warenform.de die Nachricht an ckubu@oopen.de mit

MAIL FROM: <ckubu@gmx.de>

weiterleiten.

Das ist heute problematisch, weil der empfangende Server dann SPF für gmx.de gegen die IP-Adresse von mx.warenform.de prüft. Diese IP ist natürlich nicht als GMX-Mailserver autorisiert.

Die Weiterleitung kann dadurch einen SPF-Fehler erzeugen, obwohl die ursprüngliche Nachricht legitim war.


2. Warum die Lösung nicht einfach aus „PostSRSd einschalten“ besteht

Auf diesem System reicht ein globales Umschreiben aller Absender nicht aus.

SRS soll nur dann angewendet werden, wenn wirklich eine externe Alias-Weiterleitung stattfindet.

Nicht mit SRS umgeschrieben werden sollen beispielsweise:

  • direkte ausgehende Nachrichten,
  • normale SMTP-Zustellungen,
  • lokale Alias-Zustellungen,
  • lokale Weiterleitungen aus /etc/aliases,
  • lokale virtuelle Mailboxen,
  • durch Dovecot/Sieve neu erzeugte Benachrichtigungen,
  • Nachrichten mit leerem Envelope-Sender (<>),
  • administrative Nachrichten wie root -> argus@oopen.de.

Daraus ergeben sich mehrere technische Anforderungen:

  1. Postfix muss für jeden einzelnen Ziel-Empfänger entscheiden können, ob SRS notwendig ist.
  2. Der ursprüngliche Alias-Empfänger muss während der Verarbeitung erhalten bleiben.
  3. Lokale und externe Ziele desselben Alias müssen unterschiedlich behandelt werden können.
  4. Eingehende Bounces an SRS-Adressen müssen wieder auf die ursprüngliche Adresse zurückgeschrieben werden.
  5. Die ursprüngliche DKIM-Signatur der weitergeleiteten Nachricht darf nicht unnötig beschädigt werden.
  6. Das Ganze muss ohne postmulti funktionieren und nach einem Reboot automatisch starten.
  7. Die Konfiguration muss später durch Enable-/Disable-/Update-Skripte reproduzierbar und reversibel sein.

3. Zielarchitektur

Die produktive Architektur besteht aus vier SRS-Hilfsskripten, PostSRSd, einem Reverse-Socketmap-Dienst und einer separaten Postfix-Delivery-Instanz.

3.1 Komponenten

/usr/local/sbin/srs-forward.py
/usr/local/sbin/srs-alias-decision.py
/usr/local/sbin/srs-reverse-map.py
/usr/local/sbin/srs-reverse-policy.py

PostSRSd:

/usr/local/postsrsd -> /usr/local/postsrsd-2.4.1

Konfiguration:

/etc/postsrsd-srs/postsrsd.conf
/etc/postsrsd-srs/secret

Systemd-Dienste:

postsrsd-srs.service
srs-reverse-map.service
postfix@srs-delivery.service
postfix.service

SRS-Delivery-Konfiguration:

/etc/postfix-srs/delivery/main.cf
/etc/postfix-srs/delivery/master.cf
/etc/postfix-srs/delivery/transport
/etc/postfix-srs/delivery/transport.db

4. Verwendete Ports

Port Dienst Zweck
25 Haupt-Postfix normaler SMTP-Eingang
10003 PostSRSd SRS Forward + Reverse Socketmap
10004 srs-reverse-map.py eingeschränkte Reverse-Socketmap für Haupt-Postfix
10028 SRS-Delivery-Postfix Reinjection von selektiv verarbeiteten Nachrichten
10029 SRS-Delivery-Postfix Reverse-SRS-Reinjection für Bounces

Alle SRS-internen Dienste lauschen ausschließlich auf Loopback.


5. PostSRSd

Installiert ist PostSRSd 2.4.1 unter:

/usr/local/postsrsd-2.4.1

Der stabile Pfad lautet:

/usr/local/postsrsd

und ist ein Symlink auf die aktuell aktive Version.

Das ermöglicht später ein versionsweises Update, z. B.:

/usr/local/postsrsd-2.4.1
/usr/local/postsrsd-2.5.0
/usr/local/postsrsd -> /usr/local/postsrsd-2.5.0

5.1 Systemd-Service

postsrsd-srs.service

Startkommando:

/usr/local/postsrsd/sbin/postsrsd -C /etc/postsrsd-srs/postsrsd.conf

5.2 Produktive Konfiguration

domains = {}
srs-domain = "srs.warenform.de"
socketmap = inet:127.0.0.1:10003
secrets-file = "/etc/postsrsd-srs/secret"
milter-rewrite-local = off
original-envelope = embedded
debug = off

PostSRSd stellt auf Port 10003 mindestens folgende Socketmap-Funktionen bereit:

forward
reverse

Beispiel:

postmap -q \
    'ckubu@gmx.de' \
    'socketmap:inet:127.0.0.1:10003:forward'

Ergebnis:

SRS0=...=gmx.de=ckubu@srs.warenform.de

Reverse:

postmap -q \
    'SRS0=...=gmx.de=ckubu@srs.warenform.de' \
    'socketmap:inet:127.0.0.1:10003:reverse'

Ergebnis:

ckubu@gmx.de

6. Warum das Debian-Paket postsrsd entfernt wurde

Das Debian-Paket postsrsd Version 1.x war zusätzlich installiert.

Es wurde nicht mehr benötigt, da die produktive Installation bewusst als eigene, versionierte Installation unter /usr/local/postsrsd-* betrieben wird.

Das Debian-Paket wurde deshalb entfernt:

apt-get purge postsrsd

Dadurch gibt es nur noch eine produktive PostSRSd-Implementierung und keine Verwechslungsgefahr zwischen:

/usr/sbin/postsrsd

und

/usr/local/postsrsd/sbin/postsrsd

7. Selektive SRS-Entscheidung

Die zentrale Logik liegt in:

/usr/local/sbin/srs-alias-decision.py

Sie entscheidet für jeden Empfänger:

SRS
NO_SRS
UNKNOWN

7.1 Typische Fälle

Lokaler Alias:

sender:             root@mx.warenform.de
recipient:          argus@oopen.de
original_recipient: root

Ergebnis:

NO_SRS: Lokaler Alias

Externe PostfixAdmin-Alias-Weiterleitung:

sender:             ckubu@gmx.de
recipient:          ckubu@oopen.de
original_recipient: test@warenform.de

Ergebnis:

SRS: PostfixAdmin-Alias-Kette mit SMTP-Zustellung

Direkte Nachricht:

recipient == original_recipient

Ergebnis:

NO_SRS: Keine Empfaengerumschreibung

Leerer Envelope-Sender:

MAIL FROM:<>

Ergebnis:

NO_SRS

8. Warum original_recipient entscheidend ist

Eine der wichtigsten Schwierigkeiten bei der Implementierung war, dass Postfix/AmaViS Alias-Umschreibungen zu früh durchführen kann.

Für die Entscheidung

test@warenform.de -> ckubu@oopen.de

muss srs-forward.py beide Informationen kennen:

recipient          = ckubu@oopen.de
original_recipient = test@warenform.de

Wenn Postfix die Alias-Umschreibung bereits vor AmaViS endgültig durchgeführt hat, sieht die spätere SRS-Logik dagegen nur:

recipient          = ckubu@oopen.de
original_recipient = ckubu@oopen.de

Dann wäre nicht mehr erkennbar, dass es sich um eine Weiterleitung handelt.

8.1 Lösung

no_address_mappings wurde deshalb auf den eingehenden SMTP-Dienst auf Port 25 gelegt und nicht auf die Reinjection 10025.

Relevant in /etc/postfix/master.cf:

smtp      inet  n       -       y       -       -       smtpd
   -o content_filter=amavisfeed:[127.0.0.1]:10024
   -o smtpd_sasl_auth_enable=no
   -o receive_override_options=no_address_mappings

Dadurch erhält AmaViS zunächst die ursprüngliche Alias-Adresse.

Erst nach der Reinjection auf Port 10025 findet die eigentliche Alias-Expansion statt.

Das war ein zentraler Punkt der funktionierenden Lösung.


9. Haupt-Postfix: main.cf

Die produktiven SRS-Parameter befinden sich in einem eindeutig markierten, automatisch verwaltbaren Block:

# BEGIN OOPEN-SRS-MANAGED
...
# END OOPEN-SRS-MANAGED

Dieser Block darf insbesondere an seinen Markern nicht manuell verändert werden.

Aktive Parameter:

default_transport = srs-forward
srs-forward_destination_recipient_limit = 1
recipient_canonical_maps = socketmap:inet:127.0.0.1:10004:reverse

9.1 default_transport = srs-forward

Nachrichten, die über den normalen Default-Transport zugestellt würden, werden zunächst an die Selektionslogik übergeben.

Das bedeutet nicht, dass jede Nachricht SRS bekommt.

srs-forward.py entscheidet anschließend zwischen:

SRS
NO_SRS

Bei NO_SRS wird die Nachricht mit unverändertem Envelope-Sender an die SRS-Delivery-Instanz übergeben.

9.2 srs-forward_destination_recipient_limit = 1

Diese Einstellung ist notwendig, weil ein Alias mehrere Ziele enthalten kann:

test@warenform.de
  -> chris@antimedia.de
  -> admin@warenform.de
  -> ckubu@oopen.de
  -> test@warenform.de

Einzelne Ziele können lokal sein, andere extern.

Die SRS-Entscheidung muss deshalb pro Empfänger erfolgen.

9.3 recipient_canonical_maps

recipient_canonical_maps = socketmap:inet:127.0.0.1:10004:reverse

Dieser Dienst ist für eingehende SRS-Bounces zuständig.


10. Kein postmulti

Während der Entwicklung wurde zunächst mit Postfix-Multi-Instance-Funktionen gearbeitet.

Diese Lösung wurde bewusst verworfen.

Der Haupt-Postfix verwendet heute wieder die Defaults:

multi_instance_enable = no
multi_instance_wrapper =
multi_instance_directories =

Die SRS-Delivery-Instanz wird stattdessen direkt über systemd betrieben:

postfix@srs-delivery.service

Konfiguration:

/etc/postfix-srs/delivery

Diese Architektur ist auch im SRS-Managed-Block der main.cf dokumentiert.

Spätere Installations- oder Enable-Skripte dürfen für diese Installation nicht wieder postmulti aktivieren.


11. srs-forward in master.cf

Produktiver Transport:

srs-forward unix  -       n       n       -       -       pipe
  flags=Rq null_sender= user=nobody
  argv=/usr/local/sbin/srs-forward.py ${sender} ${recipient} ${original_recipient} ${queue_id} envid=${envid}

Das Skript:

/usr/local/sbin/srs-forward.py

ruft intern auf:

/usr/local/sbin/srs-alias-decision.py

und verwendet für die SRS-Umschreibung:

socketmap:inet:127.0.0.1:10003:forward

Danach wird die Nachricht per SMTP an:

127.0.0.1:10028

übergeben.


12. Separate SRS-Delivery-Postfix-Instanz

Die Instanz läuft unter:

postfix@srs-delivery.service

Konfigurationsverzeichnis:

/etc/postfix-srs/delivery

Queue:

/var/spool/postfix-srs-delivery

Data Directory:

/var/lib/postfix-srs-delivery

Wichtige Parameter:

multi_instance_name = postfix-srs-delivery
multi_instance_enable = no

inet_interfaces = loopback-only

default_transport = smtp

local_transport = error:SRS-LOCAL-DELIVERY-BLOCKED
mailbox_transport = error:SRS-MAILBOX-DELIVERY-BLOCKED
relay_transport = error:SRS-RELAY-DELIVERY-BLOCKED

virtual_transport = srs-lmtp:unix:/var/spool/postfix/private/dovecot-lmtp

transport_maps = btree:/etc/postfix-srs/delivery/transport

Die error:-Transporte sind absichtliche Schutzschranken.

Die SRS-Delivery-Instanz soll nicht versehentlich Zustellpfade übernehmen, die für sie nicht vorgesehen sind.


13. Reinjection auf Port 10028

In /etc/postfix-srs/delivery/master.cf:

127.0.0.1:10028 inet n - y - - smtpd
    -o syslog_name=postfix-srs-delivery/reinject
    -o receive_override_options=no_address_mappings,no_unknown_recipient_checks
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o mynetworks=127.0.0.0/8

Hier landen Nachrichten aus srs-forward.py.

Der Envelope-Sender kann dabei entweder:

unverändert

oder:

SRS0=...@srs.warenform.de

sein.


14. Reverse-SRS für Bounces

SRS löst zwar das SPF-Problem bei der Weiterleitung, erzeugt aber eine neue Anforderung:

Bounces werden an die SRS-Adresse geschickt.

Beispiel:

SRS0=...=gmx.de=ckubu@srs.warenform.de

Diese Adresse muss wieder auf:

ckubu@gmx.de

zurückgeführt werden.

Dazu gibt es zwei Ebenen.

14.1 Reverse-Socketmap Port 10004

Dienst:

srs-reverse-map.service

Programm:

/usr/local/sbin/srs-reverse-map.py

Listener:

127.0.0.1:10004

Upstream:

127.0.0.1:10003

Der Haupt-Postfix verwendet:

recipient_canonical_maps = socketmap:inet:127.0.0.1:10004:reverse

14.2 Reverse-Reinjection Port 10029

Die SRS-Delivery-Instanz besitzt zusätzlich:

127.0.0.1:10029

mit eigener Recipient-Policy:

srs-reverse-policy

Programm:

/usr/local/sbin/srs-reverse-policy.py

und eigenem Cleanup-Dienst:

srs-reverse-cleanup

Dort gilt ausdrücklich:

recipient_canonical_classes=envelope_recipient

Damit wird nur der Envelope-Empfänger zurückgeschrieben, nicht unnötig der sichtbare Nachrichteninhalt.


15. Transport-Map der SRS-Delivery-Instanz

Datei:

/etc/postfix-srs/delivery/transport

Produktiver Eintrag:

srs.warenform.de    srs-reverse-smtp:[127.0.0.1]:10029

Wichtig:

Da in main.cf ausdrücklich

transport_maps = btree:/etc/postfix-srs/delivery/transport

konfiguriert ist, muss die Datenbank auch explizit als btree: erzeugt werden:

postmap btree:/etc/postfix-srs/delivery/transport

Nicht:

postmap /etc/postfix-srs/delivery/transport

Letzteres hatte während der Entwicklung eine inkompatible transport.db erzeugt und zu:

open database .../transport.db: Invalid argument

geführt.


16. Systemd-Abhängigkeiten

16.1 postfix@srs-delivery.service

Drop-in:

/etc/systemd/system/postfix@srs-delivery.service.d/srs.conf

Inhalt:

[Unit]
Wants=postsrsd-srs.service
After=postsrsd-srs.service

16.2 Haupt-Postfix

Drop-in:

/etc/systemd/system/postfix.service.d/srs.conf

Inhalt:

[Unit]
Wants=srs-reverse-map.service postfix@srs-delivery.service
After=srs-reverse-map.service postfix@srs-delivery.service

Damit werden die benötigten SRS-Komponenten auch nach einem Reboot automatisch gestartet.


17. Wichtige Sonderfälle

17.1 Lokaler Alias root

/etc/aliases enthält:

root: argus@oopen.de

Hier liefert Postfix als original_recipient nur:

root

und nicht:

root@mx.warenform.de

Die Decision-Logik muss deshalb einen unqualifizierten lokalen Alias korrekt erkennen.

Ergebnis:

NO_SRS: Lokaler Alias

Das ist wichtig, weil administrative Nachrichten von root ihren Envelope-Sender behalten sollen.

17.2 Null-Sender

Bounces verwenden:

MAIL FROM:<>

Ein Null-Sender wird niemals mit SRS umgeschrieben.

17.3 Sieve-Benachrichtigungen

Durch Dovecot/Sieve neu erzeugte Benachrichtigungen sind keine Weiterleitung der ursprünglichen Nachricht.

Sie werden deshalb korrekt als NO_SRS behandelt.


18. DKIM, SPF und DMARC

Ein wichtiges Ziel war, die originale DKIM-Signatur nicht zu beschädigen.

SRS verändert nur den Envelope-Sender.

Der sichtbare Header:

From: ckubu@gmx.de

und die ursprüngliche GMX-DKIM-Signatur bleiben erhalten.

Im abschließenden End-to-End-Test wurde am Ziel a.mx.oopen.de bestätigt:

Return-Path: <SRS0=...@srs.warenform.de>

SPF:

Received-SPF: Pass
client-ip=83.223.86.76
envelope-from=SRS0=...@srs.warenform.de

DKIM:

dkim=pass
header.d=gmx.de

DMARC:

dmarc=pass
header.from=gmx.de

Damit funktioniert das gewünschte Zusammenspiel:

Envelope-From  -> SRS-Domain
Header-From    -> ursprüngliche Absenderdomain
DKIM           -> ursprüngliche Signatur bleibt gültig
SPF            -> besteht für die SRS-Domain
DMARC          -> besteht über die gültige DKIM-Ausrichtung

19. Abschließender End-to-End-Test

Test:

Absender:  ckubu@gmx.de
Empfänger: test@warenform.de

Alias-Ziel:

ckubu@oopen.de

Journal:

postsrsd:
<ckubu@gmx.de>
forwarded as
<SRS0=...=gmx.de=ckubu@srs.warenform.de>

Danach:

to=<ckubu@oopen.de>
orig_to=<test@warenform.de>
relay=srs-forward
status=sent

SRS-Delivery:

from=<SRS0=...=gmx.de=ckubu@srs.warenform.de>

Final:

to=<ckubu@oopen.de>
relay=a.mx.oopen.de
status=sent

Der empfangende Server bestätigte:

SPF_PASS
DKIM_VALID
DMARC_PASS

20. Reboot-Test

Nach einem vollständigen Reboot wurden folgende Dienste automatisch gestartet:

postsrsd-srs.service           enabled / active
srs-reverse-map.service        enabled / active
postfix@srs-delivery.service   enabled / active
postfix.service                enabled / active

Listener:

25
10003
10004
10028
10029

Forward-/Reverse-Test nach Reboot:

Forward: SRS0=...@srs.warenform.de
Reverse: ckubu@gmx.de

Decision-Tests:

root -> argus@oopen.de
NO_SRS: Lokaler Alias

test@warenform.de -> ckubu@oopen.de
SRS: PostfixAdmin-Alias-Kette mit SMTP-Zustellung

21. Bekannte, nicht SRS-spezifische Warnungen

postfix check endet mit:

check rc=0

Es existieren jedoch bekannte Warnungen:

group or other writable: /etc/postfix/ssl/mailserver.key
group or other writable: /etc/postfix/ssl/mailserver.crt
not owned by root: /var/spool/postfix/etc/resolv.conf

Diese Warnungen sind unabhängig von SRS.

Ebenfalls unabhängig von SRS:

DNSSEC validation may be unavailable

im SMTP-Client der SRS-Delivery-Instanz.

Nach Reboot waren außerdem zeitweise:

networking.service
openipmi.service

als fehlgeschlagen markiert. Auch dies ist kein SRS-Problem; Netzwerk und Maildienste liefen trotzdem.


22. Aufgeräumte produktive Struktur

Produktive SRS-Skripte:

/usr/local/sbin/srs-alias-decision.py
/usr/local/sbin/srs-forward.py
/usr/local/sbin/srs-reverse-map.py
/usr/local/sbin/srs-reverse-policy.py

Produktive SRS-Delivery-Konfiguration:

/etc/postfix-srs/delivery/main.cf
/etc/postfix-srs/delivery/master.cf
/etc/postfix-srs/delivery/transport
/etc/postfix-srs/delivery/transport.db

PostSRSd:

/usr/local/postsrsd
/etc/postsrsd-srs/postsrsd.conf
/etc/postsrsd-srs/secret

Alte Test-/Entwicklungsdateien wurden aus den produktiven Verzeichnissen entfernt bzw. unter /root archiviert.


23. Anforderungen an spätere Installations-/Update-/Enable-/Disable-Skripte

Die spätere Automatisierung soll nicht einfach alte komplette Postfix-Konfigurationsdateien zurückspielen.

Stattdessen soll sie gezielt und reversibel arbeiten.

Installation

Ein Installationsskript soll:

  1. PostSRSd versioniert installieren.
  2. /usr/local/postsrsd auf die aktive Version verlinken.
  3. Konfiguration und Secret anlegen.
  4. die vier produktiven SRS-Skripte installieren.
  5. SRS-Delivery-Postfix-Konfiguration anlegen.
  6. systemd-Units/Drop-ins installieren.
  7. den OOPEN-SRS-MANAGED-Block in main.cf erzeugen.
  8. die benötigten master.cf-Erweiterungen reproduzierbar einfügen.
  9. die notwendige receive_override_options=no_address_mappings-Änderung am SMTP-Eingang sicherstellen.
  10. alle Konfigurationen prüfen.
  11. Dienste starten.
  12. Forward/Reverse- und Decision-Tests durchführen.

Enable

Vor der erstmaligen Aktivierung müssen die vorhandenen Werte der von SRS veränderten Parameter gesichert werden.

Diese Sicherung soll strukturiert erfolgen, nicht durch Zurückspielen einer kompletten alten main.cf.

Disable

Ein Disable-Skript muss:

  1. SRS-spezifische Routing-Parameter entfernen bzw. vorherige Werte wiederherstellen.
  2. master.cf auf den Nicht-SRS-Zustand zurücksetzen.
  3. die SRS-Dienste stoppen/deaktivieren.
  4. die vorhandene Postfix-Konfiguration erhalten.
  5. kein altes vollständiges Backup über die aktuelle Konfiguration kopieren.

Update

Updates von PostSRSd sollen über neue Versionsverzeichnisse erfolgen:

/usr/local/postsrsd-<version>

und erst nach erfolgreicher Prüfung den Symlink:

/usr/local/postsrsd

umschalten.


24. Wichtige Designentscheidungen

Die folgenden Punkte sind bewusst so umgesetzt und sollten nicht ohne erneute technische Prüfung geändert werden:

  • SRS ist selektiv, nicht global.
  • Entscheidungen erfolgen pro Empfänger.
  • original_recipient muss erhalten bleiben.
  • no_address_mappings gehört auf den Eingang vor AmaViS.
  • lokale Aliase erhalten kein SRS.
  • Null-Sender erhalten kein SRS.
  • originale DKIM-Signaturen werden nicht ersetzt.
  • Reverse-SRS ist getrennt abgesichert.
  • die SRS-Delivery-Instanz läuft nicht über postmulti.
  • interne SRS-Dienste lauschen nur auf Loopback.
  • aktive Produktionsnamen enthalten keine test, v2, v3, v4 oder prod-Bezeichnungen.
  • btree:-Maps werden ausdrücklich mit postmap btree:/... erzeugt.
  • der OOPEN-SRS-MANAGED-Block ist eine stabile Schnittstelle für spätere Skripte.

25. Kurztests für den Betrieb

Dienste:

systemctl is-active \
    postsrsd-srs.service \
    srs-reverse-map.service \
    postfix@srs-delivery.service \
    postfix.service

Listener:

ss -ltnp | grep -E ':(25|10003|10004|10028|10029)\b'

Forward:

postmap -q \
    'ckubu@gmx.de' \
    'socketmap:inet:127.0.0.1:10003:forward'

Reverse:

postmap -q \
    'SRS0=...' \
    'socketmap:inet:127.0.0.1:10003:reverse'

Reverse über Haupt-Postfix-Map:

postmap -q \
    'SRS0=...' \
    'socketmap:inet:127.0.0.1:10004:reverse'

Konfiguration:

postfix check

E2E-Journal:

journalctl --since "5 minutes ago" --no-pager | \
    grep -E 'test@warenform\.de|ckubu@oopen\.de|SRS0=|srs-forward|postfix-srs-delivery'

26. Ergebnis

Die produktive Installation erreicht das gewünschte Ziel:

  • echte externe Alias-Weiterleitungen verwenden SRS,
  • lokale oder direkte Zustellungen bleiben unverändert,
  • SPF besteht beim weitergeleiteten Ziel,
  • die ursprüngliche DKIM-Signatur bleibt gültig,
  • DMARC besteht,
  • Bounces können zurückgeführt werden,
  • die komplette SRS-Kette startet automatisch nach einem Reboot,
  • die Konfiguration ist für spätere Automatisierung vorbereitet.