85.1.12. pepsi-stage-relay-to-maildir

deliver a message to local users‘ Maildirs

Handbuchabschnitt:

1

85.1.12.1.1. Name

pepsi-stage-relay-to-maildir - die Lokale-Zustellung-Stage der Pepsi-Pipeline.

85.1.12.1.2. Übersicht

pepsi-stage-relay-to-maildir [GLOBAL-OPTIONS] worker

85.1.12.1.3. Beschreibung

pepsi-stage-relay-to-maildir ist ein Stage-Programm, das von pepsi-dispatch(1) ausgeführt wird. Es lädt den pepsi.workqueue-Datensatz (und weigert sich zu handeln, sofern sein status nicht running ist), liest seinen [stage-<stage>]-Abschnitt und stellt die Nachricht an lokale Systembenutzer zu, indem es sie in ihr Maildir/new/ schreibt. Empfänger, die nicht lokal sind, werden weitergeroutet.

Für jeden Umschlagempfänger entscheidet die Stage, ob er lokal ist: Seine Domain muss in LOCAL_DOMAINS aufgeführt sein, sein Postfachname (der Local-Part, mit etwaiger Subadresse nach RECIPIENT_DELIMITER entfernt, kleingeschrieben) muss auf einen passwd-Eintrag auflösen, und die uid dieses Benutzers muss durch TARGETS erlaubt sein. Ein lokaler Empfänger wird in sein Maildir zugestellt. Eine passwd-Abfrage, die fehlschlägt (ein LDAP- oder sssd-Backend, das ausgefallen ist), bedeutet nicht „kein solcher Benutzer“: Die gesamte Nachricht wird wiederholt, bevor irgendetwas zugestellt wird (nach einer Minute, verdoppelt bis zu einer Stunde, bis MAX_LIFETIME; siehe pepsi-dispatch(1)), statt lokale Benutzer als unbekannte Postfächer zu bouncen.

Jeder andere Empfänger wird weitergeroutet, und wohin, hängt davon ab, warum er nicht lokal ist:

  • Ein Empfänger auf der Domain eines anderen ist eine Weiterleitung — typischerweise ein Alias, der nach außen expandiert (alice@example.org → alice@example.net). Er geht zu NEXT_STAGE, das ein Relay erreichen sollte. Routen Sie ihn zuerst durch pepsi-stage-srs(1), damit der weitergeleitete Umschlagabsender die SPF-Prüfung des nächsten Hops weiterhin besteht.

  • Ein Empfänger auf einer unserer eigenen LOCAL_DOMAINS, der auf kein erlaubtes Konto auflöst, ist ein unbekanntes Postfach. Er geht zu UNKNOWN_MAILBOX_STAGE, das eine Bounce-Stage erreichen sollte.

Diese auseinanderzuhalten ist wichtig: Ein unbekanntes lokales Postfach an ein Relay zu schicken würde den MX unserer eigenen Domain nachschlagen, genau diesen Host finden und die Nachricht schnurstracks an uns selbst zurückschicken — eine Schleife, die erst endet, wenn der MAX_HOP_COUNT des Relays sie abschneidet, ein Dutzend unnötiger Läufe durch die gesamte Pipeline, nachdem die Nachricht einfach hätte abgelehnt werden sollen.

Eine einzelne Nachricht kann daher teilweise zugestellt werden: Die lokalen Empfänger werden in ihre Maildirs geschrieben und die übrigen Empfänger auf neue pending-Datensätze bei ihrem jeweiligen Ziel aufgeteilt. Zwei Adressen, die auf denselben lokalen Benutzer auflösen, werden nur einmal zugestellt.

Alles, was ein Durchlauf entscheidet, wird nach den Zustellungen in einer Anweisung geschrieben: die nicht lokalen Empfänger abgespalten, die Erfolgs- und Fehlerbenachrichtigungen erzeugt und die Nachricht entweder gelöscht oder auf die noch zu wiederholenden Empfänger reduziert. Die Zustellung erfolgt mindestens einmal: Lässt sich diese Anweisung nicht schreiben (die Datenbank ist nicht erreichbar) oder stirbt der Worker zwischen einem Maildir-Schreibvorgang und ihr, stellt die Wiederholung erneut an die bereits beschriebenen Empfänger zu, und der Benutzer sieht die Nachricht zweimal. Das Maildir-Format bietet keine Möglichkeit, eine Zustellung zurückzunehmen, und ein Duplikat ist einer verlorenen Nachricht vorzuziehen.

