milter-regex : expressions régulières anti-spam pour Sendmail

On peut ajouter à Sendmail un anti-spam très simple, basé sur des expression régulières étendues : milter-regex ; dans http://www.pkgsrc.org, il s'agit du paquet mail/milter-regex.

Le principe est simple :

  • un daemon milter-regex attend les connexions (sur une socket UNIX ou INET / INET6),
  • le MTA qui s'y connecte « parle » Milter (le protocole mis au point pour Sendmail 8.12 pour normaliser les connexions aux filtres) ⇒ il s'agit de Sendmail 8.12 ou plus (ou d'une version récente de Postfix),
  • lorsque le MTA lui passe un message, le daemon le filtre suivant un fichier de configuration,
  • il répond au MTA si le message est acceptable ou non.

Lors de chaque connexion du MTA, le daemon vérifie que le fichier de configuration n'a pas été modifié ; dans le cas contraire, il le relit avant de traiter le message. On n'a donc pas besoin de relancer le daemon milter-regex à chaque modification.

Avant de l'installer, vérifier au préalable que Sendmail est bien compilé avec le support de Milter :

$ sendmail -bt -d0.4 </dev/null|grep MILTER
 Compiled with: FOO MILTER BAR

sans quoi il faut commencer par installer une version plus complète du MTA.

Ajouter la ligne suivante dans /etc/mail/sendmail.cf :

Xmilter-regex, S=unix:/var/spool/milter/milter-regex.sock, T=S:30m;R:20m

et indiquer à Sendmail d'utiliser ce filtre :

O InputMailFilters=milter-regex

Pour utiliser plusieurs filtres, la variable InputMailFilters attend les différents noms séparés par des virgules :

O InputMailFilters=milter-regex,mimedefang

Lancer le filtre puis relancer sendmail(8). Attention au fichier socket (emplacement et surtout droits).

Évidemment, tout cela n'est possible que si Sendmail dispose de la bibliothèque Milter… Ne pas oublier de configurer le système pour que milter-regex(8) se lance avant le MTA. De plus, vérifier que le script de lancement supprime le fichier de socket et de PID en cas de reprise après un crash.

Les règles se présentent sous la forme de blocs de plusieurs lignes.

Une première ligne indiquant la réponse et commençant par l'un des mot-clefs : reject, tempfail, quarantine, discard, ou accept ; les trois premiers sont suivis d'un message de renseignement ; reject renvoie une erreur SMTP 554, tempfail une erreur 471.

Les lignes suivantes indiquent quoi chercher :

  • connect ou helo : pour filtrer sur l'origine de la connexion
  • envfrom ou envrcpt : pour filtrer l'enveloppe
  • header ou body : pour filtrer sur les entêtes ou le corps du message
  • macro : pour filtrer à l'aide d'une valeur d'une macro Sendmail

Quelques exemples:

reject "Banned email (bad x-mailer), see http://www.example.com/mail-filter.html"
header ,X-Mailer: DOPOST 1.1 (Build Nov  4 2005), (c) www.dolist.net, ,,

reject "Banned email (bad subject), see http://www.example.com/mail-filter.html"
header ,Subject, ,junk email out of control,i
header ,Subject, ,{subj190107},
header ,Subject, ,WINNING NOTIFICATION,i
header ,Subject, ,RE: MedHelp [0-9]*,i
header ,Subject, ,777,
header ,Subject, ,The\ Pharmacy\ America\ Trusts,i
header ,Subject, ,What\ Is\ 0EM\ Software\ And\ Why\ Do\ You\ Care\?,i
header ,Subject, ,s(e|3)(x|><),ei
header ,Subject, ,v(i|!|\||1)(a|4)(r|g)(g|r)(a|4),ei
header ,Subject, ,s(o|0)ftware,ei

reject "Banned email (no spaces, spoofing), see http://www.example.com/mail-filter.html"
header ,From, ,\".*\ .*\"@example\.com,ei

Ici, les messages d'erreur indiquent tous une page web donnant des raisons potentielles de refus et un contact (en cas de faux positif).

Mieux vaut éviter les filtres sur body, elles surchargent très vite le serveur. De plus, au delà de quelques centaines, les expressions régulières étendues (drapeau e en fin de règle) ralentissent aussi sensiblement le serveur. Ces deux remarques sont évidemment fortement dépendantes du trafic SMTP.

:!: Suivant la valeur de Milter.LogLevel (renseigné dans /etc/mail/sendmail.cf), attention à ce qui est journalisé : le niveau 17 journalise en-têtes et corps du message envoyés au(x) filtre(s) Milter. Outre un problème de déontologie évident, un souci de logique non moins évident (pourquoi stocker le message si on le journalise ? ou inversement…), les journaux deviennent très très verbeux très très vite.

On peut filtrer les messages syslog(3), par exemple avec Syslog-NG comme indiqué ici.

  • user/pc/sysadmin/sendmail-milter-regex.txt
  • Dernière modification : 2011/07/22 18:25
  • de pc