72. pepsi-stage-list-post¶
Modère un message de liste, le transforme et l’éclate vers les membres.
72.1. Rôle¶
pepsi-stage-list-post reçoit un message que pepsi-stage-list a reconnu comme un message destiné à une liste, et lui fait deux choses, dans cet ordre et sous ces noms : une chaîne de règles décide si le message est accepté, retenu, rejeté avec avis ou rejeté sans avis, puis un pipeline de gestionnaires décide comment un message accepté est transformé et remis. La modération et le traitement sont des étapes distinctes aux vocabulaires distincts, et les confondre produit quelque chose qui n’est pas Mailman – les noms de règle, de chaîne, de gestionnaire et de pipeline sont un marqueur de compatibilité que l’API REST rapporte et que les attributs posting_chain et posting_pipeline d’une liste désignent. Référence : pepsi-stage-list-post(1).
Ce sous-système est une réimplémentation de GNU Mailman 3 ; voir Listes de diffusion, qui nomme ce qui a été repris d’amont.
72.2. Modération¶
La chaîne d’envoi par défaut exécute le contrôle d’atténuation DMARC, le contrôle d’absence d’expéditeur, le contournement par mot de passe de modérateur (approved), les règles de boucle et d’adresse interdite, les correspondances d’en-tête du serveur et de la liste, l’indicateur d’urgence, et les règles de modération des membres et des non-membres. Ensuite, huit règles ne font que noter ce qu’elles trouvent — administrivia, destinataire implicite, nombre maximal de destinataires, taille maximale, modération de news, objet vide, résumés et en-tête suspect — et une règle any finale retient le message si l’une d’elles a réagi : dix-huit règles et quatre chaînes terminales (accept, hold, reject, discard).
Avertissement
Un mot de passe de modérateur correct contourne la liste des interdictions. C’est le comportement d’amont et la compatibilité l’exige, mais c’est une arête vive : un en-tête Approved: portant le mot de passe de modérateur de la liste saute directement à accept, par-dessus la liste des interdictions, les règles d’en-tête, l’indicateur d’urgence et les deux règles de modération.
Le mot de passe d’approbation ne survit jamais. Un modérateur peut approuver un message avec le mot de passe dans un en-tête Approved: ou dans la première ligne du corps ; sous quelque forme qu’il soit arrivé, il est retiré avant que le message ne soit archivé ou remis – dans l’en-tête, dans le corps en texte brut et dans l’alternative HTML qu’un client de messagerie a produite à côté. Un mot de passe qui atteint des archives publiques est publié définitivement, et supprimer la copie archivée ne rappelle pas les copies déjà présentes dans cinq mille boîtes. La règle retire ce qu’elle a trouvé, puis le gestionnaire cleanse supprime inconditionnellement les quatre noms d’en-tête (Approve, Approved, X-Approve, X-Approved), ce qui est la seule chose qui élimine un mauvais mot de passe.
72.3. Gestionnaires¶
Le pipeline est celui d’amont, dans l’ordre d’amont : validate-authenticity, mime-delete, tagger, member-recipients, avoid-duplicates, cleanse, cleanse-dkim, cook-headers, subject-prefix, rfc-2369, to-archive, to-digest, to-usenet, after-delivery, acknowledge, dmarc, to-outgoing.
decorate et arc-sign sont absents parce qu’amont les a lui-même commentés dans son pipeline par défaut, et pour les raisons d’amont : toute la décoration se fait à la remise, et décorer à la remise casserait une signature apposée ici. Les deux appartiennent à pepsi-stage-list-deliver et à la queue de signature. to-usenet est une opération vide explicite et journalisée – gateway_to_news reste réglable parce que le retirer changerait la ressource qu’un client REST voit, mais Pepsi ne fait pas passerelle vers NNTP, et une opération vide silencieuse laisserait un exploitant croire que sa passerelle fonctionne.
72.4. En-têtes écrits¶
L’espace de noms X-Mailman-* de Mailman est renommé X-Pepsi-List-* – Version, Rule-Hits, Rule-Misses, Approved-At, Hash-ID, Duplicate, Copy – parce que rien dans Postorius ni HyperKitty n’en lit quoi que ce soit et que le seul lecteur est un humain qui consulte un message retenu. Message-ID-Hash et son ancienne graphie X-Message-ID-Hash gardent leurs noms : ils ne portent le nom d’aucun projet, chaque URL d’archives en est dérivée, et ce sont ceux sur lesquels un tiers a le plus de chances d’avoir bâti quelque chose.
X-Pepsi-List-Hops n’a pas d’équivalent en amont et est le seul que le logiciel relise. C’est le filet contre un cycle d’abonnements passant par deux listes ou plus – la règle loop ne repère qu’un message qui revient à la même liste – et il voyage dans un en-tête parce qu’un enregistrement frère part par SMTP et revient comme du courrier ordinaire, où l’état de l’enregistrement ne survit pas. Un en-tête étant falsifiable, pepsi-ingress retire une copie entrante émise par un expéditeur non authentifié.
72.5. L’éclatement¶
Chaque membre ordinaire dont la remise est activée et qui n’est pas en résumé obtient un enregistrement, inconditionnellement, chacun avec son unique destinataire et son propre expéditeur d’enveloppe VERP <list>-bounces+<local>=<domain>@<host> – c’est ce qui permet au chemin des rejets d’attribuer un échec à exactement un abonnement sans analyser le rejet. Ce qui traverse le réseau est la liste des destinataires, pas le message : en-têtes et corps sont copiés à l’intérieur de la base, un message à cinq mille membres envoie donc un message et cinq mille petits objets JSON à PostgreSQL.
L’éclatement se fait par lots : au plus [pepsi-list] LIST_FANOUT_BATCH enregistrements (256 par défaut) sont matérialisés à la fois, et le message se met en pause entre les lots avec les destinataires restants dans son propre state. Le pic de stockage transitoire vaut donc la taille du lot fois la taille du message, et non l’effectif fois la taille du message — un message à 5 000 membres avec une pièce jointe de 5 Mo culmine vers 1,3 Go au lieu de 25 Go — et pepsi-queue montre un éclatement en cours plutôt qu’une base qui a soudain grossi. La liste des destinataires est figée au premier lot, de sorte qu’un désabonnement survenant au milieu d’un grand envoi ne peut ni sauter ni servir deux fois un voisin, et l’enregistrement source n’est supprimé que par le lot qui achève la liste, de sorte qu’une panne rejoue ce lot et rien de plus.
72.6. Le répondeur automatique de l’adresse d’envoi¶
autorespond_postings est le troisième des trois répondeurs automatiques, sur la même machinerie de délai de grâce que -request et -owner, et celui qu’il vaut la peine de lire : il se déclenche sur l”adresse d’envoi, un réglage erroné répond donc à tous ceux qui écrivent à la liste. Sur une adresse d’envoi, respond_and_discard signifie que le message reçoit une réponse et n’est pas distribué – c’est parfois ce qu’un propriétaire veut (une liste retirée du service qui répond « nous avons déménagé ») et jamais ce qu’il veut par accident, aussi le rejet est-il journalisé en warn et la console du propriétaire nomme-t-elle la valeur sans détour. Deux règles qui ne vont pas de soi : une valeur non reconnue vaut ``none`` (une action de réponse que personne ne sait écrire n’est pas une autorisation d’écrire à tout un effectif), et un message auquel on n’a pas pu répondre est quand même remis – lorsque le répondeur décline, respond_and_discard ne rejette pas, car une liste qui avalerait silencieusement chaque message à cause d’un répondeur serait la pire des défaillances. Toute réponse automatique passe d’abord par le jeu de règles partagé de la RFC 3834 (pepsi_common::autoreply) ; voir pepsi-stage-vacation.
72.7. Configuration¶
[stage-<name>] : PROGRAM = pepsi-stage-list-post, DELIVERY_STAGE (obligatoire, et pepsi-stage-list-deliver doit y tourner), BOUNCE_STAGE (obligatoire – ici, le sens est celui qu’il a partout sauf sur pepsi-stage-list), RESPONSE_STAGE (obligatoire, et ce doit être la queue de signature : l’étape de remise n’accepte que la copie d’un membre issue de l’éclatement, une notification envoyée là ne part donc jamais), REMOVE_DKIM_HEADERS (no par défaut), SITE_HEADER_MATCH_CHAIN (hold par défaut, à l’échelle du serveur, afin qu’un propriétaire de liste ne puisse pas transformer les règles antispam du serveur en un rejet sans avis), et les deux limites de disponibilité SENDER_POSTS_PER_HOUR (30 par défaut : les envois d’un expéditeur vers une même liste au-delà de ce nombre en une heure sont retenus pour le modérateur au lieu d’être envoyés à chaque membre) et MAX_HELD_MESSAGES (1000 par liste par défaut : un envoi qui serait retenu au-delà est rejeté, afin qu’une liste ouverte ne puisse pas servir à remplir le disque ; c’est le nouvel envoi qui est abandonné plutôt que le plus ancien, afin qu’un flot ne puisse pas évincer ce qu’un modérateur n’a pas encore vu). pepsi-setup vérifie les trois cibles et refuse un ``NEXT_STAGE`` : toute sortie de cette étape est terminale.
REMOVE_DKIM_HEADERS est désactivé par défaut parce qu’une liste qui ne réécrit rien laisse une signature valide et que la retirer détruit une preuve réelle ; activez-le pour les listes qui ajoutent un pied de page ou un préfixe d’objet, où la signature survivante échouerait – et une signature qui échoue est pire que pas de signature, car un échec est un indice d’altération et une absence non.
72.8. State¶
Entrées :
state.list.id(écrit par pepsi-stage-list),state.auth(les verdicts SPF/DKIM/DMARC consignés par ingress) etstate.list.pending_rcptsur un éclatement reprenant.Sorties : un descripteur
state.listsur chaque enregistrement frère – l’identifiant du membre, sa langue, son numéro de série de désabonnement et l’indicateur de doublon.Transitions : achèvement (le dernier lot d’un éclatement, une retenue, un rejet sans avis), achèvement avec un clone latéral (la notification d’état de remise d’un rejet avec avis) ou pause (un éclatement dont il reste des destinataires).
72.9. Voir aussi¶
Listes de diffusion, Archives, pepsi-stage-list, pepsi-stage-list-deliver, pepsi-list, pepsi-archive, pepsi-stage-list-post(1).