Die Zustellung selbst wird vom privilegierten Helper pepsi-helper-maildir-writer(1) durchgeführt: Die Stage startet ihn einmal pro lokalem Empfänger mit der Ziel-uid als Argument und der auf der Standardeingabe geleiteten Nachricht, und der Helper — der setuid-root läuft — fällt auf diesen Benutzer ab, um die Datei zu erstellen. Der dem Helper übergebenen Nachricht sind ein Return-Path:, ein Delivered-To: (Schleifenschutz) und ein Received:-Trace-Header vorangestellt.

Was geschieht, wenn der Helper für einen Empfänger einen Fehler meldet, hängt davon ab, ob eine Wiederholung überhaupt helfen kann — was der Helper in seinem Exit-Status angibt (siehe pepsi-helper-maildir-writer(1)):

Transiente Fehler (Exit 1 — eine volle Platte, ein E/A-Fehler, ein Helper, der noch nicht setuid-root installiert ist oder dessen Wechsel zum Benutzer der Kernel verweigert hat, eine passwd-Abfrage, die fehlschlägt oder keinen Eintrag für die uid findet) werden pausiert und mit einem exponentiellen Backoff wiederholt (von pepsi-dispatch(1) erneut eingereiht, wenn das timeout abläuft) bis MAX_LIFETIME, und erst dann zu BOUNCE_STAGE geroutet: Ein Administrator kann einen solchen Fehler unter der eingereihten Nachricht reparieren, also wartet die Nachricht.

Permanente Fehler (Exit 2 — das Postfach selbst ist unbrauchbar: ein Maildir, das kein Verzeichnis ist, ein Eigentümer oder ein Modus, der den Benutzer aussperrt, ein fehlendes Home-Verzeichnis) werden zu BOUNCE_STAGE geroutet

sofort, und auf ERROR protokolliert, unter Nennung des Empfängers und der Diagnose des Helpers. Keine Wiederholung könnte eine solche Nachricht zustellen, und sie MAX_LIFETIME (Tage) lang eingereiht zu lassen würde ein kaputtes Postfach vor dem Absender und dem Postmaster verbergen. Der Bounce trägt die eigene Diagnose des Helpers, sodass die DSN angibt, was mit dem Konto tatsächlich nicht stimmt.

Über der Quota (Exit 3) ist weder das eine noch das andere und wird von der Standortrichtlinie statt vom Urteil dieser Stage behandelt: siehe unten.

So oder so beachtet die DSN das NOTIFY des Absenders, und eine Nachricht, die selbst ein Bounce ist (Null-Absender), wird nie erneut gebounct. Wenn das globale [pepsi] ORIGINATE_SUCCESS_DSN gesetzt ist und ein Empfänger NOTIFY=SUCCESS angefordert hat, wird bei erfolgreicher lokaler Zustellung eine positive DSN erzeugt.

85.1.12.1.4. Postfach-Quota

Wenn für einen Empfänger eine Quota gilt — aus [pepsi] MAILBOX_QUOTA oder aus dem eigenen pepsi.mailbox_quota-Datensatz dieses Kontos —, entscheidet die Stage je Nachricht und je Empfänger, ob der Helper das Postfach messen muss, bevor er hineinschreibt. Sie tut das anhand der laufenden Schätzung in derselben Tabelle: der letzten Messung plus allem, was Pepsi seither zugestellt hat. Da nichts jemals von dieser Schätzung abzieht (Pepsi erfährt nicht, wenn ein Benutzer Mail über IMAP löscht), ist sie eine obere Schranke — eine Schätzung, die sagt, dass Platz ist, ist also ein Beweis, dass Platz ist, und nur wenn sie sagt, dass das Konto nahe daran sein könnte, läuft der Helper den Baum ab. Ein Postfach weit unter seiner Grenze kostet je Zustellung ein kleines Anhängen.

Ein Helper, der das Postfach als voll meldet (Exit 3), überlässt das Schicksal des Empfängers [pepsi] MAILBOX_OVER_QUOTA:

defer (der Standardwert)

Die Nachricht bleibt eingereiht und wird genau wie ein transienter Fehler wiederholt, bis MAX_LIFETIME, und erst dann gebounct. Ein Kernel-EDQUOT wird genauso behandelt. Das Zurückstellen gibt dem Konto Zeit, Platz zu schaffen — ein kurzzeitig volles Postfach ist weit häufiger als eines, das voll bleibt.

