Pyzor bouffe-t-il mes spams ?

Si vous hébergez votre courrier électronique, vous aurez probablement besoin un jour ou l'autre d'un antispam. Ce dératiseur des temps modernes est hélas nécessaire dès l'instant où vous avez eu le malheur de laisser votre adresse email traîner quelque part sur le web...

Heureusement, des solutions libres et rodées de dératisation existent. Le but est toujours le même, distinguer un spam (message indésirable) d'un ham (message légitime).

Plusieurs méthodes existent :

  • Basées sur des listes noires d'IPs de "spameurs", par exemple spamhaus ;
  • exploitant un "filtre bayésien", c'est à dire un filtre dont vous affinez le jugement au fur et à mesure que vous l'éduquez en lui indiquant lorsqu'il se trompe, c'est le cas de SpamAssassin ;
  • utilisant une base de données de spams connus, c'est le cas de pyzor, solution étudiée dans cet article.

J'ai choisi de tester pyzor par curiosité, parce-que les systèmes de listes noires sont hyper-centralisés et ont tendance à avoir la main lourde1. Par ailleurs, j'ai une hantise des faux positifs et la dernière solution est censée en produire peu.

Comment Fonctionne pyzor ?

L'idée originale semble venir du logiciel Vipul's Razor. Basiquement, il s'agit de répertorier les spams "types" qu'on peut recevoir dans une base de données. Il est ensuite possible de vérifier si tel ou tel courrier est un spam "connu".

L'inconvénient est que les spams, même si ils se ressemblent souvent, contiennent de légères différentes, ne serait-ce que pour vous dire que "Cher Monsieur Dulandeau", ou bien même les en-têtes du message...

