17. Mailinglisten¶
17.1. Dieses Subsystem ist eine Neuimplementierung von GNU Mailman 3¶
Vor allem anderen und vor dem ersten Konfigurationsbeispiel muss die Schuld klar benannt werden, denn sie ist groß.
Pepsis Mailinglisten-Subsystem ist eine Neuimplementierung von GNU Mailman 3. Sein Datenmodell, seine Rule/Chain- und Handler/Pipeline-Architektur, seine REST-API, sein E-Mail-Befehlsvokabular und die Namen seiner Benachrichtigungsvorlagen sind der Entwurf des GNU-Mailman-Projekts und nicht unserer. Das GNU-Mailman-Projekt und die Free Software Foundation halten das Urheberrecht am Original. Pepsi existiert, um damit kompatibel zu sein: ein unveränderter mailmanclient, Postorius oder HyperKitty muss diese Implementierung steuern können, und das ist der Abnahmetest, um den der ganze Entwurf herum gebaut ist.
Die Dokumentation von upstream unter <https://docs.mailman3.org> beschreibt Begriffe, die unmittelbar für Pepsis Implementierung gelten, und ist neben diesem Handbuch lesenswert. Wo dieses Kapitel „die hold-Aktion“ oder „die Vorlage list:user:notice:welcome“ sagt, meint es genau das, was Mailman meint.
Einige Dateien von Pepsi haben wir überhaupt nicht geschrieben. Die Benachrichtigungsvorlagen, die Erläuterungen zu den Einstellungen und eine Reihe von Testdaten kommen von GNU Mailman, Postorius und HyperKitty; sie tragen ihre ursprünglichen Urheberrechts- und Lizenzhinweise, sie bleiben unter der GNU General Public License Version 3 oder später, und sie sind in vendor/PEPSI-VENDORING.md aufgeführt. Abschnitt 13 der GPL Version 3 erlaubt es, ein solches Werk mit Pepsis AGPLv3+ zu verbinden; er erlaubt nichts in Richtung einer Umlizenzierung, und Pepsi hat nicht umlizenziert. COPYING sagt dasselbe für jeden, der die Lizenzierung prüft, statt das Handbuch zu lesen.
Warum den Text wiederverwenden, statt eigenen zu schreiben: diese Benachrichtigungen wurden zwei Jahrzehnte lang von echten Listenmitgliedern gelesen, beklagt und ausgebessert, in vierunddreißig Sprachen. Sie von Null an neu zu schreiben wären Wochen Arbeit gewesen, deren bestmögliches Ergebnis darin bestanden hätte, wieder dort anzukommen, wo upstream schon ist, in weniger Sprachen.
17.2. Was eine Liste ist¶
Eine Mailingliste gehört zu einer Domain und wird auf zwei Weisen bezeichnet, die nicht austauschbar sind:
- name
@domain Die Absendeadresse, also die, die Leute eintippen und die im
To:erscheint.- name
.domain Die Listen-ID, mit einem Punkt. Das ist, was die REST-API als Ressourcenbezeichner verwendet.
pepsi-list nimmt überall, wo eine Liste benannt wird, beide Schreibweisen an. Der Unterschied zählt, wenn man direkt mit der API spricht, und er ist der von upstream.
Jede Liste antwortet auf neun Adressen: der Absendeadresse selbst und acht Subadressen – -request, -join, -leave, -subscribe, -unsubscribe, -owner, -bounces und -confirm+token. Anders als GNU Mailman erzeugt Pepsi keine Alias-Datei. Mailman muss für diese neun Adressen jeder Liste Postfix- oder Exim-Alias- und Transportmaps schreiben und den MTA zum Neuladen auffordern; Pepsi routet anhand des Empfängers innerhalb der eigenen Pipeline, es gibt also nichts neu zu erzeugen, nichts neu zu laden und nichts, was aus dem Tritt geraten kann.
17.3. Wie das Subsystem aufgebaut ist¶
Fünf Stages, zwei Bibliotheken und drei Oberflächen. Alles Weitere in diesem Kapitel ist eine Einzelheit an einem davon.
inbound mail
|
v
+------------------+ not a list +----------------------------+
| pepsi-stage-list | -------------> | the rest of your pipeline |
+------------------+ +----------------------------+
| | |
post | -owner | -bounces|
| -join | |
| etc. | |
v v v
+----------+ +---------+ +--------+
| ...-post | | command | | bounce |
+----------+ +---------+ +--------+
| | |
| one row \ | scores, disables,
| per member \ | warns, unsubscribes
v v v
+-------------+ +------------------------+
| ...-deliver | | replies, notices and |
+-------------+ | probes, injected at |
| | RESPONSE/NOTICE_STAGE |
v +------------------------+
pepsi-stage-dkim-sign -> relay -> the member
|
+--> the archive (pepsi-archive), and the digest accumulator
Die fünf Stages. pepsi-stage-list routet; sie ist die einzige, die bei jeder Nachricht läuft. pepsi-stage-list-post moderiert eine Listennachricht und verteilt sie mit einem Datensatz pro Mitglied. pepsi-stage-list-deliver macht aus einem dieser Datensätze die Kopie dieses Mitglieds. pepsi-stage-list-command beantwortet alles, was eine Liste per Post tut und was keine Listennachricht ist. pepsi-stage-list-bounce verbraucht die Fehler, die zurückkommen.
Die zwei Bibliotheken. pepsi-list enthält das Listenmodell, die Attributtabelle, die Moderationsentscheidungen, den Bauteil für Sammelnachrichten und die Importer – und ist das, was die Kommandozeile pepsi-list, die REST-API und die Verwalteroberfläche alle aufrufen, sodass die drei Oberflächen sich nicht darüber uneinig sein können, was eine Einstellung bedeutet. pepsi-archive enthält das Archiv: Speicherung, Threading, Suche, Export, Import und Löschung, hinter der Kommandozeile pepsi-archive.
Die drei Oberflächen, jede an einem eigenen Listener-Flag, sind der Grund, weshalb ein einzelner Hostname keine einzelne Vertrauensgrenze ist:
Oberfläche |
Listener-Flag |
Für wen sie ist |
|---|---|---|
|
|
den Betreiber – |
|
|
Programme – |
|
|
Listenverwalter, Moderatoren und Mitglieder – |
17.3.1. Drei Identitäten und die Wörter dafür¶
Das Kapitel benutzt diese drei Wörter in genau diesen Bedeutungen, und die Oberfläche, die Benachrichtigungen und die Handbuchseiten ebenso.
- Betreiber
Wer die Pepsi-Installation betreibt. Hält ein
pepsi.admin_account, erreicht/uiund/api/v1, bearbeitetpepsi.confund kann mit jeder Liste alles tun. Es gibt keinen Betreiber je Liste.- Listenverwalter (und Moderator)
Wer eine Liste verwaltet. Hält ein
list_user-Konto und einenlist_member-Datensatz mitrole = ownerodermoderator– Befugnis ist eine Abfrage der Mitgliederliste und keine gewährte Berechtigung, was das Modell von Postorius ist und bedeutet, dass einen Verwalter zu ernennen heißt, ihn anzumelden. Ein Verwalter ändert die Einstellungen einer Liste; ein Moderator entscheidet über ihre zurückgehaltenen Nachrichten.- Mitglied
Ein Abonnement, nicht eine Person: eine Adresse auf der Mitgliederliste einer Liste. Wer zwei Adressen auf einer Liste hat, ist zwei Mitglieder, mit zwei Zustellmodi, zwei Bounce-Punkteständen und zwei Abmelde-URIs. Das Wort Abonnent bedeutet in der Prosa dasselbe; Mitglied ist das, was die API, die Oberfläche und dieses Handbuch im Referenzteil verwenden.
Ein Listenverwalter ist kein Pepsi-Betreiber, und die beiden Kontosysteme treffen sich nie; siehe Two account systems unten und Zwei Kontosysteme, und keines gewährt dem anderen etwas für die Tabellen, die Cookies und den einen Hostnamen, der sie verwechseln lässt.
17.3.2. Wie es weitergeht¶
Eine Liste betreiben, ihre Einstellungen und ihre Sammelnachrichten – der Rest dieses Kapitels.
Von GNU Mailman 2.1 oder 3 migrieren – Installation, dann What a migration does not bring.
Pepsi mit den eigenen Clients von upstream steuern – Die REST-API von GNU Mailman 3.
Das Archiv, seine Suche und seine Löschung – Archive.
Die Browseroberflächen – Die Verwaltungskonsole.
Die beteiligten Normen – RFC-Index, wo RFC 2369, RFC 5064, RFC 1153, RFC 3464 und RFC 8058 an einer Stelle gesammelt sind.
17.4. Erste Schritte¶
Eine Domain registrieren, eine Liste anlegen, ihr einen Verwalter geben:
# pepsi-list domain add lists.example.org --base-url https://lists.example.org
added list domain lists.example.org
# pepsi-list list create announce@lists.example.org --style announce-only
created announce@lists.example.org with style legacy-announce
# pepsi-list owner add announce@lists.example.org alice@example.org
alice@example.org is now an owner of announce@lists.example.org
# pepsi-list owner reset-password announce@lists.example.org alice@example.org
password for alice@example.org: xzfkh-9gehq-r7y57-6np8r
(printed rather than mailed: this path has to work when mail is broken)
# pepsi-list check
note: site: archive search: full text and trigram (substring, fuzzy)
1 finding, none fatal
Zwei Warnungen zu diesem Mitschnitt.
Die Domain muss auch eine sein, für die Pepsi Post annimmt. pepsi-list domain add registriert eine Domain für Listen; [pepsi-ingress] ACCEPTED_DOMAINS entscheidet, was der Server bei RCPT annimmt. Eine Liste in einer Domain, die ingress nicht annimmt, wird an der SMTP-Grenze abgewiesen, und nichts in den Protokollen des Listen-Subsystems erwähnt sie, weil die Nachricht es nie erreicht hat.
``members add`` umgeht die Abonnementrichtlinie. Dafür ist ein Kommandozeilenwerkzeug da – eine Mitgliederliste zu migrieren, einen Fehler zu beheben – und es ist auch das eine in diesem Subsystem, das eine Mailingliste in eine Spamkanone verwandeln kann. Der Bestätigungsablauf existiert, damit eine Adresse belegt, dass sie dort sein will; die einzigen Wege, die ihn überspringen, sind dieser Befehl und ein ausdrücklich pre_verified + pre_confirmed gestellter Aufruf eines authentifizierten REST-Clients.
17.5. Stile¶
Ein Stil ist ein benannter Satz von Attributvorgaben, der beim Anlegen einer Liste angewandt wird. GET /3.0/lists/styles meldet drei, die von upstream sind, mit den Namen, Beschreibungen und der Voreinstellung von upstream:
Name |
Auch angenommen als |
Was er ist |
|---|---|---|
|
|
Gewöhnliche Diskussionsliste. Die Voreinstellung. |
|
|
Nur Ankündigungen: Mitglieder dürfen nicht senden. |
|
|
Diskussionsliste mit privatem Archiv; nicht beworben, und Abonnements brauchen sowohl eine Bestätigung als auch einen Moderator. |
Ein weiterer Stil ist Pepsis eigener. Er wird von pepsi-list und von der Verwalteroberfläche angenommen und nicht über REST aufgeführt:
moderatedEine Diskussionsliste, auf der jede Nachricht eines Mitglieds für einen Moderator zurückgehalten wird.
Ein unbekannter Stilname ist ein Fehler. Das create_list von upstream wendet stillschweigend überhaupt keinen Stil an, wenn es einen Namen nicht erkennt, was eine Liste hinterlässt, deren Attribute alle auf dem Spaltenstandard stehen, ohne dass irgendwo etwas gesagt wird; das Bereitstellungsskript eines migrierenden Servers kann auf diese Weise Monate lang scheitern.
17.6. Einstellungen je Liste¶
Eine Liste trägt die 99 Attribute, die GNU Mailman 3.3.10 über REST offenlegt. pepsi-list list show gibt sie aus; --explain ergänzt zu jedem eine Zeile Prosa:
$ pepsi-list list show announce@lists.example.org | head -6
accept_these_nonmembers
acceptable_aliases
admin_immed_notify yes
admin_notify_mchanges no
administrivia yes
advertised yes
Siebzehn von ihnen sind nur lesbar, darunter die acht abgeleiteten Adressen (posting_address, owner_address, bounces_address und die übrigen), die aus der Identität der Liste berechnet und nie gespeichert werden – eine zweite Kopie der Identität einer Liste ist eine zweite Stelle, an der sie falsch sein kann.
Sechs weitere, die *_uri-Vorlagenattribute, existieren nur in API-Version 3.0; Version 3.1 erreicht sie stattdessen über die Vorlagenverwaltung. list show markiert beide Arten.
Warnung
``unsubscription_policy`` regiert den Ein-Klick-Abmeldelink nicht. Wenn [pepsi-list] BASE_URL und UNSUBSCRIBE_SECRET beide gesetzt sind, trägt jede Nachricht, die Pepsi an eine Liste sendet, einen List-Unsubscribe-Post-Header nach RFC 8058, und die „Abmelden“-Schaltfläche eines Mailbox-Anbieters ruft dieses Ziel mit einem einzigen POST auf. Ein gültiges Token entfernt das Mitglied unmittelbar, was auch immer dieses Attribut sagt — moderate und confirm eingeschlossen.
Das ist beabsichtigt und keine Lücke. RFC 8058 erlaubt keine weitere Interaktion: ein Anbieter, der eine Umleitung, eine Bestätigungsseite oder ein „Ihre Anfrage wartet auf Genehmigung“ erhält, kann mit keinem davon etwas anfangen, und viele markieren die Post stattdessen einfach als Spam. Ein Header, der einen Klick verspricht und ihn dann nicht einhält, ist schlimmer als keiner.
Die Richtlinie regiert weiterhin alles, was ein Mensch tut: die -leave-Adresse, das Abmeldeformular auf der Seite der Liste und das DELETE über REST. Muss eine Liste wirklich jeden Abgang moderieren, dann lautet die Antwort, den Header nicht mehr auszugeben — lassen Sie [pepsi-list] UNSUBSCRIBE_SECRET ungesetzt, und es wird überhaupt keine https:-Form ausgegeben — und hinzunehmen, dass die Liste bei jedem prüfenden Mailbox-Anbieter schlechter dasteht.
17.6.1. Drei Einstellungen, nach denen häufiger gefragt wird als nach den anderen sechsundneunzig¶
advertisedOb die Liste im öffentlichen Verzeichnis erscheint. Es ist keine Datenschutzeinstellung: eine nicht beworbene Liste ist weiterhin über ihre eigene URL erreichbar, nimmt weiterhin Nachrichten an, und ihr Archiv wird von
archive_policyregiert und nicht hiervon. Das ist die Bedeutung bei upstream, und sie zu ändern wäre ein Kompatibilitätsbruch. „Nicht beworben“ klingt wie „versteckt“; es bedeutet „nicht im Verzeichnis“.archive_policynever,privateoderpublic.neverspeichert nichts – das Archiv wird nicht geschrieben, es gibt also später nichts öffentlich zu machen.privatespeichert die Nachrichten und weist anonyme Leser ab: die Archiv-URLs antworten, als gäbe es die Liste nicht, denn ein „verboten“ würde bestätigen, dass es sie gibt.publicist öffentlich für das Internet, Suchmaschinen eingeschlossen, und/robots.txtbittet sie, das Archiv zu indizieren und den Suchendpunkt in Ruhe zu lassen.member_roster_visibilityWer sehen darf, wer angemeldet ist:
public,membersodermoderators. Die eigene Seite der Liste zeigt die Mitgliederliste nur beipublic. Dies ist das Attribut, nach dem man greift, wenn jemand „nicht beworben“ sagt und meint „die Abonnenten sollen kein öffentliches Verzeichnis derer sein, die mit uns korrespondieren“.
Alle neunundneunzig liegen auf elf Seiten der Verwalteroberfläche, in der Gruppierung von Postorius, und die Seiten sind aus derselben Deklaration erzeugt, die list show und die REST-API antreibt – ein Wert, den die Oberfläche ablehnt, wird von beiden anderen abgelehnt, mit denselben Worten. Zwei Kontosysteme, und keines gewährt dem anderen etwas hat die Rundschau.
17.6.2. Einstellungen, die Pepsi erfunden hat¶
pepsi-list list set-ext verwaltet einen zweiten, viel kleineren Satz von Einstellungen je Liste, die Pepsi hinzugefügt hat und die die REST-API nie zeigt:
search_trigramoff,shortoderfull– wie weit der Index dieser Liste für Teilzeichenfolgen- und Fuzzy-Suche reicht. Auf die serverweite ObergrenzeSEARCH_TRIGRAMbeschnitten.archive_show_addressesAnonymen Lesern des öffentlichen Archivs dieser Liste die vollständigen E-Mail-Adressen der Absender zeigen. Standardmäßig aus.
archive_retention_daysArchivierte Nachrichten löschen, die älter als dies sind. Fehlt der Wert, gilt der Serverstandard.
Sie sind für REST absichtlich unsichtbar, und das ist keine Stilfrage. Das PUT /3.0/lists/<id>/config von upstream über die ganze Ressource verlangt, dass jedes schreibbare Attribut in der Anfrage vorkommt. Ein gegen Mailman 3.3.10 gebauter Client weiß von nichts, was Pepsi hinzugefügt hat, würde unsere also auslassen und abgewiesen werden – ein erfundenes Attribut würde jedes solche PUT von jedem bestehenden Client brechen. Pepsis eigene Einstellungen liegen daher ganz außerhalb des Attributsatzes, erreichbar von der Kommandozeile und der Verwalteroberfläche und von nirgends, wo ein Mailman-Client sie sehen kann.
17.7. Konfiguration¶
Die Konfiguration je Liste liegt in der Datenbank. pepsi.conf enthält nur das, was der Betreiber besitzt:
[pepsi-list]
SITE_OWNER = postmaster@example.org
BASE_URL = https://lists.example.org
API_USER = restadmin
API_PASS = a long random string
SEARCH_TRIGRAM = short
ARCHIVE_PARTITIONS = 32
NOTICE_STAGE = dkim-sign
Den vollständigen Satz zeigt pepsi.conf(5). Drei davon verdienen hier eine Anmerkung.
NOTICE_STAGE ist die Stelle, an der die periodischen Durchläufe ihre Post ablegen. Die meisten Benachrichtigungen sendet eine Stage, die ein eigenes RESPONSE_STAGE hat; die Bounce-Durchläufe zum Warnen und Entfernen laufen von einem Timer, der keines hat. Ohne diese Option können diese Durchläufe den Zustand eines Mitglieds ändern, es aber nicht benachrichtigen, daher verweigert pepsi-setup eine Konfiguration, die Bounces ohne sie verarbeitet.
ARCHIVE_PARTITIONS wird bei der Installation festgelegt. Das Archiv ist nach der Liste hash-partitioniert, und PostgreSQL kann nicht im Betrieb neu partitionieren: den Modulus zu ändern bedeutet eine neue Tabelle und eine vollständige Kopie jeder archivierten Nachricht. pepsi-setup legt die Partitionen einmal an und weigert sich, sie danach stillschweigend zu ändern, und pepsi-list check meldet eine Konfiguration, die dem widerspricht, was auf der Platte liegt. Wählen Sie einmal. Zweiunddreißig ist bequem weit jenseits des Punktes, an dem etwas anderes zum Engpass wird.
SEARCH_TRIGRAM ist eine Obergrenze und kein Standardwert. Jede Liste wählt off, short oder full bis zu ihr. Den Serverwert zu senken verkleinert daher den Index beim nächsten Neuaufbau und betrifft nicht nur später angelegte Listen.
17.8. Die Teilzeichenfolgensuche ist optional¶
Pepsis Archivsuche benutzt zwei Mechanismen von PostgreSQL, und sie beantworten verschiedene Fragen. Die Volltextsuche – Stammformen, Gewichtung, Auszüge – beantwortet „finde mir den Thread über Zertifikate“. Die Trigrammsuche aus der Erweiterung pg_trgm beantwortet, worin Volltext schlecht ist: eine Teilzeichenfolge, einen Schreibfehler, einen Hostnamen, einen Konfigurationsschlüssel, eine Zeile aus einem Traceback. Auf einer technischen Mailingliste ist das ein großer Teil dessen, wonach Leute tatsächlich suchen, und ein Stammform-Wörterbuch wirft genau dieses Material weg.
pg_trgm liegt in postgresql-contrib, das minimale Container-Abbilder oft auslassen. Ein Server ohne es installiert dennoch und funktioniert dennoch; er hat einfach nur Volltextsuche. pepsi-list check sagt, in welchem Modus der Server ist:
$ pepsi-list check
warning: site: archive search: full text only -- pg_trgm is not installed,
so substring and fuzzy search are unavailable
install postgresql-contrib and re-run pepsi-setup; the archive then
needs `pepsi-archive reindex` to populate trgm_text
17.9. Zwei Kontosysteme¶
Listenverwalter sind keine Pepsi-Betreiber, und die beiden Identitäten treffen sich nie.
pepsi.admin_account und die Konsole /ui gehören dem Serverbetreiber, und das Handbuch sagt, sie an Loopback zu binden und über einen SSH-Tunnel zu erreichen. Listenverwalter können offensichtlich nicht so arbeiten. Die Verwalteroberfläche liegt daher auf dem öffentlichen Listener und leitet ihre Befugnis aus der Mitgliederliste her – ein Datensatz in list_member mit role = owner oder moderator –, was genau das Modell von Postorius ist, bei dem Autorisierung eine Abfrage der Mitgliederliste und keine gewährte Berechtigung ist.
Zwei Kontosysteme, mit Absicht, mit getrennten Tabellen, getrennten Sitzungscookies und getrennten Passwort-Hashes, und keines gewährt dem anderen etwas. Eine Mitgliedssitzung kann einen administrativen Wächter nie befriedigen, in keiner Richtung. Das zählt mehr, als es aussieht: Cookies sind an den Host gebunden und nicht an den Listener, ein Betreiber, der beide Oberflächen unter einem Hostnamen anbietet, verlässt sich daher allein auf die Cookienamen und die Prüfungen des Wächters.
Zwei Kontosysteme, und keines gewährt dem anderen etwas stellt die beiden nebeneinander, benennt die Tabellen und Cookies und sagt, was passiert, wenn Sie beide unter einem Hostnamen anbieten. Ein Verwalter, der sucht, was er tatsächlich tun kann, will die Darstellung der Konsole im selben Kapitel.
17.10. Bounce-Verarbeitung¶
Eine Mailingliste sendet an Adressen, die aufhören zu funktionieren, und irgendwer muss es bemerken. Pepsis Antwort ist die von GNU Mailman 3, Schritt für Schritt, weil jeder Knopf darin über die REST-API sichtbar ist und die Dokumentation eines Servers weiterhin wahr bleiben muss.
Die Gestalt davon: ein Zustellfehler kommt an die -bounces-Adresse der Liste zurück, er wird dem betroffenen Mitglied zugeordnet, der Bounce-Punktestand dieses Mitglieds steigt um höchstens eins pro Kalendertag, und wenn der Punktestand die Schwelle der Liste erreicht, wird seine Zustellung abgeschaltet. Abgeschaltet zu sein ist nicht abgemeldet zu sein – ein abgeschaltetes Mitglied wird in den folgenden Wochen einige Male gewarnt und erst dann entfernt.
17.10.1. Die Zuordnung ist kein Raten¶
Jede Kopie jeder Listennachricht, die Pepsi versendet, trägt einen Umschlagabsender, der das Mitglied benennt, für das sie ist: announce-bounces+alice=example.net@lists.example.org. Ein Bounce dieser Kopie sagt daher, um wen es geht, ohne dass irgendetwas den Bounce selbst lesen muss. Mailman kann das nur, wenn ein Betreiber VERP einschaltet; Pepsis Fan-out erfolgt immer je Empfänger, es ist daher nie aus. Das + ist der [pepsi] RECIPIENT_DELIMITER der Installation — die eine Option, mit der der Fan-out schreibt und an der der Router trennt, sodass die beiden nicht voneinander abweichen können.
Das zählt aus einem praktischen Grund. Die siebzehn heuristischen Bounce-Erkenner von upstream – einer nach einer Norm (RFC 3464) und sechzehn, die einen Hersteller oder einen Betrieb benennen – existieren, weil die Zuordnung über den Umschlag nicht verfügbar war. Pepsi portiert alle siebzehn (sie sind die von flufl.bounce, Apache-2.0, mit ihren eigenen Testdaten), aber sie lesen immer nur einen Bounce, der auf anderem Weg ankam. Wie oft das geschieht, wird in pepsi.event_log unter list.bounce.unrecognized gezählt, und diese Zahl ist die ehrliche Antwort auf „braucht dieser Server mehr Erkenner“.
Ein Bounce, den nichts erkennt, erreicht einen Menschen, mit dem Original wörtlich beigefügt, sofern das forward_unrecognized_bounces_to der Liste nicht discard sagt. Diese Weiterleitung ist beabsichtigt: das Beispiel ist der einzige Weg, auf dem der nächste Erkenner geschrieben wird.
17.10.2. Die neun Attribute¶
Attribut |
Was es entscheidet |
|---|---|
|
Ob diese Liste Bounces überhaupt bewertet. Aus bedeutet, dass sie ungelesen verworfen werden. |
|
Wie viele Bewertungstage ein Mitglied abschalten (Standard 5). |
|
Wie lange ein Punktestand ohne neuen Bounce überlebt (Standard 7 Tage). Danach beginnt der nächste Bounce wieder bei 1. |
|
Wie viele Warnungen ein abgeschaltetes Mitglied vor der Entfernung erhält (Standard 3). Null bedeutet Entfernung ohne jede Warnung. |
|
Wie lange zwischen diesen Warnungen (Standard 7 Tage). |
|
Die Verwalter über jede Erhöhung benachrichtigen (Standard aus – auf einer großen Liste ist das viel Post). |
|
Die Verwalter benachrichtigen, wenn ein Mitglied abgeschaltet wird (Standard an). |
|
Die Verwalter benachrichtigen, wenn ein Mitglied entfernt wird (Standard an). |
|
|
17.10.3. Ein durchgearbeitetes Beispiel¶
Eine Liste mit den Voreinstellungen und eine Adresse, die keine Post mehr annimmt:
Tag 1 |
ein dauerhafter Fehler kommt an. Punktestand 1. Niemand wird benachrichtigt. |
Tag 1 |
vier weitere Fehler am selben Tag. Weiterhin Punktestand 1 – höchstens eine Erhöhung pro Kalendertag. |
Tage 2–4 |
je ein Fehler pro Tag. Punktestand 4. |
Tag 5 |
noch einer. Punktestand 5 = die Schwelle: die Zustellung wird abgeschaltet und die Verwalter werden benachrichtigt, mit der auslösenden Zustellungsstatusbenachrichtigung als Anhang. |
Tag 5 |
das Mitglied erhält eine Warnung, die sagt, dass sein Abonnement abgeschaltet wurde und warum. Gesendete Warnungen: 1. |
Tag 12 |
Warnung 2. |
Tag 19 |
Warnung 3. |
Tag 26 |
die Warnungen sind aufgebraucht und das Intervall ist erneut verstrichen: das Mitglied wird abgemeldet und die Verwalter werden benachrichtigt. |
Eine Adresse, die stirbt, braucht also etwa vier Wochen, um die Liste zu verlassen, und ein schlechter Nachmittag bei einem Anbieter kostet einen Punkt. Ein Bounce-Sturm – tausend Fehler in einer Stunde – kostet ebenfalls genau einen Punkt.
Alles nach „abgeschaltet“ erledigt pepsi-list tasks --once, was ein Timer täglich ausführt. Führt es nichts aus, werden Mitglieder abgeschaltet und dann nie gewarnt und nie entfernt.
17.10.4. Proben¶
[pepsi-list] BOUNCE_PROBES = yes ändert, was das Überschreiten der Schwelle tut: statt das Mitglied abzuschalten, sendet Pepsi ihm eine Nachricht mit einem Einmal-Token im Umschlagabsender und setzt seinen Punktestand auf null. Kommt diese Nachricht als Bounce zurück, benennt das Token es genau und es wird sofort abgeschaltet. Kommt sie nicht zurück, war alles in Ordnung und nichts geschieht.
Standardmäßig ist es aus, wie bei upstream. Der Handel lautet: eine weitere Nachricht an eine Adresse, die vermutlich tot ist, gegen das Nicht-Abschalten von jemandem, dessen Anbieter einen schlechten Nachmittag hatte.
17.10.5. Was eine Migration nicht mitbringt¶
Ein von Mailman importierter Server beginnt bei jedem Mitglied mit Punktestand null. Der eigene Importer von upstream liest die Bounce-Geschichte ebenfalls nicht, das stimmt also überein – es bedeutet aber, dass eine lange tote Adresse nach der Umstellung noch einen Zustellversuch erhält.
17.11. Bekannte Einschränkungen¶
Das Subsystem umfasst das Datenmodell und das Kommandozeilenwerkzeug, den Posting-Pfad mit seiner Moderations-Chain und dem Fan-out je Mitglied, die E-Mail-Befehlsschnittstelle, die Bounce-Verarbeitung, das Archiv und seine Suche (Archive), die REST-API von GNU Mailman 3 (Die REST-API von GNU Mailman 3), die öffentliche Weboberfläche, die Mitgliedskonten und die Verwalteroberfläche (Die Verwaltungskonsole), die Importer (Installation) und beide Sammelnachrichtenformate.
Was es nicht tut: /plugins ist immer leer und es gibt keine Plugin-Schnittstelle, es gibt kein NNTP-Gateway (gateway_to_news ist setzbar und wird als die Leeroperation protokolliert, die es ist), Thread-Verschlagwortung und Kategorien fehlen im Archiv, und eine zurückgewiesene zurückgehaltene Nachricht wird ohne die Zurückweisungsbenachrichtigung verworfen, die upstream sendet. Jedes davon wird noch einmal dort gesagt, wo ein Leser darauf trifft.
17.12. Sammelnachrichten¶
Beide Formate, MIME multipart/digest und die einfache Form nach RFC 1153, denn ein Client kann digest_is_default und mime_is_default_digest zurücklesen und ein Mitglied kann plaintext_digests verlangen – ein Format auszuliefern und das Attribut für das andere anzunehmen wäre genau die stille Art Lüge, deren Verhinderung der Kompatibilitätsvertrag dient.
17.12.1. Wie eine Sammelnachricht anwächst und wie sie gesendet wird¶
Das Anwachsen ist Teil des Zustellens einer Listennachricht: ist digests_enabled an, hängt der Posting-Pfad die Nachricht an einen Datensatz je Liste an, innerhalb derselben Transaktion wie alles andere, was die Nachricht tut. Upstream hängt unter einer Sperre an eine MMDF-Mailboxdatei an; ein Datensatz ist eine der Stellen, an denen eine Datenbank einfach besser ist.
Der Datensatz trägt die Nachrichten selbst und keine Verweise auf ein Archiv. Eine Liste darf durchaus digests_enabled mit archive_policy = never haben – pepsi-list check weist sogar darauf hin, dass Sammelnachrichten dann die einzige Aufzeichnung des Gesendeten sind –, eine aus Archivverweisen gebaute Sammelnachricht wäre also genau für die Listen leer, die sie am dringendsten brauchen. digest_size_threshold begrenzt, wie viel anwächst.
Das Senden hat zwei Auslöser, und upstream hat überhaupt keinen periodischen Läufer: sein maybe_send_digest_now feuert synchron bei einer Listennachricht, sobald die Größenschwelle überschritten ist, und mailman digests --send soll in den Cron des Betreibers wandern. Pepsi behält beide Hälften und setzt die zweite dorthin, wo sie hingehört:
Größe –
digest_size_threshold, in Kilobyte (die Einheit von upstream, die der Spaltenname nicht nennt). Null bedeutet, dass die Größe nie ein Senden auslöst, eine Liste kann also rein periodisch sein.periodisch –
pepsi-list digest periodicvon einem systemd-Timer, unter Beachtung vondigest_send_periodicje Liste. Dieselbe Anordnung wie beipepsi-list tasksund der Grund, weshalb kein langlebiger Sammelnachrichtendienst geschrieben ist.
pepsi-list digest send erzwingt eine Ausgabe unabhängig von der Schwelle, und digest bump erhöht den Band ohne zu senden – die beiden Flags von upstream.
17.12.2. Band- und Ausgabennummer¶
digest_volume_frequency (yearly, monthly, quarterly, weekly, daily) entscheidet, ob der Zeitraum seit digest_last_sent_at fortgeschritten ist:
eine Liste, die noch nie eine Sammelnachricht gesendet hat, behält ihren aktuellen Band und ihre aktuelle Nummer, die erste Ausgabe einer Liste ist also Ausgabe 1 und nicht Ausgabe 2;
ist der Zeitraum fortgeschritten, erhöht sich der Band und die Nummer wird auf 1 zurückgesetzt;
ist er es nicht, erhöht sich die Nummer.
Verglichen wird der Zeitraum und nicht die verstrichene Zeit, und genau das macht die Antwort am 1. eines Monats gleich der am 31.: zwei Nachrichten mit einem Tag Abstand über eine Monatsgrenze hinweg liegen in verschiedenen Monaten, und zwei Nachrichten mit dreißig Tagen Abstand innerhalb eines Monats nicht.
17.12.3. Wie die beiden Formate aussehen¶
Die MIME-Sammelnachricht ist ein multipart/mixed aus fünf Teilen in dieser Reihenfolge: der Kopf (der den Betreff der Ausgabe als seine Content-Description trägt, was eine Sammelnachricht in einem Client lesbar macht, der Teile auflistet), die Kopfzeile, das Inhaltsverzeichnis, ein inneres multipart/digest, dessen Kinder die Originalnachrichten als message/rfc822 sind, und die Fußzeile. Die Teile für Kopf- und Fußzeile entfallen, wenn ihre Vorlage leer ist – was list:member:digest:header ist, bei upstream und hier.
Die Sammelnachricht nach RFC 1153 ist ein flacher text/plain-Text, und jede Anzahl darin ist tragend, weil Leser Sammelnachrichten seit 1990 an diesen Zeilen aufteilen: siebzig Bindestriche einmal nach dem Inhaltsverzeichnis, dreißig vor jeder Nachricht außer der ersten, die Fußzeile als vorgetäuschte zusätzliche Nachricht mit ihrem eigenen Subject: Digest Footer statt als Anhängsel, und ein Schlussgruß, gefolgt von einer Zeile Sternchen derselben Länge.
RFC 1153 ist reiner Text, ein Anhang kann das also nicht überleben. Jeder nicht-textuelle Teil wird daher zu einem Platzhalter, der benennt, was entfernt wurde – sein Dateiname, sein Medientyp und seine Größe –, denn eine einfache Sammelnachricht, die stillschweigend eine Tabelle fallen ließe, würde einen Leser im Glauben lassen, er habe die ganze Nachricht gesehen. Ein multipart/alternative liefert seinen Klartext und sagt nichts über den HTML-Zwilling, denn es wurde nichts weggenommen.
17.12.4. Wer welche erhält¶
Sammelnachrichtenmitglieder mit aktivierter Zustellung teilen sich nach delivery_mode: plaintext_digests erhalten die Ausgabe nach RFC 1153, und mime_digests und ``summary_digests`` erhalten beide die MIME-Ausgabe. Upstream hat kein eigenes Summenformat und behandelt die beiden gleich; eines zu erfinden würde bedeuten, dass ein Mitglied ein Format verlangen kann, das kein anderes Mailman erzeugt.
Jedes Format wird einmal gebaut und je Empfänger verteilt, zu denselben Bedingungen wie jede andere Zustellung – eine Sammelnachricht trägt ebenfalls ein List-Unsubscribe.
17.13. Erklärte Unterschiede zu GNU Mailman 3¶
An einer Stelle gesammelt, weil ein Betreiber, der die beiden Systeme abwägt, es an einer Stelle braucht und ein Supportgespräch etwas braucht, worauf es zeigen kann. Jeder davon ist eine Entscheidung mit einem Grund und kein Zufall.
Unterschied |
Warum |
|---|---|
Ein-Klick-Abmeldung nach RFC 8058 |
Wir geben |
Das Fan-out erfolgt immer je Empfänger |
|
Archivierte Absenderadressen werden verschleiert |
Für anonyme Betrachter, standardmäßig, mit einer Überschreibung je Liste. Keine Sicherheitsmaßnahme: verhindert wird die Masseneinsammlung, die ein öffentliches Archiv zu einer Spamquelle macht. Ein angemeldetes Mitglied sieht die ganze Adresse. |
Eine Löschung hinterlässt einen 90-Tage-Grabstein |
Damit eine erneute Zustellung oder ein erneuter Import eine absichtlich gelöschte Nachricht nicht wiederauferstehen lässt. |
``max_days_to_hold`` wird beachtet |
Es ist bei upstream wirkungslos: ein grep über den ganzen Nicht-Test-Baum von Mailman 3 findet die Spalte, den Stilstandard und den REST-Prüfer und keinen Job, der es liest. Hier verwirft |
Ein unbekannter ``style_name`` ist ein Fehler |
Das |
Vorlagen-URIs werden unter Grenzen abgerufen |
Ein Listenverwalter — nicht der Betreiber — kann eine setzen, daher wird eine |
``archive_rendering_mode = markdown`` wird gespeichert und nicht gerendert |
Das Attribut existiert, weil der Attributsatz der Vertrag ist; beide Werte werden als Text dargestellt. Vom Benutzer geliefertes Markdown in unseren eigenen Origin zu rendern ist genau das, was die Content-Security-Policy der Seiten unmöglich machen soll. |
Nirgends JavaScript |
Auf keiner der beiden Browseroberflächen. Der Preis sind die interaktiven Teile von HyperKitty; der Gewinn ist eine Richtlinie überhaupt ohne |
``X-Mailman-*`` ist zu ``X-Pepsi-List-*`` umbenannt |
Mit einer Zuordnungstabelle, weil procmail- und Sieve-Regeln die echten Kosten eines migrierenden Benutzers sind. |
Kein NNTP-Gateway, keine einsteckbaren Archivierer, keine Plugin-API |
Die sechs NNTP-Attribute bleiben in der Attributmenge und sind wirkungslos, und |
Passwörter, Bounce-Punktestände und Token in Bearbeitung werden nicht migriert |
Der eigene Importer von upstream bringt sie ebenfalls nicht mit. Siehe Von GNU Mailman migrieren. |