Ajouter une fonctionnalité d'alias délimités sous Exim4 sous Debian stable🔗

Posted by Médéric Ribreux 🗓 In blog/ Debian/

#debian #email #auto-hébergement

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.

Références