85.1.24. pepsi-stage-check-whitelist¶
mark trusted senders‘ mail as non-spam
- Handbuchabschnitt:
1
85.1.24.1.1. Name¶
pepsi-stage-check-whitelist - die Stage für die weiße Absenderliste der Pepsi-Pipeline.
85.1.24.1.2. Übersicht¶
pepsi-stage-check-whitelist [GLOBAL-OPTIONS] worker
85.1.24.1.3. Beschreibung¶
Diese Stage hat den Standardwert FUSION = yes: Wenn Stage-Fusion aktiviert ist ([pepsi] ALLOW_FUSION, der Standardwert) und diese Stage in das vereinheitlichte pepsi-Binärprogramm eingefaltet ist, kann ein Vorgänger sie in seinem eigenen Worker-Prozess ausführen, statt sie separat zu dispatchen. Da diese Stage den Header-Block der Nachricht braucht (für List-Id:), kann nur ein Vorgänger sie fusionieren, der die Header oder die ganze Nachricht geladen hat; ein Vorgänger, der allein die Umschlag-Metadaten geladen hat, dispatcht sie normal. Siehe pepsi-dispatch(1) und pepsi.conf(5).
pepsi-stage-check-whitelist ist ein Stage-Programm, das von pepsi-dispatch(1) als persistenter Worker ausgeführt wird, der Nachrichten-IDs von der Standardeingabe liest. Es lädt diesen pepsi.workqueue-Datensatz (und weigert sich zu handeln, sofern sein status nicht running ist), liest seinen [stage-<stage>]-Abschnitt und konsultiert eine benannte weiße Liste vertrauenswürdiger Absender. Passt die Nachricht auf die weiße Liste, hält die Stage state.spam = false fest, sodass ein späteres pepsi-stage-anti-spam(1) sie ohne Zahlung durchlässt. So oder so schaltet die Nachricht dann zu NEXT_STAGE weiter — diese Stage verwirft, bounct oder pausiert eine Nachricht nie.
Die weiße Liste liegt in der pepsi.whitelist-Tabelle, außerhalb des Bandes befüllt vom Operator (pepsi-whitelist(1)), vom ausgehenden pepsi-stage-auto-whitelist(1) oder von einem Benutzer, der sein eigenes Postfach importiert (pepsi-whitelist import). Jeder Datensatz paart einen whitelist_name (ein Gruppen-Etikett) mit einem whitelist_regex, dem match_field, das benennt, wogegen dieser Ausdruck abgeglichen wird, und den Bedingungen, die den Treffer beschränken. Die WHITELIST_NAME-Option der Stage wählt die Gruppe oder Gruppen aus; ob einer ihrer Datensätze passt — unter Beachtung seiner Bedingungen —, entscheidet PostgreSQL in einer einzigen Abfrage. Der whitelist_regex ist ein erweiterter regulärer POSIX-Ausdruck, unabhängig von der Groß-/Kleinschreibung abgeglichen (er wird von PostgreSQLs ~*-Operator ausgewertet, sodass der Dialekt genau POSIX ERE ist). Der Ausdruck ist nicht verankert; verankern Sie ihn mit ^/$, um den gesamten Gegenstand abzugleichen.
Ein Datensatz, dessen Ausdruck sich nicht kompilieren lässt, passt auf nichts; er lässt die Prüfung nicht fehlschlagen. Jedes Werkzeug, das die Tabelle schreibt, validiert einen Ausdruck zuerst, aber ein Datensatz, der trotzdem hineingelangt ist (ein von Hand geschriebenes INSERT), würde PostgreSQL sonst die ganze Abfrage verweigern lassen – und da jeder zutreffende Name in dieser einen Abfrage geprüft wird, würde der fehlerhafte Datensatz eines Benutzers die Mail aller aufhalten, die sich mit ihm einen Whitelist-Namen teilen. Die Stage protokolliert eine Warnung, die die betroffenen Whitelists nennt; pepsi-whitelist list findet den Datensatz.
85.1.24.1.3.1. Was abgeglichen wird¶
match_field wählt den Gegenstand des Abgleichs:
from(der Standardwert): die addr-spec, die aus demFrom:-Header der Nachricht geparst wurde — nicht der rohe Header-Wert, sodass eine auf der weißen Liste stehende Adresse, die in die Anzeigenamen-Position geschrieben wurde, keinen Treffer vortäuschen kann; RFC-5322-Kommentare und faltender Leerraum werden entfernt. Eine Nachricht ohneFrom:-Header passt auf nichts, und ebenso wenig eine, derenFrom:mehr als ein Postfach benennt (das DKIM/DMARC-Urteil, dasdkim_requiredheranzieht, wurde für die erste Adresse berechnet, sodass ein Treffer auf eine andere zwei Fragen über zwei verschiedene Absender entscheiden würde).list-id: der RFC-2919-Listenbezeichner aus demList-Id:-Header der Nachricht, auf das eingeklammerte Token reduziert, getrimmt und kleingeschrieben (List-Id: Rust users <users.rust-lang.org>wird gegenusers.rust-lang.orgabgeglichen). Eine Nachricht ohneList-Id:passt auf nichts.
Ein list-id-Datensatz existiert, weil die Beiträge einer Mailingliste beliebige From:-Adressen tragen. Kein Muster über From: kann sagen „alles, was über diese Liste kam“, sodass ein Abonnent sonst jeden einzelnen Verfasser auf die weiße Liste setzen — oder für jede von der Liste weitergeleitete Nachricht an der Schranke zahlen — müsste. Der Abgleich auf List-Id: sagt es einmal. Da dieser Header unauthentifizierter Text ist, den jeder kopieren kann, paaren Sie einen solchen Datensatz mit sealer_domain (unten).
85.1.24.1.3.2. Mehrere Gruppen und benutzereigene weiße Listen¶
WHITELIST_NAME ist eine kommaseparierte Liste, und ein Eintrag darf eine Vorlage sein, die {localpart} oder {login} enthält und pro Umschlagempfänger expandiert wird:
WHITELIST_NAME = correspondents, {localpart}/correspondents
Das konsultiert die gemeinsame Liste des Operators und die jeweils eigene jedes Empfängers. Der <login>/...-Namensraum ist derjenige, den pepsi-whitelist(1) einen gewöhnlichen Benutzer verwalten und aus seinem Postfach befüllen lässt; das ist es also, was eine benutzereigene weiße Liste wirksam werden lässt — ohne dies ist ein solcher Name nur über eine adressbezogene pepsi.settings-Überschreibung erreichbar (pepsi-settings(1)).
{localpart} expandiert zum Local-Part des Empfängers, wobei eine etwaige Subadresse entfernt wird (alice+lists@ → alice). {login} löst den Empfänger zunächst zu einem passwd-Login auf, was mit dem Namensraum zusammenpasst, wenn die Adresse nicht selbst ein Login ist (first.last@ → alice); es benötigt daher, dass sich der Empfänger lokal auflösen lässt — platzieren Sie die Stage also hinter pepsi-stage-aliases(1), wenn Sie es verwenden. Ein Empfänger, für den sich eine Vorlage nicht expandieren lässt, wird übersprungen, ebenso jede Expansion außerhalb der Namensgrammatik der weißen Liste (Buchstaben, Ziffern, _, . und - je /-getrenntem Segment, und kein Segment, das nur aus Punkten besteht).
Nur ein Empfänger an einer bedienten Domain benennt eine weiße Liste. Beide Platzhalter werden ausschließlich für Empfänger expandiert, deren Domain in LOCAL_DOMAINS steht (standardmäßig [pepsi-ingress] ACCEPTED_DOMAINS); ein Empfänger anderswo wird übersprungen. Das ist wichtig, weil ein Treffer in irgendeiner konsultierten Liste die gesamte Nachricht freigibt: Der Local-Part einer fremden Adresse wird von demjenigen gewählt, der den Umschlag geschrieben hat — ohne diese Prüfung könnte also ein Absender, der bereits auf der weißen Liste eines Benutzers steht, einer Nachricht an jemand anderen ein RCPT TO:<thatuser@anything.invalid> hinzufügen und sie damit freigeben lassen.
Alle zutreffenden Namen werden in einer Abfrage geprüft, und ein Treffer in einem beliebigen davon markiert die Nachricht als Nicht-Spam — das Urteil gilt pro Nachricht, und ein Warteschlangen-Datensatz ist eine Nachricht. Beachten Sie, dass dies das Vertrauen zwischen den bedienten Empfängern einer Nachricht zusammenlegt: Eine Nachricht, die an zwei Ihrer Benutzer gerichtet ist, ist Nicht-Spam, wenn sie auf die Liste eines von beiden passt. Die Lokalitäts-Optionen LOCAL_DOMAINS, TARGETS und RECIPIENT_DELIMITER werden nur gelesen, um diese Platzhalter zu expandieren.
Ein Datensatz kann weiter einschränken, wann er als Treffer zählt:
dkim_required: der Datensatz trifft nur zu, wenn dieFrom:-Domain der Nachricht authentifiziert ist — das heißt, Ingress hatstate.auth.dkim = passvermerkt, oder pepsi-stage-arc(1) hatstate.auth.arc = passvermerkt und DMARC ist ebenfalls bestanden (state.auth.dmarc = pass). Ein ARC-Pass allein belegt nur die Integrität der Kette — ein Absender, der irgendeine einzelne Domain kontrolliert, kann eine gültige Ein-Hop-ARC-Kette über ein gefälschtesFrom:erzeugen — daher wird er nur akzeptiert, wenn DMARC dieFrom:-Ausrichtung bestätigt.signature_required: Der Datensatz passt nur, wennstate.signature_verifiedtrueist, was pepsi-stage-decrypt(1) für eine Nachricht setzt, die eine gegen einen vertrauenswürdigen Schlüssel verifizierte Signatur trägt.sealer_domain: Der Datensatz passt nur, wenn die Nachricht mit einer ARC-Kette ankam, die validiert hat (state.auth.arc = pass), und die benannte ADMD einer der Versiegler dieser Kette ist (state.auth.arc_sealers, festgehalten von pepsi-stage-arc(1)).
sealer_domain ist es, was eine Regel über einen Zwischenträger gefahrlos schreibbar macht, und keine der beiden Hälften genügt allein. List-Id: beweist nichts: Es ist Text, den ein Absender aus einem echten Beitrag kopiert. Eine gültige ARC-Kette beweist ebenfalls nichts — RFC 8617 §8.4 stellt ausdrücklich fest, dass sie kein Vertrauen vermittelt, sondern nur, dass die darin benannten ADMDs diese Bytes wirklich bearbeitet haben, was genau der Grund dafür ist, dass jedermann eine über eine gefälschte Nachricht prägen kann. Den Versiegler zu benennen ist die lokale Richtlinie, die das Protokoll dem Empfänger bewusst überlässt: Der Operator (oder der Benutzer) sagt, welchen Zwischenträger er akzeptiert, und die Kette beweist dann, dass dieser Zwischenträger die Nachricht bearbeitet hat. Es gilt auch für from-Datensätze, wo es ein Absendermuster auf Mail einengt, die über einen bekannten Weiterleiter gelaufen ist.
Beachten Sie, dass die Domains in state.auth.arc_sealers festgehalten werden, ob die Kette validiert hat oder nicht, denn sie sind eine Aufzeichnung dessen, was behauptet wurde; die Stage verwirft sie allesamt, sofern state.auth.arc nicht pass ist, sodass eine gefälschte Kette nie einen sealer_domain-Datensatz erfüllen kann.
Wenn irgendein Datensatz passt (unter seinen Bedingungen), führt die Stage spam: false in das Nachrichten-state zusammen und schaltet weiter. Andernfalls schaltet sie die Nachricht unverändert weiter.
85.1.24.1.4. Konfiguration¶
Die Optionen liegen im eigenen [stage-<name>]-Abschnitt der Stage (PROGRAM = pepsi-stage-check-whitelist): die erforderliche WHITELIST_NAME-Liste der zu konsultierenden Gruppen, ein NEXT_STAGE (ebenfalls erforderlich — die Stage reicht die Nachricht immer weiter, daher weist pepsi-setup einen Abschnitt ohne ein solches zurück) und — nur wenn ein WHITELIST_NAME-Eintrag einen Platzhalter verwendet — die Lokalitäts-Optionen LOCAL_DOMAINS / TARGETS / RECIPIENT_DELIMITER. Sie sind in pepsi.conf(5) dokumentiert; die Datensätze der weißen Liste selbst werden mit pepsi-whitelist(1) verwaltet.
85.1.24.1.5. State¶
Eingaben: state.auth.dkim / state.auth.arc / state.auth.dmarc (für dkim_required-Datensätze), state.signature_verified (für signature_required-Datensätze), das pepsi-stage-decrypt(1) setzt — und nur für sein valid-Signatururteil, sodass eine einwandfreie Signatur mit einem Schlüssel, der nicht verankert werden konnte (valid-untrusted), die Schranke nicht öffnet — sowie state.auth.arc / state.auth.arc_sealers (für sealer_domain-Datensätze), beide von pepsi-stage-arc(1) geschrieben. Der From:-Header stammt aus der from_header-Spalte, nicht aus state; List-Id: wird aus dem Header-Block der Nachricht gelesen, weshalb diese Stage ihn lädt (der Nachrichtentext wird nie geladen).
Ausgaben: Bei einem Treffer führt die Stage spam: false in state zusammen (der Schlüssel, den pepsi-stage-anti-spam(1) liest, um die Zahlungsschranke zu überspringen) und schaltet weiter; bei keinem Treffer bleibt state unberührt. Das State-Layout wird in pepsi.state(7) beschrieben.
Übergänge: schaltet immer zu NEXT_STAGE weiter, ob der Absender auf die weiße Liste passte oder nicht. Ein Treffer wird mit dem reroute-Helfer committet, der spam: false zusammenführt und die Stage im selben einzigen UPDATE weiterbewegt; ein Nichttreffer ist ein einfaches Vorrücken. Es gibt keine Verzweigung; die Stage pausiert, schlägt fehl, bounct oder schließt nie ab — die eigentliche Entscheidung über Zahlung oder Verwerfen bleibt einer späteren Stage überlassen (pepsi-stage-anti-spam(1)).
85.1.24.1.6. Befehle¶
- worker
Läuft als persistenter pepsi-dispatch(1)-Worker, der Nachrichten-IDs von der Standardeingabe liest.
85.1.24.1.7. Globale Optionen¶
- -c FILE, –config FILE
Liest die Konfiguration aus FILE, statt die Standardorte zu durchsuchen.
- -L LOGLEVEL, –log LOGLEVEL
Setzt die Log-Ausführlichkeit (Standardwert
info).- -v, –verbose
Zeigt Log-Meldungen aus allen Quellen.
- -h, –help; -V, –version
Gibt eine Verwendungsübersicht / die Version aus und beendet sich.
85.1.24.1.8. Exit-Status¶
- 0
Die Nachricht wurde verarbeitet (weitergeschaltet, mit oder ohne Treffer in der weißen Liste).
- 1
Ein Fehler ist aufgetreten (Nachricht nicht gefunden oder nicht
running, fehlkonfigurierte Stage — z. B. ein fehlendes WHITELIST_NAME — oder ein Datenbankfehler, einschließlich eines fehlerhaftenwhitelist_regex). Der Grund wird in das Journal geschrieben.
85.1.24.1.9. Beispiele¶
Nachricht 42 gegen die weiße Liste prüfen (sie muss running sein):
echo 42 | pepsi-stage-check-whitelist -c /etc/pepsi/pepsi.conf worker
Ein Pipeline-Abschnitt, der vertrauenswürdige Absender vor der Zahlungsschranke auf die weiße Liste setzt:
[stage-check-whitelist]
PROGRAM = pepsi-stage-check-whitelist
NEXT_STAGE = anti-spam
WHITELIST_NAME = trusted-senders
Die gemeinsame Liste und die jeweils eigene jedes Empfängers konsultieren, sodass eine weiße Liste, die ein Benutzer mit pepsi-whitelist import befüllt hat, beachtet wird:
[stage-check-whitelist]
PROGRAM = pepsi-stage-check-whitelist
NEXT_STAGE = anti-spam
WHITELIST_NAME = trusted-senders, {localpart}/correspondents
Eine Partner-Domain auf die weiße Liste setzen, aber nur, wenn ihre Mail DKIM/ARC-signiert ist:
INSERT INTO pepsi.whitelist (whitelist_name, whitelist_regex, dkim_required)
VALUES ('trusted-senders', '@partner\.example\.org$', TRUE);
dkim_required ist standardmäßig TRUE, wenn ein INSERT es weglässt, wie es pepsi-whitelist add tut; ein Datensatz, der unsignierter Mail vertraut, muss ausdrücklich dkim_required = FALSE angeben.
Eine Mailingliste an der Zahlungsschranke vorbeilassen, gleich wer darin gepostet hat, aber nur, wenn die ADMD der Liste selbst die ARC-Kette der Nachricht versiegelt hat:
pepsi-whitelist add-list alice/lists users.rust-lang.org \
--sealer mail.rust-lang.org
Bewusst allein dem Header vertrauen, für eine Liste, die nicht ARC-versiegelt — dies ist das, wozu ein Angreifer nur ein List-Id: kopieren muss, beschränken Sie es also auf die eigene weiße Liste eines Benutzers statt auf eine gemeinsame:
pepsi-whitelist add-list alice/lists announce.example.org --no-dkim-required
85.1.24.1.10. Siehe auch¶
pepsi-config(1), pepsi-whitelist(1), pepsi-stage-anti-spam(1), pepsi-stage-arc(1), pepsi-settings(1), pepsi-dispatch(1), pepsi.conf(5), pepsi.state(7), pepsi-setup(1)
85.1.24.1.11. Fehler¶
Melden Sie Fehler an den Pepsi-Issue-Tracker.