Chronométrer les étapes de l’acheminement du courrier électronique

Dans certains contextes, comme à l'Université Lyon 2, il peut être important de se faire une idée en temps réel des délais d'acheminement du courrier électronique étape par étape. Bien sûr, cela n'a de sens que sur une chaîne de serveurs internes et connus. Dans le cadre de l'audit et de la surveillance de l'infrastructure de courrier électronique de Lyon 2, j'ai développé un outil "quick & dirty" d'analyse des délais inter-serveur.

Entre l'extérieur du réseau, et la boîte email de l'utilisateur nous avons 5 étapes, donc 4 délais à calculer et surveiller. Chaque étape ajoute au courrier un entête "Received:" incluant le serveur "source", le serveur "destinataire", et surtout, la date et l'heure de la transaction. La différence de temps entre les date et heure de deux entêtes nous donne le délais subit par le courrier sur le serveur "source".
Pour avoir une vue de ce qu'il se passe sur cette chaîne de serveurs, il faut donc poster un courrier en entrée de site, le recevoir en bout de chaîne, et analyser ses entêtes. Comme il n'y a pas besoin de performances, j'ai choisi l'approche la plus simple pour moi : des scripts shell et awk. Si on se limite à une vue d'ensemble, on a ceci :

  1. Une crontab (ou un agent Launchd) lance le script qui génère le courrier. Ce script se connecte sur le smtp d'entrée de site et crée le courrier. Au passage il enregistre la date d'émission du courrier dans deux fichiers (on pourrait faire plus simple).
  2. Le mail vit sa vie dans le système d'acheminement et de filtrage. Il arrive enfin sur le serveur POP.
  3. Une instance fetchmail lancée en mode "démon" se connecte au serveur POP, et ramène le ou les courriers reçus . Ces courriers sont injectés dans le Postfix local puis transmis au fichier .forward du compte utilisateur réglé dans le .fetchmailrc.
  4. Le .forward envoie chaque courrier dans un script de filtrage pour convertir les entêtes en délais.
  5. Ce script awk lance enfin un script shell qui met à jour les fichiers d'enregistrement.

Les scripts shell de l'étape 1 et 5 sont en fait un seul et même script, qui lance des instructions différentes suivant qu'il est invoqué avec ou sans arguments. Dans les deux cas il génère un graphique représentant le délai par étape en fonction de la date d'envoi.

Installation
Pour que l'installation fonctionne il faut que la machine hôte puisse se connecter en ssh sur le serveur de courrier d'entrée de site, et puisse faire du POP via fetchmail pour récupérer les courriers en fin de chaîne. Il faut que la machine dispose aussi de gnuplot si on veut tracer les graphiques, et gawk (awk n'est pas suffisant car il ne gère pas les conversions de date).

1. Télécharger les scripts email_delay_tracking.sh et filtrage.awk et les copier à l'endroit voulu sur la machine d'analyse. Ne pas oublier de les rendre exécutables.
Normalement, le script filtrage.awk n'a pas besoin d'être beaucoup modifié, il est aussi générique que possible. Néanmoins, la ligne 25 devra être éditée pour remplacer "by MACHINE-D-ANALYSE" par la mention adaptée à l'entête de réception de la machine locale. On vérifiera aussi la ligne 1 du fichier pour mettre le cas échéant le chemin exact de gawk.
La configuration de email_delay_tracking.sh est un peu plus longue. Il faut impérativement configurer les variables MY_SMTP, MY_ROOT, MY_SSHKEY et MY_ACCOUNT en début de script. Attention aussi au lignes 111 et 125, les chemins de gnuplot et gawk sont "en dur".

2. Créer la clé SSH de connexion au serveur MY_SMTP. Pour plus de sécurité il faut bien sûr opter pour une clé ssh limitée à l'envoi de courrier et à la commande date (option command).

$ ssh-keygen -f /chemin/de/la/cle/emailmonitor -t dsa
Generating public/private dsa key pair.
Enter passphrase (empty for no passphrase):    # ici on ne met rien
Enter same passphrase again:                   # idem
Your identification has been saved in /chemin/de/la/cle/emailmonitor.
Your public key has been saved in /chemin/de/la/cle/emailmonitor.pub.
The key fingerprint is: ...

La clé est générée, on va la brider maintenant en ajoutant au début de fichier emailmonitor.pub les mentions suivantes sur une seule ligne (juste devant "ssh-dss ...") :

command="echo test | mail emailmonitor@VOTRE-DOMAINE & date +%s",
no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty 

Ensuite on transfert emailmonitor.pub dans le fichier .ssh/authorized_keys de l'utilisateur voulu, sur le serveur MY_SMTP.

3. Activer filtrage.awk et email_delay_tracking.sh. Pour activer filtrage.awk il faut éditer le fichier .forward du compte utilisateur que l'on va dédier à la réception des courriers de test. Les courriers pour cet utilisateur seront tous détruits, attention donc de bien utiliser un compte dédié, ou d'utiliser procmail à la place du .forward. Typiquement, ce fichier contiendra la ligne :

$ more ~/.forward 
"|/chemin/de/filtrage.awk"

L'activation de email_delay_tracking.sh se fait par crontab. Un lancement toutes les 5 minutes est un bon rythme :

*/5 * * * * /chemin/de/email_delay_tracking.sh

La suite des activations se fait au niveau de fetchmail. En fonction de ses préférences et de l'adresse du serveur POP, on configure le fichier .fetchmailrc du compte utilisateur qui recevra les courriers de test. Cela donne quelque chose comme ça :

$ more .fetchmailrc 
set postmaster "UTILISATEUR"
set nobouncemail
set no spambounce
set properties ""
set logfile /home/UTILISATEUR/.fetchmail_log
set daemon 113
poll SERVEUR_POP
  with proto POP3 and options uidl
   user 'emailmonitor' there with password '*******' is 'UTILISATEUR' here

'emailmonitor' est le login du compte email MY_ACCOUNT. J'ai choisi un intervalle de 113 secondes entre chaque relève POP pour éviter les "collisions" avec l'étape d'envoi de courriers.

À partir de là, tout devrait fonctionner. Si ce n'est pas le cas, un simple tail -f sur .fetchmail_log, emailmonitor.log, ou les log du postfix local devrait donner l'origine de la panne. Si on a plus (ou moins) de 4 délais à calculer, il faut modifier le script email_delay_tracking.sh aux lignes 96, 105, 126-130. Pour plus de cohérence on pourra aussi modifier les lignes 32-35, 72 et 80, mais c'est facultatif. Ensuite, on doit normalement obtenir un graphique mis à jour automatiquement en temps réel.

edit : lun. 29 mai, mise à jour du script email_delay_tracking.sh (correction de bugs, ajout d'un graphique de "zoom" sur les deux dernières heures.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.