bounce

Der Empfänger wird sofort mit einem RFC-3463-5.2.2 (Postfach voll) zu QUOTA_LIMIT_STAGE geroutet, sodass der Absender es sofort erfährt statt Tage später.

Jede vom Helper gemeldete Messung wird zurückgeschrieben, und das ist es, was pepsi-ingress(1) erlaubt, einen Empfänger über der Quota bei RCPT abzulehnen — der sendende MTA ist dort noch an der Leitung, sagt es also seinem eigenen Benutzer, und Pepsi erzeugt keinen Backscatter. Siehe pepsi-quota(1) für die Sicht des Operators und für den Abgleichslauf, der diese Messungen frisch hält.

Eine Nachricht, die selbst ein Bounce ist, ist nicht ausgenommen: Sie wird wie jede andere abgelehnt und, da ein Bounce nie erneut gebounct wird, mit einer Warnung verworfen. Das ist richtig — die Alternative ist eine Schleife —, aber es ist verschwindende Mail, sodass die Journalzeile, die sie benennt, diejenige ist, die man beobachten sollte.

85.1.12.1.5. Argumente und Unterbefehle

worker

Läuft als persistenter pepsi-dispatch(1)-Worker, der Nachrichten-IDs von der Standardeingabe liest und je eine Statuszeile schreibt. So führt der Dispatcher die Stage im Produktivbetrieb aus.

85.1.12.1.6. Konfiguration

Aus dem [stage-<stage>]-Abschnitt der Nachricht gelesen:

PROGRAM

Muss pepsi-stage-relay-to-maildir sein.

SERVER_NAME (erforderlich)

Der im vorangestellten Received:-Trace-Header festgehaltene Hostname.

TARGETS

Welche lokalen Konten Mail empfangen dürfen, als durch Komma/Leerzeichen getrennte Liste aus: einem Benutzernamen (alice); einer uid (452); einem einschließenden uid-Bereich (1000-1100); oder einem nach oben offenen uid-Bereich (10000-, jede uid auf oder über der Grenze). Ein Token wird nur dann als Bereich gelesen, wenn beide bindestrichgetrennten Teile numerisch sind, sodass ein bindestrichbehafteter Benutzername (pepsi-maildir) eindeutig ist. Wenn nicht gesetzt, ist der Standardwert der reguläre (Nicht-System-)uid-Bereich aus /etc/login.defs (UID_MIN..``UID_MAX``), mit Rückfall auf 1000-60000. Unabhängig von TARGETS verweigert pepsi-helper-maildir-writer(1) jede uid unter UID_MIN, sodass ein Token, das ein Systemkonto benennt (etwa die 452 oben auf einem Host mit UID_MIN 1000), die Zustellung an dieses dauerhaft fehlschlagen lässt; pepsi-setup(1) warnt vor einem solchen Token.

LOCAL_DOMAINS

Durch Leerraum/Komma getrennte Domains, deren Empfänger für die lokale Zustellung in Frage kommen. Standardwert ist [pepsi-ingress] ACCEPTED_DOMAINS.

RECIPIENT_DELIMITER

Der Unteradress-Trenner (alice+lists stellt in das Postfach alice zu). Standardwert ist [pepsi] RECIPIENT_DELIMITER und, in dessen Ermangelung, +; setzen Sie ihn auf none, um das Abstreifen von Unteradressen zu deaktivieren. Setzen Sie bevorzugt die [pepsi]-Variante: pepsi-ingress(1) verwendet diesen Wert, um zu ermitteln, wessen Postfach-Quota ein Empfänger betrifft, und hat keinen Stage-Abschnitt zu lesen. pepsi-setup(1) warnt, wenn eine Stage ihn überschreibt, weil unteradressierte Mail dann der Ablehnung zur RCPT-Zeit entgeht.

HELPER

Der auszuführende privilegierte Zustell-Helper. Standardwert ist pepsi-helper-maildir-writer (auf $PATH aufgelöst); setzen Sie einen absoluten Pfad zum Überschreiben.

NEXT_STAGE

Wohin Empfänger auf anderen Domains weitergeleitet werden. Erforderlich, wann immer eine Nachricht solche Empfänger haben könnte. Der Assistent verdrahtet es mit dem SRS-Relay-Schwanz (srs → der Smarthost, oder srs → direkte Zustellung an den MX im Internet, wenn kein Smarthost konfiguriert ist), sodass ein Alias, der nach außen expandiert, tatsächlich zugestellt wird.

