85.1.24. pepsi-stage-check-whitelist¶
mark trusted senders” mail as non-spam
- Section du manuel:
1
85.1.24.1.1. Nom¶
pepsi-stage-check-whitelist - l’étape de liste blanche d’expéditeurs du pipeline Pepsi.
85.1.24.1.2. Synopsis¶
pepsi-stage-check-whitelist [GLOBAL-OPTIONS] worker
85.1.24.1.3. Description¶
Cette étape a FUSION = yes par défaut : lorsque la fusion d’étapes est activée ([pepsi] ALLOW_FUSION, la valeur par défaut) et que cette étape est pliée dans le binaire pepsi unifié, un prédécesseur peut l’exécuter dans son propre processus worker plutôt que de la dispatcher séparément. Comme cette étape a besoin du bloc d’en-têtes du message (pour List-Id:), seul un prédécesseur ayant chargé les en-têtes ou le message entier peut la fusionner ; un prédécesseur n’ayant chargé que les métadonnées d’enveloppe la dispatche normalement. Voir pepsi-dispatch(1) et pepsi.conf(5).
pepsi-stage-check-whitelist est un programme d’étape exécuté par pepsi-dispatch(1) comme un worker persistant lisant les identifiants de message sur l’entrée standard. Il charge la ligne pepsi.workqueue correspondante (refusant d’agir si son status n’est pas running), lit sa section [stage-<stage>], et consulte une liste blanche nommée d’expéditeurs de confiance. Si le message correspond à la liste blanche, l’étape note state.spam = false afin qu’une pepsi-stage-anti-spam(1) ultérieure le laisse passer sans paiement. Dans les deux cas, le message avance ensuite vers NEXT_STAGE — cette étape ne supprime, ne fait rebondir ni ne met jamais un message en pause.
La liste blanche réside dans la table pepsi.whitelist, peuplée hors bande par l’opérateur (pepsi-whitelist(1)), par le pepsi-stage-auto-whitelist(1) sortant, ou par un utilisateur important sa propre boîte aux lettres (pepsi-whitelist import). Chaque ligne associe un whitelist_name (un label de groupe) à un whitelist_regex, au match_field qui nomme ce à quoi cette expression est comparée, et aux conditions qui conditionnent la correspondance. L’option WHITELIST_NAME de l’étape sélectionne le groupe ou les groupes ; savoir si l’une quelconque de leurs lignes correspond — sous réserve de ses conditions — est décidé par PostgreSQL en une seule requête. Le whitelist_regex est une expression régulière étendue POSIX, comparée sans tenir compte de la casse (elle est évaluée par l’opérateur ~* de PostgreSQL, donc le dialecte est exactement l’ERE POSIX). L’expression n’est pas ancrée ; ancrez-la avec ^/$ pour correspondre au sujet entier.
Une ligne dont l’expression ne se compile pas ne correspond à rien ; elle ne fait pas échouer la vérification. Chaque outil qui écrit la table valide d’abord une expression, mais une ligne entrée malgré tout (un INSERT écrit à la main) ferait sinon refuser à PostgreSQL la requête entière – et comme chaque nom applicable est vérifié dans cette unique requête, la mauvaise ligne d’un utilisateur retiendrait le courrier de tous ceux qui partagent avec lui un nom de liste blanche. L’étape journalise un avertissement nommant les listes blanches concernées ; pepsi-whitelist list trouve la ligne.
85.1.24.1.3.1. Ce qui est comparé¶
match_field sélectionne le sujet de la comparaison :
from(la valeur par défaut) : l’addr-spec analysée depuis l’en-têteFrom:du message — non la valeur brute de l’en-tête, de sorte qu’une adresse en liste blanche écrite à la place du nom d’affichage ne puisse simuler une correspondance, et les commentaires RFC 5322 ainsi que les espaces de repliement sont retirés. Un message sans en-têteFrom:ne correspond à rien, et il en va de même d’un message dont leFrom:nomme plus d’une boîte aux lettres (le verdict DKIM/DMARC que consultedkim_requireda été calculé pour la première adresse, de sorte que faire correspondre une autre trancherait deux questions portant sur deux expéditeurs différents).list-id: l’identifiant de liste RFC 2919 issu de l’en-têteList-Id:du message, réduit au jeton entre chevrons, rogné et mis en minuscules (List-Id: Rust users <users.rust-lang.org>est comparé àusers.rust-lang.org). Un message sansList-Id:ne correspond à rien.
Une ligne list-id existe parce que les messages d’une liste de diffusion portent des adresses From: arbitraires. Aucun motif sur From: ne peut dire « tout ce qui est passé par cette liste », de sorte qu’un abonné devrait sinon mettre en liste blanche chaque contributeur individuel — ou payer la barrière pour chaque message que la liste relaie. Comparer List-Id: le dit une fois. Comme cet en-tête est un texte non authentifié que n’importe qui peut recopier, associez une telle ligne à sealer_domain (ci-dessous).
85.1.24.1.3.2. Plusieurs groupes, et listes blanches par utilisateur¶
WHITELIST_NAME est une liste séparée par des virgules, et une entrée peut être un modèle contenant {localpart} ou {login}, qui est développé par destinataire d’enveloppe
WHITELIST_NAME = correspondents, {localpart}/correspondents
Cela consulte la liste partagée de l’opérateur et celle propre à chaque destinataire. L’espace de noms <login>/... est celui que pepsi-whitelist(1) permet à un utilisateur ordinaire de gérer et de semer depuis sa boîte aux lettres ; c’est donc ce qui rend une liste blanche par utilisateur effective — sans cela, un tel nom n’est atteignable que par une redéfinition pepsi.settings par adresse (pepsi-settings(1)).
{localpart} se développe en la partie locale du destinataire, toute sous-adresse retirée (alice+lists@ → alice). {login} résout d’abord le destinataire en un login passwd, ce qui est ce qui s’aligne sur l’espace de noms lorsque l’adresse n’est pas elle-même un login (first.last@ → alice) ; cela exige donc que le destinataire se résolve localement, placez par conséquent l’étape après pepsi-stage-aliases(1) lorsque vous l’utilisez. Un destinataire pour lequel un modèle ne peut pas être développé est ignoré, de même que tout développement sortant de la grammaire des noms de liste blanche (lettres, chiffres, _, . et - par segment séparé par /, et aucun segment composé uniquement de points).
Seul un destinataire à un domaine servi nomme une liste blanche. Les deux marqueurs ne sont développés que pour les destinataires dont le domaine figure dans LOCAL_DOMAINS (par défaut [pepsi-ingress] ACCEPTED_DOMAINS) ; un destinataire situé ailleurs est ignoré. Cela compte parce qu’une correspondance dans n’importe quelle liste consultée dédouane le message entier : la partie locale d’une adresse étrangère est choisie par qui a écrit l’enveloppe, de sorte que sans ce test un expéditeur déjà présent dans la liste blanche d’un utilisateur pourrait ajouter RCPT TO:<thatuser@anything.invalid> à un message destiné à quelqu’un d’autre et le faire dédouaner.
Tous les noms applicables sont vérifiés en une seule requête, et une correspondance dans l’un quelconque d’entre eux marque le message comme non-spam — le verdict est par message, et une ligne de la file d’attente est un message. Notez que cela met la confiance en commun entre les destinataires servis d’un même message : un message adressé à deux de vos utilisateurs est non-spam s’il correspond à la liste de l’un ou l’autre. Les options de localité LOCAL_DOMAINS, TARGETS et RECIPIENT_DELIMITER ne sont lues que pour développer ces marqueurs.
Une ligne peut en outre restreindre les cas où elle compte comme une correspondance :
dkim_required: la ligne ne correspond que si le domaineFrom:du message est authentifié — c’est-à-dire qu’ingress a notéstate.auth.dkim = pass, ou que pepsi-stage-arc(1) a notéstate.auth.arc = passet que DMARC a aussi réussi (state.auth.dmarc = pass). Un succès ARC seul n’est qu’une intégrité de chaîne — un expéditeur contrôlant un seul domaine quelconque peut frapper une chaîne ARC valide d’un seul saut sur unFrom:falsifié — il n’est donc accepté que lorsque DMARC confirme l’alignement duFrom:.signature_required: la ligne ne correspond que sistate.signature_verifiedvauttrue, ce que pepsi-stage-decrypt(1) positionne pour un message portant une signature qu’il a vérifiée contre une clé de confiance.sealer_domain: la ligne ne correspond que si le message est arrivé porteur d’une chaîne ARC qui a validé (state.auth.arc = pass) et si l’ADMD nommé est l’un des scelleurs de cette chaîne (state.auth.arc_sealers, noté par pepsi-stage-arc(1)).
sealer_domain est ce qui rend sûre l’écriture d’une règle portant sur un intermédiaire, et aucune des deux moitiés ne suffit seule. List-Id: ne prouve rien : c’est du texte qu’un expéditeur recopie d’un message authentique. Une chaîne ARC valide ne prouve rien non plus — la RFC 8617 §8.4 est explicite : elle ne transmet aucune confiance, seulement que les ADMD qui y sont nommés ont réellement manipulé ces octets, ce qui est exactement pourquoi n’importe qui peut en frapper une sur un message falsifié. Nommer le scelleur est la politique locale que le protocole laisse délibérément au destinataire : l’opérateur (ou l’utilisateur) énonce quel intermédiaire il accepte, et la chaîne prouve alors que cet intermédiaire a manipulé le message. Cela vaut aussi pour les lignes from, où cela restreint un motif d’expéditeur au courrier relayé par un redirecteur connu.
Notez que les domaines de state.auth.arc_sealers sont notés que la chaîne ait validé ou non, car ils sont la trace de ce qui a été prétendu ; l’étape les écarte tous à moins que state.auth.arc ne vaille pass, de sorte qu’une chaîne falsifiée ne peut jamais satisfaire une ligne sealer_domain.
Si une ligne correspond (sous réserve de ses conditions), l’étape fusionne spam: false dans le state du message et avance. Sinon elle fait avancer le message inchangé.
85.1.24.1.4. Configuration¶
Les options résident dans la propre section [stage-<name>] de l’étape (PROGRAM = pepsi-stage-check-whitelist) : la liste WHITELIST_NAME obligatoire des groupes à consulter, un NEXT_STAGE (obligatoire lui aussi — l’étape passe toujours le message plus loin, de sorte que pepsi-setup rejette une section qui n’en a pas), et — uniquement lorsqu’une entrée de WHITELIST_NAME utilise un marqueur — les options de localité LOCAL_DOMAINS / TARGETS / RECIPIENT_DELIMITER. Elles sont documentées dans pepsi.conf(5) ; les lignes de liste blanche elles-mêmes sont gérées avec pepsi-whitelist(1).
85.1.24.1.5. État¶
Entrées : state.auth.dkim / state.auth.arc / state.auth.dmarc (pour les lignes dkim_required), state.signature_verified (pour les lignes signature_required), que pepsi-stage-decrypt(1) positionne — et seulement pour son verdict de signature valid, de sorte qu’une signature saine faite avec une clé qui n’a pu être ancrée (valid-untrusted) n’ouvre pas la barrière — ainsi que state.auth.arc / state.auth.arc_sealers (pour les lignes sealer_domain), tous deux écrits par pepsi-stage-arc(1). L’en-tête From: provient de la colonne from_header, non de state ; List-Id: est lu dans le bloc d’en-têtes du message, raison pour laquelle cette étape le charge (le corps n’est jamais chargé).
Sorties : en cas de correspondance, l’étape fusionne spam: false dans state (la clé que pepsi-stage-anti-spam(1) lit pour sauter la barrière de paiement) et avance ; sans correspondance, state est laissé intact. La disposition de l’état est décrite dans pepsi.state(7).
Transitions : avance toujours vers NEXT_STAGE, que l’expéditeur ait ou non correspondu à la liste blanche. Une correspondance est validée avec le helper reroute, qui fusionne spam: false et déplace l’étape dans le même et unique UPDATE ; une non-correspondance est une simple avancée. Il n’y a pas de branche ; l’étape ne met jamais en pause, n’échoue, ne réachemine ni ne termine — la décision réelle de paiement/abandon est laissée à une étape ultérieure (pepsi-stage-anti-spam(1)).
85.1.24.1.6. Commandes¶
- worker
Exécuté comme un worker persistant de pepsi-dispatch(1), lisant les identifiants de message sur l’entrée standard.
85.1.24.1.7. Options globales¶
- -c FILE, –config FILE
Lit la configuration depuis FILE au lieu de parcourir les emplacements par défaut.
- -L LOGLEVEL, –log LOGLEVEL
Règle la verbosité de journalisation (par défaut
info).- -v, –verbose
Affiche les messages de journal de toutes les sources.
- -h, –help ; -V, –version
Affiche un résumé d’utilisation / la version et quitte.
85.1.24.1.8. Code de sortie¶
- 0
Le message a été traité (avancé, avec ou sans correspondance de liste blanche).
- 1
Une erreur s’est produite (message introuvable ou non
running, étape mal configurée — par exemple un WHITELIST_NAME manquant — ou une erreur de base de données, y compris unwhitelist_regexmalformé). La raison est écrite dans le journal.
85.1.24.1.9. Exemples¶
Vérifier le message 42 par rapport à la liste blanche (il doit être running)
echo 42 | pepsi-stage-check-whitelist -c /etc/pepsi/pepsi.conf worker
Une section de pipeline qui met en liste blanche les expéditeurs de confiance avant la barrière de paiement
[stage-check-whitelist]
PROGRAM = pepsi-stage-check-whitelist
NEXT_STAGE = anti-spam
WHITELIST_NAME = trusted-senders
Consulter la liste partagée ainsi que celle propre à chaque destinataire, afin qu’une liste blanche qu’un utilisateur a semée avec pepsi-whitelist import soit honorée
[stage-check-whitelist]
PROGRAM = pepsi-stage-check-whitelist
NEXT_STAGE = anti-spam
WHITELIST_NAME = trusted-senders, {localpart}/correspondents
Mettre en liste blanche un domaine partenaire, mais seulement lorsque son courrier est signé en DKIM/ARC
INSERT INTO pepsi.whitelist (whitelist_name, whitelist_regex, dkim_required)
VALUES ('trusted-senders', '@partner\.example\.org$', TRUE);
dkim_required vaut par défaut TRUE lorsqu’un INSERT l’omet, comme le fait pepsi-whitelist add ; une ligne qui fait confiance au courrier non signé doit indiquer dkim_required = FALSE explicitement.
Laisser passer une liste de diffusion au-delà de la barrière de paiement, quel qu’en soit le contributeur, mais seulement lorsque l’ADMD propre à la liste a scellé la chaîne ARC du message
pepsi-whitelist add-list alice/lists users.rust-lang.org \
--sealer mail.rust-lang.org
Faire délibérément confiance au seul en-tête, pour une liste qui ne scelle pas en ARC — c’est ce qu’un attaquant n’a qu’à recopier un List-Id: pour satisfaire : limitez-en donc la portée à la liste blanche propre d’un utilisateur plutôt qu’à une liste partagée
pepsi-whitelist add-list alice/lists announce.example.org --no-dkim-required
85.1.24.1.10. Voir aussi¶
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. Bogues¶
Signalez les bogues au gestionnaire de tickets de Pepsi.