85.1.43. pepsi-whitelist¶
manage the sender whitelist, by hand or by mailbox
- Section du manuel:
1
85.1.43.1.1. Nom¶
pepsi-whitelist - ajouter, lister, supprimer et importer des entrées de liste blanche d’expéditeurs.
85.1.43.1.2. Synopsis¶
pepsi-whitelist [GLOBAL-OPTIONS] add [–no-dkim-required] [–signature-required] [–sealer DOMAIN] NAME REGEX
pepsi-whitelist [GLOBAL-OPTIONS] add-list [–pattern] [–no-dkim-required] [–signature-required] [–sealer DOMAIN] NAME LIST-ID
pepsi-whitelist [GLOBAL-OPTIONS] list [NAME] [–json]
pepsi-whitelist [GLOBAL-OPTIONS] remove NAME REGEX
pepsi-whitelist [GLOBAL-OPTIONS] remove-list [–pattern] NAME LIST-ID
pepsi-whitelist [GLOBAL-OPTIONS] import [IMPORT-OPTIONS] [PATH…]
85.1.43.1.3. Description¶
pepsi-whitelist est l’outil de l’opérateur pour la table pepsi.whitelist — les ensembles nommés de motifs qui marquent un message comme digne de confiance (non spam). Chaque ligne a un whitelist_name (le groupe auquel elle appartient), un whitelist_regex (une expression régulière étendue POSIX comparée sans tenir compte de la casse, via l’opérateur ~*), un match_field qui nomme ce à quoi cette expression est comparée — l’addr-spec du From: du message ou son List-Id: — et trois conditions : dkim_required, signature_required et sealer_domain. Elles sont décrites dans pepsi-stage-check-whitelist(1), qui est ce qui les évalue.
Chaque motif est vérifié avant d’être stocké, en demandant à PostgreSQL – le moteur qui l’exécutera – de le compiler : add, add-list et import refusent une expression qui ne se compile pas, avec la raison donnée par PostgreSQL, et un import n’écrit rien si l’un de ses motifs est refusé.
La liste blanche est consultée par pepsi-stage-check-whitelist(1) et peuplée automatiquement à partir des destinataires sortants par pepsi-stage-auto-whitelist(1) ; cet outil permet à un administrateur de gérer les lignes directement, et permet à chaque utilisateur de semer sa propre liste blanche à partir du courrier qu’il a déjà envoyé (import). Ce n’est pas une étape. Il se connecte à la même base de données que les autres composants, via la section partagée [pepsi-postgres], et lit la section facultative [pepsi-whitelist] décrite dans pepsi.conf(5).
Contrairement à pepsi-stage-auto-whitelist(1), qui échappe une adresse de destinataire en un motif ancré aux limites, add stocke le whitelist_regex exactement tel qu’il est donné, de sorte que l’opérateur contrôle directement la correspondance. import échappe les adresses qu’il trouve, exactement comme le fait l’étape.
85.1.43.1.3.1. Listes de diffusion¶
add-list et remove-list gèrent les lignes list-id qui mettent une liste de diffusion entière en liste blanche — chaque message qu’elle relaie, quel qu’en soit l’auteur, ce qu’un motif sur From: ne peut exprimer parce que les messages d’une liste portent des adresses d’expéditeur arbitraires.
Ce sont des sous-commandes distinctes plutôt qu’un indicateur sur add, parce qu’elles prennent un autre type d’argument. add stocke son REGEX verbatim, ce qui convient à un motif qu’un opérateur a composé délibérément ; un identifiant de liste tapé dans cet emplacement serait une expression régulière non ancrée, de sorte que users.example.org correspondrait aussi à users.example.org.attacker.example et mettrait en liste blanche une liste au choix de l’attaquant. add-list prend l’identifiant tel qu’il apparaît dans l’en-tête — chevrons facultatifs, casse et phrase environnante ignorées — et l’ancre lui-même. –pattern est l’échappatoire pour le joker délibéré (toutes les listes d’un domaine), et l’argument est alors de nouveau une expression régulière, comme avec add.
Un en-tête List-Id: est un texte non authentifié que tout expéditeur peut recopier d’un message authentique : une règle qui ne repose que sur lui est une règle que n’importe qui peut satisfaire. –sealer DOMAIN est l’autre moitié : la ligne exige alors en outre que le message soit arrivé avec une chaîne ARC ayant validé et que DOMAIN ait été l’un de ses scelleurs, tel que pepsi-stage-arc(1) le note. DOMAIN est normalisé (mis en minuscules, point final retiré) sous la même forme que celle que note l’étape ARC, de sorte que les deux ne peuvent pas diverger. Cela fonctionne aussi sur les lignes add, où cela restreint un motif d’expéditeur au courrier relayé par un redirecteur connu.
85.1.43.1.3.2. Noms de liste blanche et qui peut les utiliser¶
Un whitelist_name est soit
- global — un seul segment tel que
correspondents, que seul l’opérateur peut gérer ; soit
- détenu par un utilisateur —
<login>/<segment>tel quealice/correspondents, et alice/lists/rust-langpour d’autres sous-listes.
Un segment est composé de lettres, de chiffres, de _, de . et de - ; le séparateur est /. Un segment fait uniquement de points est refusé, de sorte que . et .. ne peuvent pas être des segments et qu’un nom de liste blanche ne peut jamais être un chemin relatif. Le point est par ailleurs autorisé parce que le segment propriétaire est le login passwd du compte, et alice.smith est un login ordinaire sur tout déploiement LDAP/SSSD/FreeIPA — tout comme un {localpart} de la forme first.last dans pepsi-stage-check-whitelist(1). / est le séparateur parce qu’aucun système de type POSIX ne l’autorise dans un nom de connexion, alors que -, _, . et un $ final y sont tous légaux et ne pourraient donc pas délimiter sans ambiguïté. (Un login portant un caractère hors de la grammaire des segments ne possède toujours aucun espace de noms ; import –all-users saute un tel compte avec un message plutôt que de faire échouer toute l’exécution.)
Parce que ce programme est installé setuid (voir ci-dessous), tout utilisateur local peut l’exécuter. Un appelant non privilégié ne peut lire et écrire que des noms de son propre espace de noms — le login de l’uid réel, pris dans la base passwd, jamais dans $USER ni dans un argument. Cette restriction couvre aussi list : la liste blanche partagée de l’opérateur est un relevé de qui l’organisation fréquente, et ce programme ne doit pas le livrer à chaque compte de l’hôte. root, ainsi que les comptes pepsi, pepsi-owner et pepsi-whitelist, peuvent gérer toutes les listes blanches.
Pour qu’une liste blanche par utilisateur ait le moindre effet, une étape doit la consulter ; voir les marqueurs {localpart} et {login} de WHITELIST_NAME dans pepsi-stage-check-whitelist(1).
85.1.43.1.3.3. Le modèle setuid¶
Gérer la table partagée pepsi.whitelist nécessite une identité de base de données que les utilisateurs ordinaires n’ont pas, alors que parcourir la boîte aux lettres d’un utilisateur nécessite son identité. Le programme est donc installé setuid vers le compte pepsi-whitelist (mode 4755) et abaisse immédiatement ses ids effectifs vers l’utilisateur appelant, ne conservant le propriétaire que dans le set-user-id sauvegardé. Il les relève de nouveau pendant les quelques millisecondes où il dialogue avec PostgreSQL — l’authentification peer se fonde sur l’uid effectif — et pour rien d’autre.
C’est ce même mécanisme qui permet à root d’utiliser l’outil. Les autres commandes de l’opérateur — pepsi-queue(1), pepsi-status(1), pepsi-settings(1), pepsi-tlsrpt(1), pepsi-failure-bouncer(1) — deviennent simplement le compte de service pepsi lorsqu’elles sont démarrées en tant que root, définitivement, car elles n’ont rien à faire en tant que root. Celle-ci, si : import –user et –all-users exécutent le helper de parcours sous les identifiants d’un autre utilisateur, ce que seul root peut organiser. Elle conserve donc l’identité appelante, root compris, et ne bascule que ses ids effectifs — vers le compte pepsi-whitelist, dont le rôle de base de données n’a de droits que sur la table de liste blanche — le temps de chaque appel à la base, pour revenir ensuite à root.
Ce compte n’est délibérément pas le compte de service pepsi : pepsi-setup(1) accorde à son rôle de base de données SELECT, INSERT et DELETE sur la table pepsi.whitelist et rien de plus, de sorte que la compromission d’un binaire que chaque utilisateur local peut exécuter ne peut atteindre ni la file d’attente de messages, ni les statistiques, ni les clés de signature.
L’analyse de la boîte aux lettres — la seule partie qui lit des données contrôlées par un attaquant, à savoir chaque message que quiconque a jamais envoyé à l’utilisateur — n’a pas lieu dans ce processus du tout. Elle s’exécute dans pepsi-helper-mailbox-scan(1), lancé avec setresuid positionnant les ids réel, effectif et sauvegardé sur l’utilisateur cible, de sorte que ce processus ne conserve nulle part dans ses identifiants un id privilégié et ne peut pas devenir pepsi-whitelist, même en principe.
Parce qu’un programme setuid ne doit pas être dirigé vers un fichier de configuration choisi par l’appelant, -c/–config est rejeté pour les appelants non privilégiés, et les variables d’environnement qui redirigeraient autrement la recherche de configuration (HOME, XDG_CONFIG_HOME), l’expansion de ${DATADIR} (PATH) ou la connexion à la base de données (PG*) sont retirées avant que la configuration ne soit lue.
85.1.43.1.4. Commandes¶
- add [–no-dkim-required] [–signature-required] [–sealer DOMAIN] NAME REGEX
Insérer une entrée
fromstockant REGEX sous la liste blanche NAME. L’insertion est idempotente sur la contrainteUNIQUE(whitelist_name, match_field, whitelist_regex): ré-ajouter un triplet existant est sans effet et laisse ses conditions inchangées.- –no-dkim-required
Effacer l’indicateur
dkim_requiredde la ligne. Par défaut il est positionné, de sorte qu’une correspondance ne compte que si la signature DKIM ou ARC de l’expéditeur s’est vérifiée.- –signature-required
Positionner l’indicateur
signature_requiredde la ligne. Par défaut il est effacé. Lorsqu’il est positionné, une correspondance ne compte que si la signature du message s’est vérifiée.- –sealer DOMAIN
Définir le
sealer_domainde la ligne. Par défaut il est vide (n’importe quel chemin). Lorsqu’il est défini, une correspondance ne compte que si le message est arrivé avec une chaîne ARC ayant validé et que DOMAIN a été l’un de ses scelleurs. DOMAIN est mis en minuscules et débarrassé d’un point final, en accord avec ce que note pepsi-stage-arc(1).
- add-list [–pattern] [CONDITION-OPTIONS] NAME LIST-ID
Insérer une entrée
list-idsous la liste blanche NAME, correspondant à tout message dont l’en-têteList-Id:porte l’identifiant LIST-ID. L’identifiant peut être donné entre chevrons ou nu, dans n’importe quelle casse, avec ou sans phrase descriptive ; il est réduit à sa forme nue en minuscules et ancré, de sorte qu’il corresponde à cette liste et à aucune autre. Prend les mêmes options de condition que add, et l’associer à –sealer est vivement conseillé — voir Listes de diffusion ci-dessus.- –pattern
Traiter LIST-ID comme une expression régulière étendue POSIX à stocker verbatim, plutôt que comme un identifiant unique à ancrer. Pour le cas du joker délibéré (toutes les listes d’un domaine) ; une expression non ancrée correspond à tout identifiant qui la contient, écrivez donc les ancres vous-même.
- list [NAME] [–json]
Lister les entrées ordonnées par nom, champ de correspondance, puis regex. Avec NAME, seul ce groupe de liste blanche est affiché.
- –json
Émettre un tableau JSON d’objets (
whitelist_id,whitelist_name,whitelist_regex,match_field,dkim_required,signature_required,sealer_domain) au lieu de la table lisible par un humain.
- remove NAME REGEX
Supprimer l’entrée
fromdont lewhitelist_nameest NAME et dont lewhitelist_regexest exactement REGEX. Une lignelist-idportant le même texte de motif est une entrée différente et est laissée intacte ; employez remove-list pour elle.- remove-list [–pattern] NAME LIST-ID
Supprimer l’entrée
list-idque add-list aurait créée pour LIST-ID, de sorte que l’identifiant qui a ajouté une liste la retire également. –pattern a le même sens que dans add-list, et doit être donné s’il l’a été alors.- import [OPTIONS] [PATH…]
Semer une liste blanche à partir des destinataires du courrier que l’utilisateur a envoyé.
Une boîte aux lettres est parcourue à la recherche des messages envoyés par l’utilisateur, et les adresses
To:,Cc:etBcc:de ces messages deviennent des entrées de liste blanche, de sorte que lorsque ces personnes répondent, leurs réponses sont reconnues. Les destinataires à un domaine local sont sautés — les expéditeurs locaux ne passent jamais par la barrière entrante.Un message compte comme envoyé par l’utilisateur lorsque son
From:(ou sonSender:) est à l’un des domaines locaux et que son bloc d’en-têtes ne porte aucun champReceived:,Return-Path:,Delivered-To:niX-Original-To:. Les deux moitiés sont nécessaires :From:n’est pas authentifié, c’est donc à lui seul une affirmation que n’importe qui peut faire, et un inconnu qui vous envoie un message portant votre propre adresse dansFrom:et la sienne dansTo:verrait sinon cette adresse insérée dans votre liste blanche par le prochain import — c’est-à-dire précisément la barrière que la liste blanche ouvre. Exiger une signature ne la referme pas, car le faussaire signe le courrier de son propre domaine. Les quatre champs ci-dessus sont écrits par un MTA ou un MDA de réception et jamais par un client de messagerie qui compose un message : leur absence est donc la preuve que le message a été classé ici plutôt que remis ici.Le courrier reçu est donc ignoré, comme tout ce qui est arrivé. –include-delivered désactive ce test ; lisez ci-dessous avant de l’employer.
L’endroit où un message est classé n’a toujours pas d’importance : un parcours de Maildir traverse tout l’arbre, de sorte que
~/Maildircouvre.Sentet chaque dossier d’archive en une seule exécution. Seul le bloc d’en-têtes de chaque message est lu, jamais le corps.PATH… sont des fichiers de boîte aux lettres ou des répertoires Maildir. Sans aucun,
~/Maildirest parcouru s’il existe, sinon/var/mail/<login>;[pepsi-whitelist] MAILBOXredéfinit cette valeur par défaut. Notez que/var/mail/<login>est un spool de remise et ne contient que du courrier reçu : sur un hôte sans Maildir, la valeur par défaut ne trouve donc rien et un dossier Sent doit être nommé explicitement.- –name NAME
Liste blanche à semer. Par défaut
<login>/correspondents(ou lecorrespondentsglobal pour un appelant privilégié).- –include-delivered
Compter un message comme envoyé sur la seule foi de son
From:, en abandonnant le test de trace de remise ci-dessus. Dangereux sur toute boîte aux lettres qui contient du courrier reçu — unFrom:falsifié suffit alors à planter une entrée de liste blanche. Cela existe pour le magasin inhabituel dont les copies envoyées sont réellement passées par la remise, et ne devrait être pointé que vers ce dossier Sent, jamais vers une boîte de réception.- –format
auto|mbox|maildir Forcer le format de boîte aux lettres au lieu de le détecter par chemin (un répertoire est une Maildir, un fichier une mbox).
- –auto-wildcard
Proposer de remplacer les adresses individuelles d’un domaine par une seule entrée
*@domainlorsqu’au moins N adresses distinctes y ont été vues (N est--threshold, par défaut[pepsi-whitelist] WILDCARD_THRESHOLD, 10).Les propositions sont imprimées et confirmées une à une sur un terminal ; en refuser une garde simplement les adresses de ce domaine individuelles. Avec –yes, toutes sont acceptées ; sans terminal et sans –yes, toutes sont refusées, de sorte qu’une exécution sans surveillance ne peut jamais élargir d’elle-même une liste blanche à un domaine entier.
Les hébergeurs e-mail publics ne sont jamais proposés, quel que soit le nombre de correspondants que l’utilisateur y a : « tout le monde chez
gmail.com» n’est pas un ensemble de personnes que l’utilisateur connaît. La liste de ces domaines est[pepsi-whitelist] HOSTERS_FILE(/usr/share/pepsi/hosters.txt).- –threshold N
Nombre d’adresses distinctes à un même domaine avant qu’un joker ne soit proposé.
- –hosters FILE
Utiliser FILE comme liste d’hébergeurs publics au lieu de celle configurée.
- –no-hosters
N’exclure aucun domaine de la mise en joker.
- –dry-run
Signaler ce qui serait ajouté et ne rien changer.
- -y, –yes
Accepter chaque proposition de joker sans demander.
- –max-entries N
Nombre maximal de lignes que cet import peut ajouter (par défaut
[pepsi-whitelist] MAX_ENTRIES, 5000). Chaque ligne d’une liste blanche est comparée auFrom:de chaque message entrant qui la consulte, de sorte qu’un import non borné est un coût permanent par message.- –max-messages N
Examiner au plus N messages. Cela plafonne le nombre de messages analysés et classés, pas la portion de la boîte aux lettres qui est lue : le fichier, l’arbre ou le compte IMAP est tout de même parcouru jusqu’au bout.
- –own-address ADDRESS
Ne considérer comme appartenant à l’utilisateur que le courrier envoyé depuis cette adresse exacte, au lieu de tout expéditeur à un domaine local. Répétable.
- –imap URL
Parcourir un magasin de courrier qui n’est pas sur ce système de fichiers, p. ex.
imaps://alice@mail.example.com/.imaps://est du TLS implicite (port 993),imap://du STARTTLS (port 143) ; un composant de chemin est un motif de boîte aux lettres (par défaut*, toutes les boîtes). Les boîtes aux lettres sont ouvertes en lecture seule (EXAMINE) et seuls les blocs d’en-têtes sont récupérés, de sorte qu’un parcours ne marque rien comme\Seen.LMTP ne peut pas faire cela — c’est un protocole de remise sans aucun verbe qui liste ou récupère quoi que ce soit — ce qui explique pourquoi IMAP est l’option réseau.
- –imap-user NAME
Le login IMAP, s’il n’est pas dans l’URL.
- –imap-password-file FILE
Lire le mot de passe sur la première ligne de FILE au lieu de le demander. Gardez-le en mode
0600: ce chemin lit le fichier lui-même et ne vérifie pas ses permissions, contrairement à l’option du même nom de pepsi-helper-mailbox-scan(1), qui refuse un fichier que tout autre utilisateur peut lire. Le mot de passe n’est jamais passé sur une ligne de commande, où tous les autres utilisateurs pourraient le lire dansps.- –doveadm
Lire un magasin Dovecot local via
doveadm, pour les formats qu’aucun scanner de fichiers ne peut analyser (mdbox/sdbox).doveadmest exécuté par ce programme (il a besoin de privilèges) et sa sortie est redirigée vers le helper de parcours non privilégié.- –doveadm-path PATH
Le binaire
doveadmà utiliser.- –user LOGIN
Importer pour un autre utilisateur, dans son espace de noms. Nécessite un appelant privilégié ; le helper de parcours est abaissé aux identifiants de cet utilisateur.
- –all-users
Importer pour chaque compte local que
[pepsi-whitelist] TARGETSautorise, chacun dans son propre<login>/correspondents. Nécessite un appelant privilégié. Seuls les comptes du fichier passwd local sont trouvés ; nommez un compte de service d’annuaire avec –user.- –no-dkim-required, –signature-required
Comme pour add, appliqué à chaque ligne que l’import ajoute.
85.1.43.1.5. Options globales¶
Ces options globales précèdent la sous-commande (un indicateur placé à la fin est rejeté).
- -c FILE, –config FILE
Lit la configuration depuis FILE au lieu de parcourir les emplacements par défaut. Rejeté pour les appelants non privilégiés lorsque ce programme est installé setuid : la configuration décide de la connexion à la base de données, de sorte qu’un processus setuid n’en lit qu’une qui appartient à root.
- -L LOGLEVEL, –log LOGLEVEL
Règle la verbosité de journalisation. LOGLEVEL est l’un de
error,warn,info,debugoutrace(par défaut :info).- -v, –verbose
Affiche les messages de journal de toutes les sources, y compris les bibliothèques tierces.
- -h, –help
Affiche un résumé d’utilisation et quitte.
- -V, –version
Affiche la version et quitte.
85.1.43.1.6. Code de sortie¶
- 0
Achèvement réussi.
- 1
Une erreur s’est produite : un fichier de configuration malformé ou une connexion ou requête de base de données échouée. La raison est écrite dans le journal.
85.1.43.1.7. Fichiers¶
Lorsque –config n’est pas fourni, le premier fichier existant de la liste suivante est utilisé. Chaque composant Pepsi partage le même fichier de configuration, c’est donc la même liste que chacun parcourt :
$XDG_CONFIG_HOME/pepsi.conf$HOME/.config/pepsi.conf/etc/pepsi/pepsi.conf/etc/pepsi.conf
${DATADIR}/hosters.txtLa liste d’hébergeurs publics pour lesquels import –auto-wildcard ne propose jamais de joker, installée par
make installdepuiscontrib/hosters.txt(/usr/share/pepsi/hosters.txtsur une installation par défaut). Surchargée par[pepsi-whitelist] HOSTERS_FILEou, pour une seule exécution, par –hosters.~/Maildir,/var/mail/loginLes boîtes aux lettres que import parcourt lorsqu’aucun PATH n’est donné, dans cet ordre ;
[pepsi-whitelist] MAILBOXremplace la paire.
85.1.43.1.8. Exemples¶
Mettre un expéditeur en liste blanche (DKIM/ARC requis par défaut)
pepsi-whitelist -c /etc/pepsi/pepsi.conf add trusted-senders '^alice@example\.com$'
Le motif est stocké verbatim, l’ancrer est donc le travail de l’opérateur. Un alice@example\.com non ancré correspond aussi à alice@example.com.attacker.example et à "alice@example.com!"@attacker.example, que l’attaquant peut l’un comme l’autre placer dans un en-tête From:. C’est pour cette raison que les motifs engendrés (import et pepsi-stage-auto-whitelist(1)) ancrent toujours sur ^/$.
Mettre tout un domaine en liste blanche sans exiger de signature
pepsi-whitelist -c /etc/pepsi/pepsi.conf add trusted-senders --no-dkim-required '@example\.org$'
Lister le groupe trusted-senders en JSON
pepsi-whitelist -c /etc/pepsi/pepsi.conf list trusted-senders --json
Supprimer une entrée
pepsi-whitelist -c /etc/pepsi/pepsi.conf remove trusted-senders '@example\.org$'
En tant qu’utilisateur ordinaire, mettre en liste blanche une liste de diffusion à laquelle vous êtes abonné, de sorte que ses messages vous parviennent quels qu’en soient les auteurs, mais seulement lorsque l’ADMD propre à la liste les a scellés
pepsi-whitelist add-list alice/lists users.rust-lang.org \
--sealer mail.rust-lang.org
Toutes les listes exploitées à un même domaine, ce qui exige d’écrire les ancres à la main
pepsi-whitelist add-list alice/lists --pattern '^[a-z0-9-]+\.lists\.example\.org$' \
--sealer lists.example.org
Désabonné ; retirer la règle avec l’identifiant qui l’a créée
pepsi-whitelist remove-list alice/lists users.rust-lang.org
En tant qu’utilisateur ordinaire, semer votre propre liste blanche depuis votre boîte aux lettres, en voyant d’abord ce que cela ferait
pepsi-whitelist import --dry-run
pepsi-whitelist import
Idem, mais en regroupant les domaines auxquels vous écrivez largement en une entrée chacun (les hébergeurs publics ne sont jamais regroupés)
pepsi-whitelist import --auto-wildcard
Parcourir seulement votre dossier Sent, et un compte distant via IMAP
pepsi-whitelist import ~/Maildir/.Sent
pepsi-whitelist import --imap imaps://alice@mail.example.com/Sent
En tant que root, semer la liste blanche propre à chaque compte local depuis un magasin Dovecot
pepsi-whitelist import --all-users --doveadm --auto-wildcard --yes
85.1.43.1.9. Voir aussi¶
pepsi-config(1), pepsi-helper-mailbox-scan(1), pepsi-stage-check-whitelist(1), pepsi-stage-auto-whitelist(1), pepsi-queue(1), pepsi.conf(5), pepsi-setup(1)
85.1.43.1.10. Bogues¶
Signalez les bogues au gestionnaire de tickets de Pepsi.