UNKNOWN_MAILBOX_STAGE

Wohin ein Empfänger auf einer unserer eigenen LOCAL_DOMAINS geht, wenn er auf kein erlaubtes Konto auflöst. Standardmäßig NEXT_STAGE, was richtig ist, wenn NEXT_STAGE selbst eine Bounce-Stage oder ein Smarthost ist, dem die Konten der Domain gehören. Setzen Sie es ausdrücklich (der Assistent setzt es auf die Bounce-Stage), wann immer NEXT_STAGE ein Relay erreicht, sonst wird Mail für einen unbekannten lokalen Benutzer an den eigenen MX dieses Hosts zurück-relayt und läuft in einer Schleife bis MAX_HOP_COUNT.

BOUNCE_STAGE

Die DSN-Erzeugungs-Stage, zu der ein Empfänger geroutet wird, wenn sein Postfach dauerhaft unbrauchbar ist, oder sobald ein transienter Fehler über MAX_LIFETIME hinaus wiederholt wurde.

QUOTA_LIMIT_STAGE

Wohin ein Empfänger geht, wenn sein Postfach voll ist und [pepsi] MAILBOX_OVER_QUOTA bounce lautet. Standardwert ist BOUNCE_STAGE. Benannt und benutzt genau wie die gleichnamige Option von pepsi-stage-relay-to-lmtp(1), die das x.2.2 routet, das ein MDA für denselben Zustand meldet: Welchen lokalen Zustellweg ein Standort auch nutzt, der Operator konfiguriert eine Sache.

RETRY_INITIAL, RETRY_MAX_INTERVAL, RETRY_FACTOR, MAX_LIFETIME

Die Wiederholungs-/Aufgabe-Zeitsteuerung für einen transienten fehlgeschlagenen lokalen Schreibvorgang (gleiche Bedeutung wie bei den Relay-Stages); ein dauerhaft unbrauchbares Postfach wird sofort gebounct und wartet nie darauf. Dauern verwenden h/m/s-Einheiten. Standardwerte: 5 m, 2 h, 2 und 120 h.

85.1.12.1.7. Installation und Privilegien

Um den setuid-root-Helper zu erreichen, muss pepsi-stage-relay-to-maildir selbst set-group-id auf die pepsi-maildir-Gruppe installiert sein (Modus 2550, Eigentümer pepsi:pepsi-maildir — ausführbar für den Eigentümer und nicht für alle, denn das setgid-Bit ist die Schranke vor dem setuid-root-Helper; das Ausführungsrecht kann auch nicht von den Gruppenbits kommen, da pepsi bewusst kein Mitglied der Gruppe ist, also kommt es vom Eigentümer). pepsi-dispatch(1) führt die Stage als unprivilegierten pepsi-Dienstbenutzer aus; das setgid-Bit gibt dem Worker eine effektive gid von pepsi-maildir, was genau das ist, was ihm erlaubt, den gruppenbeschränkten pepsi-helper-maildir-writer(1) auszuführen — und nichts anderes auf dem Host erlangt diese Fähigkeit. make install richtet dies ein (sein install-maildir-stage-Schritt), sofern es als root ausgeführt wird und die pepsi-maildir-Gruppe existiert; andernfalls gibt es die genauen, von Hand auszuführenden Befehle aus.

Da das setgid-Bit diese Schranke ist, stellt das Programm dieselbe Regel selbst auf: Sofern der reale Benutzer nicht root oder das Dienstkonto pepsi ist, beendet es sich mit einem Fehler, bevor irgendeine Konfiguration gelesen wird, und — wie die setuid-Krypto-Stages — entfernt es die Umgebungsvariablen, die das Laden der Konfiguration steuern (HOME, XDG_CONFIG_HOME, PG*, TALER_*, PEPSI_*), und legt PATH auf einen sicheren Standardwert fest. Ein Dateimodus ist eine Tatsache der Installation und dies eine Tatsache des Programms; keines von beiden soll für sich allein stehen.

85.1.12.1.8. Siehe auch

pepsi-helper-maildir-writer(1), pepsi-quota(1), pepsi-stage-relay-to-smarthost(1), pepsi-stage-relay-to-internet(1), pepsi-stage-bounce(1), pepsi-dispatch(1), pepsi.conf(5), pepsi.state(7), maildir(5)

85.1.12.1.9. Fehler

Melden Sie Fehler an den Pepsi-Issue-Tracker.