65. pepsi-whitelist¶
Verwaltet die weiße Absenderliste von Hand.
65.1. Rolle¶
pepsi-whitelist verwaltet die pepsi.whitelist-Tabelle — die benannten Mengen von Absender-Mustern, die eine Nachricht als vertrauenswürdig (Nicht-Spam) markieren. Es verbindet sich über den gemeinsamen [pepsi-postgres]-Abschnitt und liest den optionalen [pepsi-whitelist]-Abschnitt. Dieselbe Tabelle wird von pepsi-stage-check-whitelist gelesen und von pepsi-stage-auto-whitelist automatisch befüllt; dieses Werkzeug erlaubt einem Administrator, Einträge direkt hinzuzufügen, aufzulisten und zu entfernen, und jedem Benutzer, aus der bereits von ihm gesendeten Mail eine eigene weiße Liste zu befüllen. Es ist keine Stage. Referenz: pepsi-whitelist(1).
Anders als die übrigen Operator-Werkzeuge, die als root gestartet schlicht zum Dienstkonto pepsi werden, behält dieses die aufrufende Identität und wechselt nur seine effektiven IDs rund um jeden Datenbankaufruf: import --user und --all-users brauchen root, um das Postfach eines anderen Benutzers mit dessen Zugangsdaten zu durchsuchen.
65.2. Funktionen¶
add — einen Eintrag einfügen: eine
whitelist_name-Gruppe und einenwhitelist_regex(einen erweiterten regulären POSIX-Ausdruck, wörtlich gespeichert — von der Prüf-Stage unabhängig von der Groß-/Kleinschreibung gegen die aus demFrom:-Header geparste addr-spec abgeglichen, nie gegen den rohen Header-Text).--no-dkim-requiredlöscht das datensatzweisedkim_required-Flag (standardmäßig gesetzt);--signature-requiredsetztsignature_required(standardmäßig gelöscht);--sealer DOMAINverlangt zusätzlich, dass die validierte ARC-Kette der Nachricht von dieser Domain gesiegelt wurde. Idempotent: Einen vorhandenen Eintrag(name, match field, regex)erneut hinzuzufügen ist eine No-Op und lässt seine Flags unverändert.add-list / remove-list — dasselbe für eine Mailingliste, die über die
List-Idihrer Beiträge statt über einFrom:-Muster erkannt wird, was jeden Beitrag trifft, gleich wer ihn geschrieben hat.--patternbehandelt das Argument als POSIX-ERE statt als einen exakten Bezeichner. EineList-Idist ein Header, den jeder kopieren kann, kombinieren Sie sie daher mit--sealer.list — Einträge geordnet nach Name, Abgleichsfeld und Regex auflisten, optional auf einen einzelnen
whitelist_namebeschränkt, als Tabelle oder--json.remove — den Eintrag löschen, der durch seinen genauen
whitelist_nameundwhitelist_regexidentifiziert wird.import — eine weiße Liste aus einem Postfach befüllen: Jede Nachricht, deren
From:/Sender:auf einer lokalen Domain liegt und deren Header-Block kein Zustellspur-Feld (Received:,Return-Path:,Delivered-To:,X-Original-To:) trägt, hat der Benutzer gesendet, also sind ihreTo:-/Cc:-/Bcc:-Adressen Leute, mit denen er korrespondiert, und werden als Einträge hinzugefügt. Empfangene Mail wird ignoriert (jeden auf die weiße Liste zu setzen, der Ihnen geschrieben hat, würde den Zweck zunichte machen), ebenso Empfänger auf einer lokalen Domain. Liest mbox, Maildir (einschließlich seiner Unterordner), IMAP (--imap, mit--imap-user/--imap-password-file) und Dovecots eigene Formate (--doveadm,--doveadm-path); es werden nur Header-Blöcke gelesen, nie Nachrichtentexte.--dry-runmeldet, was hinzugefügt würde, und ändert nichts;--own-addressgrenzt ein, was als von Ihnen gesendete Mail zählt;--max-entries/--max-messagesbegrenzen den Lauf; und--user/--all-userslassen root andere Konten befüllen, jedes in seinen eigenen Namensraum.--include-deliveredliest auch empfangene Mail und ist aus dem naheliegenden Grund als unsicher gekennzeichnet: Ein gefälschtesFrom:würde dann die weiße Liste befüllen.import –auto-wildcard — bietet an, die einzelnen Adressen einer Domain durch einen einzigen
*@domain-Eintrag zu ersetzen, sobald dort mindestensWILDCARD_THRESHOLD(10, je Lauf mit--thresholdüberschreibbar) verschiedene Adressen gesehen wurden. Vorschläge werden auf einem Terminal einzeln bestätigt, mit--yesalle angenommen und alle abgelehnt, wenn es kein Terminal gibt — ein unbeaufsichtigter Lauf weitet eine weiße Liste nie von sich aus auf eine ganze Domain aus. Öffentliche E-Mail-Hoster (HOSTERS_FILE,/usr/share/pepsi/hosters.txt, mit--hostersüberschreibbar und mit--no-hostersabschaltbar) werden nie vorgeschlagen, wie viele Korrespondenten ein Benutzer dort auch haben mag: „alle beigmail.com“ ist keine Menge von Leuten, die der Benutzer kennt, und es würde jedem Spammer mit einem kostenlosen Konto eine Umgehung der Bezahlschranke in die Hand geben. Ihre Adressen werden weiterhin einzeln importiert.
65.3. Namensräume der weißen Liste¶
Ein whitelist_name ist entweder global (ein Segment, z. B. correspondents — der des Operators) oder einem Benutzer gehörend: <login>/<segment>, z. B. alice/correspondents. Segmente bestehen aus Buchstaben, Ziffern, _, . und - (ein Punkt, weil alice.smith ein gewöhnlicher Login ist); das Trennzeichen ist /, weil kein POSIX-artiges System es in einem Login-Namen zulässt, -, _, . und ein abschließendes $ dagegen schon. Ein Segment, das nur aus Punkten besteht, wird abgelehnt, sodass .. — und damit jeder relative Pfad — undarstellbar ist.
Gewöhnliche Benutzer dürfen nur ihren eigenen Namensraum lesen und schreiben, geschlüsselt auf den passwd-Login der realen uid (nie $USER oder ein Argument). Das schließt list ein: Die gemeinsame weiße Liste hält fest, mit wem die Organisation korrespondiert, und ein Programm, das jeder Benutzer ausführen darf, darf sie nicht ausgeben. root und die Konten pepsi/pepsi-owner/pepsi-whitelist dürfen alles verwalten.
Damit eine benutzereigene weiße Liste überhaupt etwas bewirkt, muss eine Prüf-Stage sie konsultieren — siehe die Platzhalter {localpart} / {login} im WHITELIST_NAME von pepsi-stage-check-whitelist.
65.4. Privilegienmodell¶
Die gemeinsame Tabelle zu erreichen erfordert eine Datenbank-Identität, die gewöhnliche Benutzer nicht haben; ein Postfach zu lesen erfordert ihres. Daher ist pepsi-whitelist setuid pepsi-whitelist installiert (Modus 4755) und senkt seine effektiven IDs sofort auf den aufrufenden Benutzer ab, um sie nur für die wenigen Millisekunden wieder anzuheben, in denen es mit PostgreSQL spricht (die Peer-Authentifizierung richtet sich nach der effektiven uid).
Dieses Konto ist bewusst nicht das pepsi-Dienstkonto: pepsi-setup gewährt seiner Rolle nur SELECT/INSERT/DELETE auf pepsi.whitelist, sodass die Kompromittierung eines Binärprogramms, das jeder lokale Benutzer ausführen kann, weder die Nachrichten-Warteschlange noch die Signierschlüssel erreicht.
Das Parsen des Postfachs — Megabytes an angreiferkontrolliertem RFC 5322 — geschieht in pepsi-helper-mailbox-scan(1), gestartet mit setresuid, das die reale, effektive und gespeicherte ID auf den Zielbenutzer setzt. Diesem Prozess bleibt in seinen Zugangsdaten keine privilegierte ID, sodass er nicht einmal im Prinzip pepsi-whitelist werden kann; er ist das einzige eigenständige pepsi-helper-*-Programm ganz ohne setuid-Bit. Schließlich wird -c/--config für unprivilegierte Aufrufer abgelehnt, und die Umgebungsvariablen, die die Konfigurationssuche (HOME, XDG_CONFIG_HOME), die ${DATADIR}-Expansion (PATH) und libpq (PG*) steuern, werden entfernt, bevor die Konfiguration gelesen wird.
Anders als pepsi-stage-auto-whitelist (das eine Adresse zu einem verankerten Muster maskiert) speichert add den whitelist_regex genau wie angegeben, sodass der Operator den Abgleich direkt steuert.
65.5. Konfiguration¶
[pepsi-whitelist] (alles optional): HOSTERS_FILE (Standardwert ${DATADIR}/hosters.txt), WILDCARD_THRESHOLD (Standardwert 10), MAX_ENTRIES (die Obergrenze der Datensätze, die ein import hinzufügen darf, Standardwert 5000), SCAN_HELPER (Standardwert pepsi-helper-mailbox-scan) und MAILBOX (das Postfach, aus dem standardmäßig importiert wird), dazu die gemeinsamen Lokalitätsoptionen (LOCAL_DOMAINS, TARGETS, RECIPIENT_DELIMITER), die entscheiden, welche Adressen als unsere zählen. Die Datenbankverbindung stammt aus [pepsi-postgres]. Siehe pepsi-whitelist(1).
65.6. Siehe auch¶
pepsi-stage-check-whitelist, pepsi-stage-auto-whitelist, pepsi-queue, Architektur, pepsi-whitelist(1), pepsi-helper-mailbox-scan(1), pepsi.conf(5).