Pour pallier à cet inconvénient, pyzor utilise seulement une partie du message : les en-têtes ne sont pas prises en compte, puis n% du message est gardé, x lignes sont sautées, m% du messages conservé... etc (cf l'algorithme détaillé). Du message restant, on extraira une somme de contrôle (hash), bien plus pratique à stocker.

Au niveau architecture, le serveur contient une base de hash de spams connus et chaque client est configuré pour causer à un unique serveur auquel il peut :

  • Demander si un message est un spam connu ;
  • rapporter un spam ;
  • rapporter un ham (courrier légitime).

Installation

Il y a plusieurs manières de configurer pyzor. J'ai choisi de le faire au niveau utilisateur, en utilisant le fichier ~/.forward.

apt-get install pyzor

Tester les mails entrants

On utilise pour appeler pyzor à chaque mail entrant et faire le tri l'excellentl fdm2. La configuration se fait dans ~/.fdm.conf :


#
## MACROS
#

# Je stocke mes mails dans /home/user/.maildir :
$maildir       = "%h/.maildir" # À ADAPTER

#
## COMPTES
#
account "spam" maildir "${maildir}/.Junk"

# Les mails entrants (traitement à chaque mail reçu.)
account "incoming" stdin

#
## ACTIONS
#
# Utilitaires :
#
action "mark-as-read" exec "mf=\"%[mail_file]\" ; mv \"\${mf}\" \"\${mf%%/*}\"/../cur/\"\${mf##*/}:2,S\""

#
# Distribution principale :
#
action "inbox" maildir "%h/.maildir"

#
# Traitement du Spam :
#
action "spam" {
  maildir "${maildir}/.Junk"
  action "mark-as-read"
}

# Filtrage du spam avec pyzor
match account "incoming" and pipe "pyzor check" returns (0,) action   "spam"

# Règle par défaut
match account "incoming" action "inbox"

Il faut ensuite éditer le fichier ~/.forward afin que le MTA sache qu'il doit confier la livraison du courrier à FDM pour l'utilisateur concerné :

"|/usr/bin/fdm -m -a incoming fetch"

À ce stade, la détection est déjà opérationnelle... Mais comment réagir lorsqu'un spam survit à notre tambouille de mort-aux-rats maison ?

Rapporter les spams non détectés

Pour améliorer la détection dans le futur, pas d'états d'âme… Il faut moucharder le spam non détecté au serveur !

Pour ça, faisons simple :

  • On crée un dossier IMAP nommé spam viking3 par exemple (votre client mail le fait très bien) ;
  • lorsqu'on reçoit un spam non filtré, on "nourrit" le dossier spam viking avec ;
  • périodiquement, tous les mails dans le dossier spam viking sont raportés au serveur pyzor.

Une fois le dossier créé, ajouter ces lignes au ~/fdm.conf :


account "spam_viking" maildir "${maildir}/.spam viking"

action "report_as_spam" {
  pipe "pyzor report"
  action "spam"
}

match account "spam_viking" action "report_as_spam"

Enfin, il s'agit de demander au système de rapporter les spams, disons tous les jours à 5h42. On utilise pour ça l'outil cron :

$ crontab -e

puis ajouter la ligne suivante au fichier ouvert :

42   5  *      *      * /usr/bin/fdm -l fetch -a "spam_viking"

Et euh... ça marche ?

Lors de mes recherches sur pyzor et consorts, j'ai été très surpris de constater qu'on trouvait difficilement des tests d'efficacité. Histoire de faire avancer le bouzin, j'ai fait mes propres mesures quand à l'efficacité de pyzor qui valent ce qu'elles valent. Au passage, elles permettent de se faire une idée de la quantité de spam qu'on peut avoir à traîter lorsqu'on s'auto-héberge et qu'on expose un peu son adresse sur le web.

  • Ces chiffres concernent que le courrier reçu sur une unique boîte email (la mienne, que j'utilise au quotidien);
  • les compteurs sont relevés tous les jours pendant 41 jours;
  • Le serveur mail est auto-hébergé sur une ligne ADSL.

Détection du spam sur un mois avec Pyzor

spams reçus détectés par Pyzor efficacité
sur 41 jours 219 79 36.8%
moy. quotidienne 5.9 2 36.8%

.... 37% d'efficacité.... pas terrible ! Les filtres bayésiens font sans aucun doute mieux après un bon entraînement. Et la mesure des faux positifs me demanderez-vous ? Eh bien, c'est simple... sur cette période de 41 jours, je n'ai relevé aucun faux positif !

Conclusion

Avantages

  • Aucun faux-positif ;
  • simple à installer, pas d'apprentissage ;
  • client et serveur open-source4
  • ne semble pas trop gourmand en ressources;
  • principe d'intelligence collective.

Inconvénients

  • Détection peu efficace ;
  • architecture centralisée.

Perspectives

J'ai commencé ces mesures avec pyzor a une époque où la quantité de spam devenait pénible à gérer à la main... On constate sur le graphe que depuis les choses se sont calmées5. Je pourrais donc à priori conserver pyzor, qui me réduit un peu la tâche, sans risque de faux positif.

Cependant, si je revenais à des volumes plus élevés, j'envisagerais clairement autre-chose que Pyzor.

Par ailleurs, pour ces tests, j'ai utilisé le serveur public proposé par pyzor (configuration par défaut). Par ailleurs, je n'ai pas envie à terme de compter sur un service externe et central. ; aussi j'aimerais essayer de monter mon propre service, pour voir quelle efficacité cela peut avoir (vu que c'est basé sur une connaissance exhaustive de tous les spams, j'ai des doutes...). Il est tout-à-fait envisageable d'entraîner un serveur pyzor avec des archives de spam pour l'initialiser.

Dans un monde génial et multicolore (celui que nous construisons ;-)), on pourrait même envisager un fonctionnement en fédération de serveurs qui papotent entre eux pour s'échanger du hash... chiche ?


  1. Pour l'anecdote, mon IP a été blacklistée avant qu'elle n'émette le moindre mail, et je ne semble pas être le seul parmi les auto-hébergés). Il semblerait que l'appartenance d'une IP au bloc d'un FAI grand public suffise à un accès internet de particulier suffise à sa mise à l'index... (+ d'infos sur les listes noires

  2. Bien sûr, un autre LDA tel que procmail ferait l'affaire également... 

  3. Mais d'où diable vient ce nom de dossier idiot ?.. peut-être bien de l'origine même du terme spam... 

  4. Je précise car le serveur de vipul's razor est propriétaire... 

  5. cette accalmie pourrait-être liée au fait que le serveur a changé deux fois d'IP (déménagement) sur cette période et été indisponible quelques heures à ces occasions. J'ai peut-être été ainsi rayé des listes de serveurs "spamables", si de l'expérience là-dessus...