Add Readme files for Sender Rewriting Scheme (SRS).
This commit is contained in:
+465
@@ -0,0 +1,465 @@
|
|||||||
|
# README-SRS.md
|
||||||
|
|
||||||
|
## Selektives SRS auf `mx.warenform.de` – Überblick
|
||||||
|
|
||||||
|
**Stand:** 17.10.2026
|
||||||
|
|
||||||
|
Diese Datei beschreibt bewusst nur, **was** eingerichtet wurde, **warum** es nötig ist und **was im Betrieb zu beachten ist**.
|
||||||
|
|
||||||
|
Für die technische Detaildokumentation siehe:
|
||||||
|
|
||||||
|
```text
|
||||||
|
README-install-SRS.md
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0. Das Grundproblem: Warum Weiterleitungen heute problematisch sein können
|
||||||
|
|
||||||
|
Mailserver wie Gmail, Microsoft, GMX oder Yahoo prüfen eingehende Nachrichten unter anderem mit SPF, DKIM und DMARC.
|
||||||
|
|
||||||
|
Bei einer klassischen Weiterleitung entsteht dabei ein grundsätzliches Problem:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ckubu@gmx.de
|
||||||
|
|
|
||||||
|
v
|
||||||
|
test@warenform.de
|
||||||
|
|
|
||||||
|
v
|
||||||
|
ckubu@gmail.com
|
||||||
|
```
|
||||||
|
|
||||||
|
Die ursprüngliche Nachricht kommt korrekt von einem GMX-Mailserver und besteht dort normalerweise den SPF-Test. Bei der Weiterleitung sendet anschließend aber `mx.warenform.de` die Nachricht weiter, während der Envelope-Absender ohne SRS weiterhin `ckubu@gmx.de` lautet.
|
||||||
|
|
||||||
|
Der Zielserver sieht damit vereinfacht:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Absender-Domain: gmx.de
|
||||||
|
sendender Server: mx.warenform.de
|
||||||
|
```
|
||||||
|
|
||||||
|
und prüft:
|
||||||
|
|
||||||
|
> Darf `mx.warenform.de` E-Mails für `gmx.de` versenden?
|
||||||
|
|
||||||
|
Das ist natürlich nicht der Fall. Die weitergeleitete Nachricht kann deshalb trotz legitimer Herkunft einen SPF-Fehler erhalten.
|
||||||
|
|
||||||
|
Wenn zusätzlich die ursprüngliche DKIM-Signatur durch Änderungen an Headern oder Nachrichteninhalt ungültig wird, kann schließlich auch DMARC fehlschlagen. Bei strengen DMARC-Policies können Provider eine solche Nachricht ablehnen oder als Spam behandeln.
|
||||||
|
|
||||||
|
SRS löst das SPF-Problem, indem nur der SMTP-Envelope-Absender der weitergeleiteten Nachricht umgeschrieben wird:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ckubu@gmx.de
|
||||||
|
```
|
||||||
|
|
||||||
|
wird beispielsweise zu:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SRS0=...=gmx.de=ckubu@srs.warenform.de
|
||||||
|
```
|
||||||
|
|
||||||
|
Der sichtbare Header bleibt dagegen:
|
||||||
|
|
||||||
|
```text
|
||||||
|
From: ckubu@gmx.de
|
||||||
|
```
|
||||||
|
|
||||||
|
Dadurch kann der Zielserver feststellen:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SPF -> PASS für srs.warenform.de
|
||||||
|
DKIM -> PASS für die ursprüngliche Absenderdomain gmx.de
|
||||||
|
DMARC -> PASS über die weiterhin gültige DKIM-Signatur
|
||||||
|
```
|
||||||
|
|
||||||
|
Genau dieses Verhalten wurde bei der hier dokumentierten Installation im End-to-End-Test bestätigt.
|
||||||
|
|
||||||
|
Wichtig ist dabei: SRS soll nicht pauschal auf alle ausgehenden Nachrichten angewendet werden, sondern nur auf echte externe Alias-Weiterleitungen. Daraus ergibt sich die selektive Architektur dieser Installation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Ausgangssituation
|
||||||
|
|
||||||
|
`mx.warenform.de` ist ein produktiver Mailserver mit Postfix, AmaViS, SpamAssassin, ClamAV, OpenDKIM/OpenDMARC und Dovecot.
|
||||||
|
|
||||||
|
Der Server verwaltet auch Mail-Aliase, die teilweise an externe Empfänger weiterleiten.
|
||||||
|
|
||||||
|
Beispiel:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ckubu@gmx.de
|
||||||
|
|
|
||||||
|
v
|
||||||
|
test@warenform.de
|
||||||
|
|
|
||||||
|
+--> lokale Empfänger
|
||||||
|
|
|
||||||
|
+--> ckubu@oopen.de
|
||||||
|
```
|
||||||
|
|
||||||
|
Das Problem:
|
||||||
|
|
||||||
|
Bei einer klassischen Weiterleitung bleibt der ursprüngliche Envelope-Sender erhalten.
|
||||||
|
|
||||||
|
Dann würde `mx.warenform.de` eine Nachricht mit:
|
||||||
|
|
||||||
|
```text
|
||||||
|
MAIL FROM:<ckubu@gmx.de>
|
||||||
|
```
|
||||||
|
|
||||||
|
an einen fremden Server weiterleiten.
|
||||||
|
|
||||||
|
Der fremde Server prüft SPF und sieht dabei:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Absenderdomain: gmx.de
|
||||||
|
sendender Server: mx.warenform.de
|
||||||
|
```
|
||||||
|
|
||||||
|
Da `mx.warenform.de` nicht zum SPF von GMX gehört, kann die legitime weitergeleitete Mail einen SPF-Fehler bekommen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Lösung
|
||||||
|
|
||||||
|
Für echte externe Alias-Weiterleitungen wird der Envelope-Sender per SRS umgeschrieben.
|
||||||
|
|
||||||
|
Aus:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ckubu@gmx.de
|
||||||
|
```
|
||||||
|
|
||||||
|
wird beispielsweise:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SRS0=...=gmx.de=ckubu@srs.warenform.de
|
||||||
|
```
|
||||||
|
|
||||||
|
Dadurch prüft der Zielserver SPF gegen:
|
||||||
|
|
||||||
|
```text
|
||||||
|
srs.warenform.de
|
||||||
|
```
|
||||||
|
|
||||||
|
und damit gegen eine Domain, für die `mx.warenform.de` tatsächlich senden darf.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Warum nicht einfach alle Nachrichten mit SRS umschreiben?
|
||||||
|
|
||||||
|
Weil SRS nur für Weiterleitungen benötigt wird.
|
||||||
|
|
||||||
|
Nicht umgeschrieben werden sollen:
|
||||||
|
|
||||||
|
- normale ausgehende Mails,
|
||||||
|
- lokale Mailbox-Zustellungen,
|
||||||
|
- lokale Aliase,
|
||||||
|
- `root -> argus@oopen.de`,
|
||||||
|
- Dovecot/Sieve-Benachrichtigungen,
|
||||||
|
- Bounces mit leerem Envelope-Sender.
|
||||||
|
|
||||||
|
Deshalb wurde eine **selektive** SRS-Lösung gebaut.
|
||||||
|
|
||||||
|
Sie entscheidet für jeden Empfänger einzeln:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SRS
|
||||||
|
oder
|
||||||
|
NO_SRS
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Warum die Lösung relativ aufwendig ist
|
||||||
|
|
||||||
|
Mehrere technische Probleme mussten gleichzeitig gelöst werden.
|
||||||
|
|
||||||
|
### Alias-Information darf nicht verloren gehen
|
||||||
|
|
||||||
|
Nach der Viren-/Spamprüfung über AmaViS muss noch erkennbar sein:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ursprünglicher Empfänger: test@warenform.de
|
||||||
|
endgültiges Ziel: ckubu@oopen.de
|
||||||
|
```
|
||||||
|
|
||||||
|
Sonst könnte die SRS-Logik nicht erkennen, dass überhaupt eine Weiterleitung stattgefunden hat.
|
||||||
|
|
||||||
|
Deshalb wurde die Reihenfolge der Postfix-Adressumschreibung bewusst angepasst.
|
||||||
|
|
||||||
|
### Ein Alias kann lokale und externe Ziele enthalten
|
||||||
|
|
||||||
|
Zum Beispiel:
|
||||||
|
|
||||||
|
```text
|
||||||
|
test@warenform.de
|
||||||
|
-> lokale Mailbox
|
||||||
|
-> lokale Mailbox
|
||||||
|
-> externe Adresse
|
||||||
|
```
|
||||||
|
|
||||||
|
Nur das externe Ziel braucht SRS.
|
||||||
|
|
||||||
|
Darum wird die Entscheidung pro Empfänger getroffen.
|
||||||
|
|
||||||
|
### Bounces müssen zurückkommen können
|
||||||
|
|
||||||
|
Ein fremder Mailserver sieht als Envelope-Sender eine SRS-Adresse.
|
||||||
|
|
||||||
|
Wenn er einen Bounce erzeugt, muss diese Adresse wieder auf den ursprünglichen Absender zurückgeführt werden.
|
||||||
|
|
||||||
|
Deshalb gibt es zusätzlich einen Reverse-SRS-Pfad.
|
||||||
|
|
||||||
|
### DKIM soll erhalten bleiben
|
||||||
|
|
||||||
|
SRS verändert nur den Envelope-Sender.
|
||||||
|
|
||||||
|
Der sichtbare:
|
||||||
|
|
||||||
|
```text
|
||||||
|
From:
|
||||||
|
```
|
||||||
|
|
||||||
|
Header und die ursprüngliche DKIM-Signatur bleiben erhalten.
|
||||||
|
|
||||||
|
Das ist wichtig, damit DKIM und DMARC weiterhin funktionieren.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Produktive Komponenten
|
||||||
|
|
||||||
|
PostSRSd:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/usr/local/postsrsd -> /usr/local/postsrsd-2.4.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Skripte:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/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
|
||||||
|
```
|
||||||
|
|
||||||
|
Dienste:
|
||||||
|
|
||||||
|
```text
|
||||||
|
postsrsd-srs.service
|
||||||
|
srs-reverse-map.service
|
||||||
|
postfix@srs-delivery.service
|
||||||
|
postfix.service
|
||||||
|
```
|
||||||
|
|
||||||
|
SRS-Delivery-Konfiguration:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/etc/postfix-srs/delivery
|
||||||
|
```
|
||||||
|
|
||||||
|
PostSRSd-Konfiguration:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/etc/postsrsd-srs
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Ports
|
||||||
|
|
||||||
|
```text
|
||||||
|
25 normaler SMTP-Eingang
|
||||||
|
10003 PostSRSd
|
||||||
|
10004 Reverse-SRS-Map
|
||||||
|
10028 SRS-Reinjection
|
||||||
|
10029 Reverse-SRS-Reinjection
|
||||||
|
```
|
||||||
|
|
||||||
|
Die SRS-internen Ports sind nur lokal erreichbar.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Postfix-Hauptkonfiguration
|
||||||
|
|
||||||
|
In `/etc/postfix/main.cf` gibt es einen automatisch verwalteten Bereich:
|
||||||
|
|
||||||
|
```text
|
||||||
|
# BEGIN OOPEN-SRS-MANAGED
|
||||||
|
...
|
||||||
|
# END OOPEN-SRS-MANAGED
|
||||||
|
```
|
||||||
|
|
||||||
|
Dieser Block und insbesondere seine Marker sollen nicht manuell verändert werden.
|
||||||
|
|
||||||
|
Aktive SRS-Einstellungen:
|
||||||
|
|
||||||
|
```text
|
||||||
|
default_transport = srs-forward
|
||||||
|
srs-forward_destination_recipient_limit = 1
|
||||||
|
recipient_canonical_maps = socketmap:inet:127.0.0.1:10004:reverse
|
||||||
|
```
|
||||||
|
|
||||||
|
Die separate SRS-Delivery-Postfix-Instanz wird **nicht mit `postmulti`** verwaltet.
|
||||||
|
|
||||||
|
Sie läuft direkt als:
|
||||||
|
|
||||||
|
```text
|
||||||
|
postfix@srs-delivery.service
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Verifizierter Normalfall
|
||||||
|
|
||||||
|
Test:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ckubu@gmx.de
|
||||||
|
->
|
||||||
|
test@warenform.de
|
||||||
|
->
|
||||||
|
ckubu@oopen.de
|
||||||
|
```
|
||||||
|
|
||||||
|
Am Ziel kam tatsächlich an:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Return-Path:
|
||||||
|
<SRS0=...=gmx.de=ckubu@srs.warenform.de>
|
||||||
|
```
|
||||||
|
|
||||||
|
Der Zielserver meldete:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SPF_PASS
|
||||||
|
DKIM_VALID
|
||||||
|
DMARC_PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
Die originale GMX-DKIM-Signatur blieb also gültig.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Verifizierter lokaler Sonderfall
|
||||||
|
|
||||||
|
Lokaler Alias:
|
||||||
|
|
||||||
|
```text
|
||||||
|
root -> argus@oopen.de
|
||||||
|
```
|
||||||
|
|
||||||
|
Ergebnis:
|
||||||
|
|
||||||
|
```text
|
||||||
|
NO_SRS
|
||||||
|
```
|
||||||
|
|
||||||
|
Der Envelope-Sender bleibt:
|
||||||
|
|
||||||
|
```text
|
||||||
|
root@mx.warenform.de
|
||||||
|
```
|
||||||
|
|
||||||
|
Das ist ausdrücklich so gewünscht.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Reboot-Test
|
||||||
|
|
||||||
|
Nach einem vollständigen Reboot waren automatisch aktiv:
|
||||||
|
|
||||||
|
```text
|
||||||
|
postsrsd-srs.service
|
||||||
|
srs-reverse-map.service
|
||||||
|
postfix@srs-delivery.service
|
||||||
|
postfix.service
|
||||||
|
```
|
||||||
|
|
||||||
|
und die erwarteten Listener:
|
||||||
|
|
||||||
|
```text
|
||||||
|
25
|
||||||
|
10003
|
||||||
|
10004
|
||||||
|
10028
|
||||||
|
10029
|
||||||
|
```
|
||||||
|
|
||||||
|
Forward- und Reverse-SRS funktionierten ebenfalls nach dem Reboot.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Was bei Änderungen besonders zu beachten ist
|
||||||
|
|
||||||
|
Folgende Punkte sind nicht zufällig, sondern Teil des Designs:
|
||||||
|
|
||||||
|
- SRS nur für echte externe Weiterleitungen.
|
||||||
|
- Entscheidung pro Empfänger.
|
||||||
|
- ursprünglicher Alias-Empfänger muss erhalten bleiben.
|
||||||
|
- Reverse-SRS muss erreichbar sein.
|
||||||
|
- keine globale Umschreibung aller Absender.
|
||||||
|
- kein `postmulti`.
|
||||||
|
- interne SRS-Ports nur auf Loopback.
|
||||||
|
- originale DKIM-Signatur möglichst unverändert lassen.
|
||||||
|
- Null-Sender niemals mit SRS umschreiben.
|
||||||
|
- `root` und andere lokale Aliase korrekt erkennen.
|
||||||
|
- `btree:`-Maps mit `postmap btree:/...` erzeugen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Betriebskontrolle
|
||||||
|
|
||||||
|
Dienste:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl is-active \
|
||||||
|
postsrsd-srs.service \
|
||||||
|
srs-reverse-map.service \
|
||||||
|
postfix@srs-delivery.service \
|
||||||
|
postfix.service
|
||||||
|
```
|
||||||
|
|
||||||
|
Ports:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ss -ltnp | grep -E ':(25|10003|10004|10028|10029)\b'
|
||||||
|
```
|
||||||
|
|
||||||
|
Postfix:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
postfix check
|
||||||
|
```
|
||||||
|
|
||||||
|
Forward-Test:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
postmap -q \
|
||||||
|
'ckubu@gmx.de' \
|
||||||
|
'socketmap:inet:127.0.0.1:10003:forward'
|
||||||
|
```
|
||||||
|
|
||||||
|
Journal nach einem Testmail:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
journalctl --since "5 minutes ago" --no-pager | \
|
||||||
|
grep -E 'test@warenform\.de|ckubu@oopen\.de|SRS0=|srs-forward|postfix-srs-delivery'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. Spätere Automatisierung
|
||||||
|
|
||||||
|
Als nächster Schritt sollen Installations-, Update-, Enable- und Disable-Skripte erstellt werden.
|
||||||
|
|
||||||
|
Wichtig dabei:
|
||||||
|
|
||||||
|
- bestehende Postfix-Konfiguration nicht pauschal überschreiben,
|
||||||
|
- vorherige Werte gezielt sichern,
|
||||||
|
- den `OOPEN-SRS-MANAGED`-Block als maschinenlesbare Schnittstelle verwenden,
|
||||||
|
- SRS reproduzierbar aktivieren und deaktivieren,
|
||||||
|
- keine kompletten alten `main.cf`-/`master.cf`-Backups zurückspielen,
|
||||||
|
- PostSRSd versionsweise unter `/usr/local/postsrsd-<version>` verwalten.
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user