Cadeau bonus

Pour ceux qui ne seraient pas satisfaits de la façon dont nous avons interfacé Sympa avec Postfix, voici une autre piste qui préserve d'avantage les ressources système en cas de « spam storm ».

Les transports

Nous le savons, il est possible de définir des transports particuliers dans le fichier master.cf de postfix.

Nous pouvons en définir un certain nombre qui font référence à /usr/lib/sympa/bin/queue. Voici ce que nous pouvons ajouter dans notre master.cf :

#
# Les « pipes » sympa
# ou
# Les transports du gestionnaire de listes sympa
#
sympalist        unix  -       n       n       -       -       pipe
  flags=RF user=sympa argv=/usr/lib/sympa/bin/queue ${user}@${extension}
symparequest     unix  -       n       n       -       -       pipe
  flags=RF user=sympa argv=/usr/lib/sympa/bin/queue ${user}-request@${extension}
sympaeditor      unix  -       n       n       -       -       pipe
  flags=RF user=sympa argv=/usr/lib/sympa/bin/queue ${user}-editor@${extension}
sympasubscribe   unix  -       n       n       -       -       pipe
  flags=RF user=sympa argv=/usr/lib/sympa/bin/queue ${user}-subscribe@${extension}
sympaunsubscribe unix  -       n       n       -       -       pipe
  flags=RF user=sympa argv=/usr/lib/sympa/bin/queue ${user}-unsubscribe@${extension}
sympabounce      unix  -       n       n       -       -       pipe
  flags=RF user=sympa argv=/usr/lib/sympa/bin/bouncequeue ${user}@${extension}

Nous reconnaissons des syntaxes assez proches de celles que nous avons vues dans /etc/mail/sympa.aliases. Il nous faudra réaliser une « map » des transports à emprunter suivant l'adresse du message à envoyer à Sympa.

Alias virtuels

Nous allons exploiter les propriétés des extensions d'adresses, avec le recipient_delimiter :

recipient_delimiter = +

Ainsi que les possibilités de réécriture d'adresses avec les alias virtuels de Postfix. La compréhension de ce mécanisme n'est pas d'une grande simplicité, il faut bien le dire.

Extension d'adresse

Si nous écrivons quelque chose comme truc+bidule@undomaine.quelconque, la partie à gauche du @ va être séparée en deux :

  • la partie à gauche du + (truc) sera récupérée dans la variable ${user} ;
  • la partie à droite du + (bidule) sera récupérée dans la variable ${extension}.

Compte tenu des transports que nous avons créés dans master.cf, nous voyons bien que cette possibilité va nous servir.

Alias virtuels

Une table d'alias, nous l'avons compris à force, permet de remplacer une adresse par une autre. Nous pouvons exploiter les expressions régulières dans ces tables, et n'allons pas nous en priver. Créons par exemple un fichier /etc/postfix/sympa_virtual_aliases qui contiendrait, compte tenu de nos essais précédents, ceci :

/^(sympa|listmaster)\@lists\.nain-t\.net$/    $1+lists.nain-t.net@sympalist.
/^(liste1)-(request|editor|owner|subscribe|unsubscribe)\@lists\.nain-t\.net$/  $1+lists.nain-t.net@sympa$2.
/^(liste1)\@lists\.nain-t\.net$/  $1+lists.nain-t.net@sympalist.

/^(sympa|listmaster)\@lists\.machin\.net$/    $1+lists.machin.net@sympalist.
/^(liste1)-(request|editor|owner|subscribe|unsubscribe)\@lists\.machin\.net$/  $1+lists.machin.net@sympa$2.
/^(liste1)\@lists\.machin\.net$/  $1+lists.machin.net@sympalist.

Vous ne lisez toujours pas les expressions régulières dans le texte ? Tant pis pour vous.

Soit une adresse qui serait par exemple liste1-unsubscribe@lists.machin.net. Elle sera remplacée par liste1+lists.machin.net@sympaunsubscribe. Curieux comme adresse non ?

Mais attendons la suite, nous comprendrons mieux plus tard.

Transport à la carte

Créons un fichier nommé par exemple /etc/postfix/sympa_transport_maps qui contiendrait ceci :

/^.*\@sympalist$/         sympalist:
/^.*\@symparequest$/      symparequest:
/^.*\@sympaeditor$/       sympaeditor:
/^.*\@sympasubscribe$/    sympasubscribe:
/^.*\@sympaunsubscribe$/  sympaunsubscribe:
/^.*\@sympaowner$/        sympabounce:

(Oui ! Encore des expressions régulières).

Par exemple, un message desitiné à une adresse qui aurait dans sa partie « domaine » (à droite du @ la valeur sympaunsubscribe et seulement cette valeur, sera transmise au transport sympaunsubscribe.

Reprenons notre exemple précédent.

  1. Postfix a reçu un message pour liste1-unsubscribe@lists.machin.net ;
  2. cette adresse a donc été transformée en liste1+lists.machin.net@sympaunsubscribe à cause de la table d'alias virtuels ;
  3. la table des transports dit qu'un message dont l'adresse du destinataire se termine par sympaunsubscribe doit être transmise au transport du même nom ;
  4. le transport en question (/usr/lib/sympa/bin/queue que nous connaissons déjà) va donc recevoir un message avec une adresse de destination de la forme ${user}-unsubscribe@${extension}.
  • Notre ${user}, c'est liste1 ;
  • notre ${extension}, c'est lists.machin.net.

L'adresse communiquée au transport est donc finalement liste1-unsubscribe@lists.machin.net. Astucieux non ? Je vous rassure, votre serviteur n'a pas inventé un truc aussi compliqué (et aussi efficace). Il s'est contenté de le trouver ici.

Et finalement...

Dans postfix, à part ajouter les transports dans master.cf, il faut invoquer le récipient-delimiter :

recipient_delimiter = +

Invoquer la carte des transports :

transport_maps=regexp:/etc/postfix/sympa_transport_maps

Invoquer la table des alias virtuels :

virtual_alias_maps = mysql:/etc/postfix/db/virtual-alias.cf, regexp:/etc/postfix/sympa_virtual_aliases

Avantage

Cette méthode élimine les expressions plus génériques que nous avions employées dans la première solution, évitant ainsi d'envoyer du spam à sympa (ce qui ne l'est pas), Postfix refusant directement ces messages qui ne sont plus pour lui dans ses destinataires connus. Autrement dit, contrairement à la solution d'origine où un message à albert@lists.machin.net aurait été transmis à Sympa et c'est sympa qui l'aurait rejeté, ici, c'est Postfix qui va le rejeter directement.

Inconvénient

A chaque création d'une nouvelle liste, il faudra intervenir manuellement sur le fichier /etc/postfix/sympa_virtual_aliases car les alias construits par alias_manager.pl ne sont ici d'aucune utilité.

Comme ce script utilise des « templates tt2 » il reste peut-être un espoir pour qu'un expert trouve un modèle qui apporte une réponse à la question. Faute de quoi, il faut écrire un autre script pour automatiser cette tâche.