Retrouvez cet article dans : Linux Magazine Hors série 36
Il y a très très longtemps, dans une galaxie très lointaine, les seigneurs siths avaient la fâcheuse habitude de tomber dans des trous. Pour pallier cela, ils avaient créé un système qui leur permettait d’être redirigés dans des endroits plus sûrs. Employant les chasseurs de primes Boba procmail Fett et son père Jango fetchmail Fett, ils avaient mis en place un astucieux système parfois même utilisé et toléré par les Jedi.
Peu après son arrivée sur la planète secrète Anoth, Anakin Solo (neveu de Luke Skywalker) décida de supprimer ce système afin d’en finir avec les Siths.
– Musique –
|
1 |
|
1.1 |
fdm remplace donc avantageusement les deux outils. On ne peut plus utiliser que son procmail et fetchmail (et leurs alternatives). J’ai toujours eu des soucis avec procmail et quand je me suis penché sur une solution pour récupérer mes mails et les traiter, je me suis retrouvé avec plein d’incertitudes dans la tête. C’est alors qu’un jardinier m’a filé un lien. Au début, j’étais plutôt contre l’idée de remplacer deux outils par un seul (vous savez, le vieux principe d’Unix : une fonction, un outil). Mais en fait, c’est de la ballounette en barres.
|
1.2 |
fdm est un outil sous licence BSD qui marche sur tous les BSD, et les GNU/Linux. Il permet de récupérer mails et news sur : pop, imap, nntp (avec SSL ou sans dans chaque cas), maildir/mbox, stdin et de délivrer le courrier à un pipe, un fichier, un maildir, une mailbox ou un serveur SMTP.
La syntaxe du fichier de configuration est relativement aisée d’accès et les capacités de l’outil sont impressionnantes.
Nous commencerons par examiner un exemple correspondant à un usage classique : récupérer les mails d’un compte sur un serveur, faire le traitement antispam, et livrer les mails. Nous verrons ensuite une configuration plus avancée utilisant un peu plus les capacités de cet outil. Pour finir, nous étudierons les différentes façons de lancer fdm : à la main ou via une entrée du crontab.
Afin de planter cette nouvelle pousse chez vous, il vous faut préparer un peu de terrain. Vous pouvez récupérer les sources [1], utiliser un package ou un port. Si vous prenez les sources, il vous faudra récupérer une dépendance au passage : TDB Trivial DataBase library [2].
|
2 |
fdm est pensé pour remplacer fetchmail/getmail et procmail dans un principe mono-utilisateur. Son fichier de configuration est donc au même endroit que celui de ceux-ci : dans votre $HOME. Pour ceux qui voudraient employer fdm à plus grande échelle, il est possible de le configurer pour plusieurs utilisateurs. Nous n’aborderons cependant pas ce point ici.
Par défaut, fdm va chercher le fichier ~/.fdm.conf. En voici un exemple simpliste :
|
# options set maximum-size 64M set queue-high 4 set lock-file "/home/ange/.fdmlock" # actions action "inbox" maildir "/home/ange/mail/inbox" action "spam" maildir "/home/ange/mail/spamed" # comptes mails account “imap” imap server “piquant.renn.es” user "ange" pass "RLY" # règles match all action rewrite “/usr/local/bin/dspam --client --user \ ange --mode=toe --deliver=innocent,spam --stdout” continue match “^X-DSPAM-Result: spam” in headers action “spam” match “^Subject: SPAM” in headers action “spam” match all action “inbox” |
|
2.1 |
On note tout d’abord que le fichier est séparé en quatre parties : options, actions, comptes et règles.
Les options permettent de spécifier à fdm comment il doit agir par défaut (nombre de mails traités en même temps, taille maximum des mails etc.). Les actions sont des sortes de fonctions qui permettent de trier, rediriger ou passer à un autre programme pour traitement. Les comptes mails et news sont définis d’une façon relativement simple. Enfin, les règles réalisent les tris par regexp ou tags avant d’appeler les actions.
|
2.1.1 |
|
# taille maximum des mails set maximum-size 64M # nombre de mails traités en même temps set queue-high 4 # fichier de lock set lock-file "/home/ange/.fdmlock" |
Ici, j’ai choisi d’indiquer à fdm de ne pas traiter les mails de plus de 64 Mo, puis de traiter les mails par quatre maximum et enfin d’utiliser un fichier dans mon $HOME comme verrou.
|
Note |
|
queue-high permet de dire à fdm quelle est la taille maximum du buffer de traitement de mails. En effet, fdm va récupérer les mails quasiment au compte-gouttes afin d’alimenter ce buffer. Si vous avez une machine gonflée à bloc, vous pouvez pousser cette option jusqu’au maximum de 50. Mais, prenez garde de ne pas oublier que cela représente le nombre de mails maximum à traiter en même temps : si vous avez une taille maximum de 64 ou 128 Mo, cela peut commencer à faire beaucoup ! |
|
2.1.2 |
|
# tri du courrier ## dans inbox action "inbox" maildir "/home/ange/mail/inbox" ## dans spamed action "spam" maildir "/home/ange/mail/spamed" |
Toutes ces actions seront appelées dans le cadre des matchs qui suivent. Elles servent à déposer le courrier dans les bonnes boîtes (inbox, spam qui sont des maildirs).
|
2.1.3 |
|
# comptes mails account "imap" imap server "piquant.renn.es" user "ange" pass "RLY" |
On ne peut plus simple, si ? On définit un compte nommé "imap", utilisant le protocole imap pour se connecter sur le serveur piquant.renn.es avec le login "ange" et le mot de passe "RLY".
|
Note |
|
|
Si vous n’aimez pas avoir vos logins en clair, il est possible de les stocker dans un fichier .netrc :
|
|
2.1.4 |
|
# filtrage du spam match all action rewrite "/usr/local/bin/dspam --client --user \ ange --mode=toe --deliver=innocent,spam --stdout" continue # suppression du spam match "^X-DSPAM-Result: spam" in headers action "spam" match "^Subject: SPAM" in headers action "spam" # traitement de ce qui reste match all action "inbox" |
Voici le gros du boulot : le filtrage. fdm va utiliser des règles et trier le courrier en le testant avec des regexps, et des actions prédéfinies. Nous commençons par passer tout le courrier (match all) à une action de type rewrite (très similaire à un pipe sauf que fdm récupère la sortie du programme pour la traiter) vers l’antispam (ici dspam). Une fois ces mails taggués par dspam, fdm regarde leurs en-têtes et vérifie les champs "X-DSPAM-RESULT" et "Subject". S’ils sont positifs, ils sont passés à l’action spam définie plus haut. Enfin, les survivants sont passés à l’action inbox définie, elle aussi, précédemment.
|
Note |
|
L’option continue indique à fdm de ne pas arrêter le traitement du mail à cette règle et de le faire passer par les règles qui suivent. |
|
2.2 |
En résumé : fdm se connecte au compte imap, passe tous les mails à dspam, sépare le spam du courrier valide, livre via l’action "spam" les spams et via l’action "inbox" le courrier sain.
Voilà pour une configuration simple, et efficace. Si vous avez des besoins réduits, ça devrait vous suffire. Cependant, certains aiment avoir une configuration aux petits oignons, le genre qui fait beaucoup de choses toute seule : le thé, les cookies et la confiture !
|
3 |
Loutre que nous sommes, nous allons vite avoir besoin de petits trucs en plus pour faire certaines manipulations pratiques : traitement des spams, faux négatifs et faux positifs, archivage du contenu de l’inbox, des mailings lists et des spams… Tout le genre de choses pour lesquelles on serait tenté de faire des scripts en Perl (par exemple).
Cependant, avant de passer au gros morceau, il me faut introduire deux notions qui vont nous simplifier la vie dans cette configuration : les macros et les tags.
|
3.1 |
Les macros sont en fait des variables, qui nous servent ici à stocker le chemin vers dspam et le nom du user. La syntaxe est différente suivant le type de données que vous voulez stocker dans la macro. Un % précède le nom de la macro si la donnée stockée est un nombre, un $ si c’est une chaîne.
|
%macro_nombre = 123 $userm = "ange" |
Lors de l’inclusion d’une macro dans une chaîne de caractères, il faut l’entourer d’accolades comme ceci :
|
account "local" maildir "/home/${userm}/mail/inbox" |
|
3.2 |
fdm ajoute un certain nombre de tags à chaque mail qu’il traite, ce qui nous aidera pour le filtrage et le tri. Voici les plus utiles
account : le compte dont le mail provient.
home : le $HOME de l’utilisateur.
hour, minute, second, day, month, year, year2 : pour trier en fonction de la date, et de l’heure de l’exécution (!!). year est l’année complète (2008), year2 l’année abrégée à deux chiffres (exemple : 08 pour 2008).
mail_hour, mail_minute, mail_second, mail_day, mail_month, mail_year, mail_year2 : pour trier en fonction de la date, et de l’heure du mail. Même remarque pour "mail_year2" que pour "year2" : les deux derniers chiffres seulement.
server : ajouté lorsque le mail vient d’un compte imap ou pop.
Les tags sont utilisables au sein d’actions et de règles, comme les tags "year2", "month" et "account" dans les exemples suivants :
|
# action action "spam_arch" maildir "/home/${userm}/mail/spam/%[year2].%[month]" # règle match string “%[account]” to “librium_imap” action “spam_test” continue |
|
3.3 |
Voici le gros morceau. Cette fois-ci non seulement fdm récupère le courrier sur le compte imap, le traite contre le spam, mais il archive aussi les vieux mails et les vieux spams, et, pour finir, traite les faux positifs et faux négatifs afin que l’antispam ne se plante plus les fois suivantes.
|
# MACROS $dspam = "/usr/local/bin/dspam" $userm = "ange" # OPTIONS set maximum-size 64M set queue-high 4 set lock-file "/home/${userm}/.fdmlock" # ACTIONS 1 action "inbox" maildir "/home/${userm}/mail/inbox" action "spam" maildir "/home/${userm}/mail/spamed" # ACTIONS 2 # spam testing action "spam_test" rewrite "${dspam} --client --user ${userm} --mode=toe --deliver=innocent,spam --stdout" # entrainement de dspam ## faux negatifs action "spam_fn" { rewrite "${dspam} --client --user ${userm} --class=spam --source=error" action “spam” } ## faux positifs action "spam_fp" { rewrite "${dspam} --client --user ${userm} --class=innocent --source=error" action “inbox” } |
|
# ACTIONS 3 # archivage des spams action "spam_arch" maildir "/home/${userm}/mail/spam/%[year2].%[month]" # archivage des mails action "archivage" maildir "/home/${userm}/mail/old/%[mail_year2].%[mail_month]" # COMPTES # imap account “imap” imap server “piquant.renn.es” user “ange” pass “RLY” # COMPTES locaux # (archivage, spam training ...) account "local" maildir "/home/${userm}/mail/inbox" account "local_spam" maildir "/home/${userm}/mail/spamed" account "local_fp" maildir "/home/${userm}/mail/unspam" account "local_fn" maildir "/home/${userm}/mail/spam" # REGLES ## Filtrage du Spam # traitement par dspam match string "%[account]" to "librium_imap" action "spam_test" continue # spam quick dropping (mici gaston) match string "%[account]" to "librium_imap" and "^X-DSPAM-Confidence: 0.[89].*" in headers and "^X-DSPAM-Result: spam" in headers action "drop" # livraison du spam match string "%[account]" to "librium_imap" and "^X-DSPAM-Result: spam" in headers action "spam" match string "%[account]" to "librium_imap" and "^Subject: SPAM" in headers action "spam" |
|
## livraison # livraison des mails dans l’inbox match string "%[account]" to "librium_imap" action "inbox" ## Archivage match string "%[account]" to "local" and age > 3 months action "archivage" match string "%[account]" to "local_spam" and age > 7 days action "spam_arch" # Entrainement de *dspam* match string "%[account]" to "local_fn" action "spam_fn" match string "%[account]" to "local_fp" action "spam_fp" |
|
3.3.1 |
On a vu que les macros nous permettent de définir des variables pour simplifier la configuration. Ici, nous définissons deux variables : le chemin absolu vers l’antispam et le nom de notre utilisateur.
|
3.3.2 |
On reprend ici les mêmes options que dans la configuration simple, pas besoin de plus.
|
3.3.3 |
On retrouve ici les actions que nous utilisions dans la première configuration. Elles servent, rappelons- le, à livrer le mail dans les maildirs inbox et spam.
|
3.3.4 |
Cette fois-ci, nous avons créé une action dédiée pour l’antispam. On retrouve la même action rewrite que dans la configuration précédente, simplement déplacée pour éclaircir la configuration.
Cette action est complétée par deux autres qui servent à traiter les erreurs de dspam. En effet, parfois un spam peut passer entre les mailles du filet et atterrir dans votre inbox (faux négatifs) ou l’inverse : un mail valide peut atterrir dans vos spams (faux positifs).
Je pars ici du principe que vous placez, comme moi, les erreurs dans des maildirs temporaires dédiées avant de les faire repasser automatiquement à votre antispam. Nous utiliserons donc un maildir spam qui servira pour les faux négatifs, et un maildir unspam pour les faux positifs. Ainsi, à chaque fois que fdm sera lancé, il regardera dans ces deux maildirs pour les repasser à dspam en lui disant qu’il s’est trompé. Enfin, fdm les replacera dans les bons maildirs.
Cela implique deux actions : un appel à dspam, puis une livraison. Heureusement, fdm permet d’écrire des actions " complexes " composées de plusieurs actions. La syntaxe est relativement intuitive pour peu que vous ayez utilisé un langage comme Perl, Ruby, C ou PHP (et d’autres), puisqu’elle utilise des accolades :
|
action "spam_fn" { # appel de fdm rewrite “${dspam} --client --user ${userm} --class=spam --source=error” # livraison par l’action spam action “spam” } |
|
3.3.5 |
L’archivage est quelque chose de relativement pratique si vous ne faites pas de ménage dans vos mails régulièrement. Nous avons vu que les tags nous permettaient d’avoir accès aux informations comme la date d’exécution, et la date du mail, exactement ce qu’il nous faut. Nous verrons dans les règles comment décider qu’un mail doit être archivé. Ici, nous n’allons voir que l’action de livraison dans les archives.
Dans le cas des spams, nous ne pouvons pas nous baser sur la date du mail. À la place, nous utiliserons la date d’exécution fournie par les tags "year2" (année, en deux chiffres) et "month" (mois) :
|
# archivage des spams action "spam_arch" maildir "/home/ange/mail/spam/%[year2].%[month]" |
Cette action livre donc les spams dans un maildir dont le nom est de la forme "08.01". Fort pratique ! Si on vous dit qu’on vous a envoyé un mail il y a deux ou trois semaines de ça et que vous ne l’avez jamais vu, il suffit d’aller dans les archives de spam pour vérifier s’il n’a pas été désigné comme spam.
Dans le cas du courrier " valide ", on peut se baser sur la date du mail (en général) et donc utiliser les tags "mail_year2" et "mail_month" :
|
# archivage des mails action "archivage" maildir "/home/ange/mail/old/%[mail_year2].%[mail_month]" |
|
3.3.6 |
Ici, nous retrouvons notre compte imap en compagnie de comptes locaux. Ces derniers seront utilisés pour les actions d’archivage et de traitement des erreurs de l’antispam.
|
3.3.7 |
On retrouve les règles de la configuration précédente légèrement modifiées. La principale modification vient du fait que nous avons désormais plusieurs comptes traités. Pour s’assurer que seuls les mails provenant du serveur IMAP sont traités par l’antispam, il nous faut tester le tag "account" et ne faire passer que les mails venant du compte "librium_imap" :
|
# traitement par dspam match string "%[account]" to "librium_imap" action "spam_test" continue |
Afin de limiter la quantité de spam, on va utiliser un en-tête rajouté par dspam dans les mails : "X-DSPAM-Confidence". Cet en-tête indique la confiance de dspam dans son jugement. On peut considérer que, s’il est très sûr de lui (entre 0.8 et 0.9), on peut directement supprimer (drop) ces mails. Ce que fait cette règle :
|
# spam quick dropping (mici gaston) match string "%[account]" to "librium_imap" and "^X-DSPAM-Confidence: 0.[89].*" in headers and "^X-DSPAM-Result: spam" in headers action "drop" |
Notez que l’on prend soin de vérifier que c’est effectivement un spam (test de l’en-tête X-DSPAM-Result), car pour les mails valides (ou classés "whitelist"), dspam peut aussi être sûr à 0.8 ou 0.9. Enfin, si je dis ça, ce n’est pas du tout parce que j’ai perdu des mails comme ça, non non du tout.
|
Note |
|
La confiance de dspam est toujours supérieure à 0.0 (0%) et strictement inférieure à 1.0 (100%), car il ne peut jamais être totalement sûr de son jugement. |
Cette possibilité de cumuler les tests, avec les mots clés "and" et "or", est une des fonctionnalités les plus pratiques pour faire des configurations un peu léchées. Ainsi, il faut que le mail passant par la règle vérifie l’une et l’autre des conditions ou l’une ou l’autre.
Enfin, il nous reste à livrer les spams dans la boîte appropriée, ce qui est fait ici en appelant l’action spam comme dans le précédent exemple :
|
# livraison du spam match string "%[account]" to "librium_imap" and "^X-DSPAM-Result: spam" in headers action "spam" match string "%[account]" to "librium_imap" and "^Subject: SPAM" in headers action "spam" |
|
3.3.8 |
On retrouve la livraison dans l’inbox, avec juste l’ajout de la vérification du compte de provenance :
|
# livraison des mails dans l’inbox match string "%[account]" to "librium_imap" action "inbox" |
|
3.3.9 |
L’archivage en lui-même est réalisé par les actions "archivage" et "spam_arch" présentées plus haut. Ici, nous allons voir comment décider si un mail est bon pour les cartons ou pas. Pour cela, nous utilisons le très très utile mot clé "age".
Dans le cas des mails sains (vérification du compte de provenance : "local"), considérons qu’ils doivent être archivés s’ils ont plus de trois mois :
|
match string "%[account]" to "local" and age > 3 months action "archivage" |
Et dans le cas des spams, nous les archiverons s’ils ont plus de 7 jours :
|
match string "%[account]" to "local_spam" and age > 7 days action "spam_arch" |
|
3.3.10 |
Nous avons déjà vu comment repasser les mails à dspam pour qu’il s’améliore. Voici comment piocher dans les deux répertoires temporaires :
|
# Entrainement de *dspam* match string "%[account]" to "local_fn" action "spam_fn" match string "%[account]" to "local_fp" action "spam_fp" |
|
4 |
|
4.1 |
Avec de pareilles configurations, il est utile d’avoir de quoi tester avant de mettre en production. Pour cela, rien de plus simple : l’option "-n" permet de faire lire le fichier de configuration par fdm. Pour que ce soit vraiment classe, il faut utiliser une bonne dose de "-v" et finir par l’option "-f" qui permet de spécifier quel fichier on veut tester :
|
$> fdm -vvvvnf fdm.conf version is: fdm 1.4, started at: Wed Feb 20 15:29:50 2008 [...] user is: ange, home is: /home/ange loading configuration from fdm.conf fdm.conf: world readable or writable added macro "$dspam": "/usr/local/bin/dspam" added macro "$userm": "ange" added action "inbox": deliver=0:maildir "/home/ange/mail/inbox" added action "spam": deliver=0:maildir "/home/ange/mail/spamed" added action "spam_test": deliver=0:rewrite "/usr/local/bin/dspam --client --user ange --mode=toe --deliver=innocent,spam --stdout" added action “spam_fn”: deliver=0:rewrite “/usr/local/bin/dspam --client --user ange --class=innocent --source=error” [...] options are: maximum-size=67108864, timeout=900, default-user=1001, file-umask=077, queue-high=4, queue-low=3, lock-file=”/home/ange/.fdmlock”, strip-characters=”\<>$%^&*|{}[]”’`;” using tmp directory: /tmp $> |
|
Note |
|
|
Le petit message "fdm.conf: world readable or writable" indique que le fichier est lisible (ou modifiable) par tous (pas bien). Il vaut donc mieux faire un petit changement de droits :
|
|
4.2 |
Maintenant que nous avons testé notre configuration, il ne nous reste plus qu’à lancer la bête sur la foule innocente :
|
$> fdm -f /home/ange/.fdm.conf -vv -u ange fetch |
L’option -u permet de spécifier l’utilisateur par défaut et l’option -f permet de spécifier le fichier de configuration à utiliser (déjà vu). Enfin, le mot clé fetch indique à fdm de récupérer les mails et de les traiter.
|
Note |
|
Le mot clé poll à la place de fetch permettrait simplement d’obtenir le nombre de mails par compte. |
|
4.3 |
L’exécution automatisée est évidemment d’une grande utilité. Il suffit de rajouter l’option -l à la commande précédente pour indiquer à fdm d’utiliser syslog et non stderr pour publier ses logs :
|
$> cat /etc/crontab | grep fdm */5 * * * * ange /usr/local/bin/fdm -f /home/ange/.fdm.conf -l -u ange fetch |
Ainsi, fdm sera lancé par cron toutes les 5 minutes.
|
5 |
Quelques petits points qui mériteraient aussi d’être traités plus amplement.
|
5.1 |
|
set proxy "<url_proxy>" |
Si vous devez passer à travers un proxy pour sortir de votre réseau, alors cette option vous sauvera sûrement. Les proxys HTTP et SOCKS5 sont supportés.
|
5.2 |
|
set verify-certificates |
Cette option permet d’indiquer à fdm de vérifier les certificats SSL des serveurs de mails. Il est possible de spécifier compte par compte de ne pas vérifier le certificat en utilisant l’option no-verify dans la définition d’un compte.
|
account "imaps one" imaps server "imap.poi.re" no-verify |
|
5 |
Voilà un tour rapide de ce qui est possible avec fdm. Il manque plein plein de choses encore, mais il faudrait écrire un livre sur cet outil tellement il a d’options, de possibilités, etc. Pour ceux qui voudraient en savoir plus, je ne peux que les encourager à lire la documentation fort bien fournie disponible sous forme de man évidemment, mais aussi sur le site de fdm [1].
Comme d’habitude, ce n’est probablement pas la panacée, et certains trouveront à redire et préféreront rester avec les solutions dont ils ont l’habitude, c’est leur droit : chacun ses goûts. Cependant, je pense que cet outil, méconnu, mérite que l’on s’y attarde un peu ne serait-ce que pour voir des choses nouvelles. Au pire, vous passerez 10 minutes à adapter une des deux configurations de l’article à vos besoins pour quitter vos vieux compagnons procmail et fetchmail, auxquels vous n’êtes pas mariés… (après tout).
Merci à M. _M pour m’avoir fait découvrir dspam et à M. G pour fdm, deux outils dont je ne peux plus me passer. Merci aux lutins relecteurs (M. _a notamment) sans qui cette prose ne serait vraiment pas aussi bien.
|
Bibliographie, webographie, mailographie… |
|
" fdm, le projet : http://sourceforge.net/projects/fdm et la doc : http://fdm.sourceforge.net/. " tdb, le projet : http://sourceforge.net/projects/tdb/. |
Retrouvez cet article dans : Linux Magazine Hors série 36





Laissez une réponse
Vous devez avoir ouvert une session pour écrire un commentaire.