57. pepsi-stage-milter¶
Eine Nachricht durch einen sendmail-/Postfix-Milter-Mailfilter schicken.
57.1. Rolle¶
pepsi-stage-milter spricht das Milter-Protokoll — die Mailfilter-Schnittstelle, die sendmail eingeführt und Postfix übernommen hat —, sodass die Filter, die ein Operator ohnehin betreibt, hier unverändert funktionieren: opendkim, rspamd, clamav-milter, spamass-milter, milter-greylist. Für jede Nachricht verbindet sich die Stage mit dem Socket des Filters, spielt die Nachricht als SMTP-Sitzung nach, wendet alle vom Filter verlangten Änderungen an und routet die Nachricht nach ihrem Urteil. Referenz: pepsi-stage-milter(1).
Die Stage ist ein Client und nichts weiter. Der Filter ist ein bestehender langlebiger Daemon mit eigenem Paket, eigener systemd-Unit und eigenem Benutzerkonto, genau wie unter sendmail und Postfix — Pepsi startet ihn weder noch sperrt es ihn ein, denn einen Daemon einzusperren ist Sache der Unit dieses Daemons und unter Debian dort bereits erledigt. Die Stage selbst trägt daher keinerlei Privileg: kein setuid-Bit, kein setgid-Bit, keinen Helper.
57.2. Nach der Warteschlange, und was das kostet¶
Warnung
Ein Milter ist als Pre-Queue-Filter konzipiert, und Pepsi führt ihn nach der Warteschlange aus. Das ist die eine Stelle, an der Pepsis Milter-Unterstützung der eines MTA nicht gleichwertig ist.
In einem MTA laufen die Callbacks innerhalb der SMTP-Sitzung, bevor der Server die Nachricht angenommen hat — was es einem Milter erlaubt, einem gefälschten Absender mit 550 zu antworten und überhaupt keinen Bounce zu erzeugen. Pepsis Pipeline läuft vollständig nach dem Einreihen der Nachricht: Wenn irgendeine Stage einen Datensatz sieht, hat pepsi-ingress bereits 250 gesagt. Ein REJECT hier kostet daher einen Bounce an die Adresse, die der Umschlag nannte, und das ist bei gefälschtem Spam ein unschuldiger Dritter.
Ein von Postfix übernommener Greylisting- oder DNSBL-Milter filtert weiterhin korrekt, aber zum Preis von Backscatter. Richten Sie REJECT_STAGE auf eine pepsi-stage-discard statt auf eine pepsi-stage-bounce, wenn das ins Gewicht fällt. Filter, die nur annotieren — ein Signierer oder ein Bewerter, der einen Header für eine spätere pepsi-stage-if zum Verzweigen hinzufügt —, sind nicht betroffen.
57.3. Funktionen¶
Beide Socket-Familien:
SOCKETnimmt sendmails eigeneS=-Grammatik, die auch Postfix akzeptiert —unix:/path,inet:host:port,inet:port@host,inet6:[addr]:port—, sodass ein direkt aus einer der beiden Konfigurationen übernommener Wert unverändert funktioniert.Die Sitzung wird rekonstruiert, nicht erfunden: Die Connect-, Helo- und Mail-Phasen stammen aus dem, was
pepsi-ingressunterstate.originfestgehalten hat — die Peer-Adresse und ihr PTR-Name, derHELO-Name, die TLS-Version und die Chiffre, der Listener (die lokale Adresse, exportiert als{daemon_addr}in der Standard-Connect-Makroliste von Postfixj {daemon_name} {daemon_addr} v _), dieBODY=/SMTPUTF8-Parameter und wie sich die Sitzung authentifiziert hat (die RFC-4954-Makros{auth_type}/{auth_authen}/{auth_author}/{auth_ssf}). Eine lokal injizierte Nachricht (ein Bounce, eine automatische Antwort, einepepsi-sendmail-Submission) wird als Loopback-Sitzung präsentiert, wie sendmail es für lokale Submission tut.Eine Aktions-Positivliste:
ALLOW_ACTIONSentscheidet, welche Änderungen der Filter vornehmen darf. Der Standardwert (addhdrs chgbody chghdrs) deckt jeden Inhaltsfilter ab; den Umschlag umzuschreiben — Empfänger hinzuzufügen oder zu löschen (addrcpt/delrcpt), den Absender zu ändern (chgfrom) — undquarantinemüssen ausdrücklich gewährt werden.allundnonesind Kurzschreibweisen, und ein unbekannter Name ist ein Fehler statt eines stillen Leerlaufs. Ohne Sandbox um den Filter herum ist dies der einzige verfügbare Hebel für den Wirkungsradius.Eine unerfüllte Anforderung wird gemeldet, nicht ignoriert: Ein Filter, der eine Aktion braucht, die nicht angeboten wurde, wird im Journal genannt, und die Nachricht nimmt den
ON_FAILURE-Pfad. Postfix verwirft eine solche Anfrage stillschweigend, und so entdeckt ein Operator sechs Monate später, dass ein signierender Milter nie etwas signiert hat.Die Fehlersemantik von Postfix:
ON_FAILUREspiegeltmilter_default_actionund hat denselben Standardwert (tempfail), ebenso die drei Timeouts (30 s / 30 s / 300 s), sodass ein ausgefallener Filter Mail verzögert, statt sie zu verlieren oder ungefiltert durchzulassen.Ablehnung je Empfänger fächert auf: Ein Empfänger, den der Filter in der
RCPT-Phase abweist, wird auf einen eigenen Geschwisterdatensatz beiREJECT_STAGEabgezogen, und der Rest der Nachricht läuft weiter, wobeistate.dsn.rcptauf jedem entstehenden Datensatz im Gleichschritt mitrcpt_tozerteilt wird. Ein Empfänger, den der Filter nur aufschiebt (4xx), wird auf einen Datensatz abgezogen, der an der Milter-Stage wartet und später erneut gefiltert wird, bisMAX_LIFETIME— dann wird er gebounct, nie abgewiesen.Header-Injektion ist nicht möglich: Ein Header-Wert, der einen Zeilenumbruch enthält, wird neu gefaltet, statt zu einem zweiten Feld werden zu dürfen, und ein ungültiger Feldname wird rundweg abgelehnt.
57.4. Platzierung¶
Eingehend platzieren Sie sie nach pepsi-stage-decrypt, damit der Filter Klartext sieht, und vor den Schranken für weiße Liste und Spam, damit diese auf das verzweigen können, was er markiert hat. Ausgehend platzieren Sie sie unmittelbar vor pepsi-stage-dkim-sign, damit unsere eigene Signatur seine Änderungen abdeckt.
pepsi-setup --wizard erledigt das für Sie für die Filter, die es finden kann. Es durchsucht den Host nach sieben bekannten Daemons, bestätigt jeden durch eine vollständig durchgeführte echte Optionsaushandlung mit seinem Socket und gibt eine Stage je angenommenem Filter aus — geordnet danach, was der Filter tut, mit ALLOW_ACTIONS auf genau das gesetzt, was dieser Filter während der Aushandlung verlangt hat, und mit Ablehnungen, die zu einer erzeugten Discard-Stage geroutet statt gebounct werden. Filter, deren Aufgabe Pepsi bereits erledigt (opendkim, openarc, opendmarc, SPF-Daemons, postsrsd), werden benannt und übersprungen. Siehe den Suchlauf in pepsi-setup(1).
Ein Filter, der den Nachrichtentext umschreibt, bricht zwangsläufig den DKIM-Body-Hash des Urhebers und das ARC-AMS dieser Installation — derselbe unvermeidliche Vorbehalt, den pepsi-stage-vacation für seine Betreffmarkierung trägt. Auf einem Zweig mit lokaler Zustellung ist das harmlos; auf einem Zweig, der die Nachricht weiterleitet, ziehen Sie einen Filter vor, der nur Header hinzufügt.
57.5. Urteile¶
|
|
|
|
|
|
|
pausiert zur Wiederholung, dann |
|
gelöscht, stillschweigend |
|
|
Ein Tempfail, der MAX_LIFETIME überdauert, ist kein Urteil über die Nachricht, daher nimmt er nie REJECT_STAGE (das Mail stillschweigend verwerfen kann): Er geht an BOUNCE_STAGE oder bleibt, wenn es keines gibt, für pepsi-failure-bouncer fehlgeschlagen.
ACCEPT_STAGE existiert, weil Postfix eine Liste von Miltern anwendet, wo Akzeptieren bedeutet „die übrigen überspringen“. Ein Filter je Stage kennt so etwas nicht, sodass ohne die Option Akzeptieren und Fortfahren dasselbe wären; richten Sie sie hinter den Rest einer Kette, um die Unterscheidung wiederherzustellen.
57.6. Konfiguration¶
[stage-<name>]: PROGRAM = pepsi-stage-milter, SOCKET (erforderlich), NEXT_STAGE (erforderlich — ``CONTINUE`` ist das Standardurteil und geht dorthin, und ``ACCEPT_STAGE`` deckt nur ``ACCEPT`` ab), die Routing-Ziele ACCEPT_STAGE/REJECT_STAGE/QUARANTINE_STAGE, BOUNCE_STAGE (worauf REJECT_STAGE zurückfällt), ON_FAILURE (tempfail — der Standardwert —, accept, reject oder discard), ALLOW_ACTIONS, MILTER_NAME (das Makro {daemon_name}; standardmäßig das Etikett der Stage selbst), PROTOCOL_VERSION (2 bis 6, Standardwert 6), die drei Timeouts CONNECT_TIMEOUT/COMMAND_TIMEOUT/CONTENT_TIMEOUT, die gemeinsamen Wiederholungsoptionen (RETRY_INITIAL/RETRY_MAX_INTERVAL/RETRY_FACTOR/ MAX_LIFETIME) und die sieben MACROS_*-Listen (MACROS_CONNECT, MACROS_HELO, MACROS_MAIL, MACROS_RCPT, MACROS_DATA, MACROS_EOH, MACROS_EOM, die jeweils standardmäßig Postfix‘ eigene Liste verwenden, mit dem Sentinel none, um in dieser Phase nichts zu exportieren — ein leerer Wert liest sich als abwesend und wendet den Standardwert erneut an). pepsi-setup verlangt NEXT_STAGE und prüft, dass jedes Routing-Ziel auf eine echte Stage auflöst. Siehe pepsi-stage-milter(1).
57.7. State¶
Eingaben:
state.origin(die festgehaltene Sitzung, dem Filter nachgespielt) undstate.dsn(parallel zu jeder Empfängerumschreibung gehalten).Ausgaben:
state.milter— das Urteil, die Protokollversion, die verstrichene Zeit und die angewandten Änderungen, dazu der Antwortcode des Filters und der Quarantänegrund, wo vorhanden. Eine abgelehnte Nachricht trägt außerdemstate.bounce, mit dem SMTP-Code des Filters, dem erweiterten Status nach RFC 3463 und dem Text in eigenen Feldern.
57.8. Siehe auch¶
pepsi-stage-if, pepsi-stage-discard, pepsi-stage-bounce, pepsi-stage-dkim-sign, Unterstützte Funktionen, pepsi-stage-milter(1).