Ajouter une fonctionnalité d'alias délimités sous Exim4 sous Debian stable 🔗
Introduction¶
Dans la lutte contre le SPAM, j'ai déjà adopté certaines mesures comme le greylisting. C'est efficace même si cela n'est pas parfait. Néanmoins, il y a un élément dont je ne dispose toujours pas. En effet, je ne sais pas qui est le vendu de l'histoire…
Car régulièrement, au gré de ma vie numérique connectée, je dois laisser trainer mon adresse de courrier électronique. Bien entendu, même si les sites qui récupèrent cette information s'engagent tous à ne pas la refourguer à d'autres compagnons, mon niveau de confiance est proche de l'ensemble vide. Mais alors, que faire ?
Les alias délimités viennent à notre rescousse¶
Un moyen simple consiste à utiliser ce que j'appelle des alias délimités. C'est sans doute une mauvaise traduction de l'option 'recipient delimiter' du MTA Postfix. Cela consiste en l'utilisation d'un caractère de délimitation au sein d'une adresse de courrier électronique.
Concrètement, cela prend la forme suivante: si vous avez une adresse de courrier en toto@mondomaine.example, vous pouvez utilisez aussi une adresse du type toto_cequevousvoulez@mondomaine.example. Elle sera acceptée par votre MTA et le message sera routé vers toto@mondomaine.example.
L'astuce consiste à utiliser un délimiteur (ici, c'est '_' mais ça peut être ce qu'on veut) en suffixe d'une adresse autorisée, c'est-à-dire qui existe réellement sur votre serveur. Ainsi, lorsque vous confiez votre adresse à un site marchand qui en a vraiment besoin, vous pouvez simplement utiliser toto_nomdumarchand@mondomaine.example comme adresse. Elle sera reconnue par votre MTA et vous recevrez du courrier électronique directement à votre adresse principale, sans aucune configuration.
L'intérêt de cette méthode consiste à fournir uniquement des adresses personnalisées pour chaque site sur lequel vous avez un compte. De cette manière, si vous récupérez du spam, il vous suffit d'afficher l'adresse d'origine (elle est présente dans les en-têtes et nombreux sont les MUA qui l'affichent (souvent pas par défaut).
Ainsi, vous saurez quel site a proprement revendu ou refourgué votre précieuse adresse. Google implémente cette astuce avec le délimiteur '+'.
Après cet intermède de haut niveau, passons à la mise en œuvre…
Quelques rappels sur la configuration d'Exim4 sous Debian¶
Bon, ce qui est bien avec Debian et aussi avec Exim, c'est qu'une fois que la configuration est correctement implémentée, on n'a plus à y toucher pendant de nombreuses années.
Concrètement, le vrai fichier de configuration utilisé par Exim est
situé dans /var/lib/exim4/config.autogenerated
. Ce fichier est,
comme son nom l'indique, généré par un programme dédié nommé
update-exim4.conf
(oui, je sais, un exécutable avec un .conf dedans,
c'est peu courant). Ce dernier utilise la configuration éclatée située
dans /etc/exim4/conf.d
ainsi que le fichier de macros
/etc/exim4/update-exim4.conf.conf
(ça fait beaucoup de .conf non ?).
Pour modifier la configuration d'Exim, vous devez donc modifier des
choses dans les fichiers situés dans /etc/exim4/conf.d
puis lancer
update-exim4.conf
et relancer votre service exim4 (systemctl
restart exim4
).
Implémentation des alias délimités dans Exim4¶
Je ne vais pas vous ré-expliquer les principes d'Exim, il me faudrait un livre entier. Vous pouvez néanmoins vous réferrer à la documentation officielle qui est pour le coup, complète.
Comme tout ce qui a trait à la délivrance de courrier électronique dans Exim, nous allons simplement créer un router spécifique qui se charge de vérifier la présence du délimiteur en suffixe, de l'enlever avec tout le reste de l'adresse initiale et de balancer le message vers un autre routeur, chargé lui des adresses "officielles".
Je vous invite à créer un fichier nommé
/etc/exim4/conf.d/router/310_recipient_delimiter
(le nom est
important pour l'ordre d'enchaînement des routers) avec le contenu suivant:
### router/300_recipient_delimiter
##################################
# Ce router gère la redirection vers les adresses dynamiques, définies
# avec un délimiteur. ex: toto__whatever est redirigé vers toto
recipient_delimiter:
debug_print = "R: recipient_delimiter for $local_part@$domain"
driver = redirect
domains = +local_domains
local_part_suffix = __* : ..*
data = ${quote_local_part:$local_part}@$domain
redirect_router = system_aliases
Voici les quelques explications indispensables à la compréhension de ce que nous faisons.
D'abord, nous créons un router spécifique. Il est nommé recipient_delimiter. Vous pouvez mettre ce que vous voulez comme nom mais, pour rester conforme à ce qui existe dans la littérature des MTA, j'utilise le terme recipient delimiter.
debug_print est une instruction qui imprime un message lorsqu'on est dans le mode debug d'Exim (cf plus bas). Il affiche une chaîne de caractères qui nous permet de prendre connaissance des variables local_part et domain. Ces variables contiennent respectivement la partie initiale de l'adresse en cours de traitement (toto) et le domaine traité. Le fait de mettre $ devant un nom de variable permet d'afficher son contenu (c'est $ qui permet le développement du contenu de la variable).
driver = redirect indique que ce router est de type
redirect
. C'est le router d'Exim qui permet la redirection de
message vers d'autres routers. C'est pleinement ce que nous cherchons
à faire: rediriger toto__whatever vers toto qui sera gérée par un
autre router (system_aliases dans notre cas).
domains est la liste des domaines acceptés par ce router. Dans notre cas, il s'agit des domaines du système, stocké dans la variable local_domains. En fait cette variable est une liste nommée, on utilise le caractère + pour indiquer qu'on souhaite utiliser le contenu de la liste et non la chaîne de caractères en direct.
local_part_suffix est une condition pour que le router capture le
message. Concrètement, si le contenu de cette condition est
vérifié, alors le message est géré par notre router
recipient_delimiter
. Si ce n'est pas le cas, alors le message n'est
pas traité par ce router (et il y a de fortes chances pour qu'à la
fin, il soit rejeté). La chaîne de correspondance utilise la
syntaxe d'Exim des listes. Concrètement, le suffixe cherché est du
type __*
ou ..*
qui traite donc les adresses du type
toto__whatever ou toto..whatever (* correspond à n'importe quel
caractère). Attention, cette option est plus puissante qu'on ne peut
le penser. En effet, le simple fait de déclarer un suffixe de partie
locale d'adresse suffit à réduire la partie locale de l'adresse à la
partie avant le suffixe.
data est une option de configuration des routers de type redirect. Elle indique, dans la syntaxe Exim, un moyen de trouver l'adresse réelle (toto@mondomaine.example) à partir de l'adresse initiale (toto__whatever@mondomaine.example). quote_local_part est un opérateur qui permet de mettre entre quotes la partie locale de l'adresse. Il faut l'utiliser chaque fois qu'on travaille sur la partie locale de l'adresse. Il permet de se conformer à la RFC 2822 qui gère la syntaxe du courrier électronique. On utilise ici local_part directement car local_part_suffix a déjà fait le travail de séparation pour nous.
Enfin, redirect_router est une autre option des routers de type redirect qui permet d'indiquer vers quel autre router ou balance le message qui correspond au suffixe et qui contiendra l'adresse réelle trouvée. Dans notre cas, il s'agit de system_aliases qui gère les alias systèmes et qui est le router que j'utilise pour mes comptes de messagerie configurés. Ce dernier gère la suite comme un grand.
Attention, j'utilise un transport assez simple (celui qui distribue le courrier dans un répertoire utilisateur en direct) mais si vous utilisez un transport plus élaboré qui utilise un service externe, il faudra sans doute configurer le service externe pour prendre en compte aussi l'adresse originelle qui est transmise dans les en-tête du message.
Tester notre configuration¶
Après avoir appliqué votre configuration, vous pouvez la tester en
utilisant l'option -bt
du binaire exim, de la manière suivante:
# exim4 -bt toto__nimportequoi
R: recipient_delimiter for toto__nimportequoi@mondomaine.example
R: system_aliases for toto__nimportequoi@mondomaine.example
R: system_aliases for moi@mondomaine.example
R: userforward for moio@mondomaine.example
R: procmail for moi@mondomaine.example
R: maildrop for moi@mondomaine.example
R: lowuid_aliases for moi@mondomaine.example (UID 1053)
R: local_user for moi@mondomaine.example
moi@medspx.fr
<-- toto@mondomaine.example
<-- toto__nimportequoi@mondomaine.example
router = local_user, transport = maildir_home
Ici, on voit que toto__nimportequoi est transformé en toto puis en moi
(la véritable adresse car toto est aussi un alias mais non dymanique,
déclaré dans /etc/aliases
)
En cas de problème, vous aurez probablement un message du type:
R: system_aliases for toto__nimportequoi@mondomaine.example
toto__nimportequoi@mondomaine.example is undeliverable: Unrouteable address
Afficher la source dans Roundcube¶
Dans Roundcube, l'adresse originelle n'est pas affichée par défaut,
vous devrez activer la colonne À
pour l'afficher dans la liste des
courriels entrants.
Conclusions¶
Avec ce routeur, vous avez une infinité d'adresses de courrier électronique à votre disposition pour lutter contre le SPAM en sachant qui vous a vendu.
Maintenant, cet article ne parle pas de la contre-offensive possible qui peut prendre une forme légale (si vous avez envie de prendre du temps pour ça), une redirection vers du SPAM par défaut de cette adresse une fois qu'elle a été revendue ou encore plus radical, un bannissement de l'adresse au niveau du serveur.