Filtrer sans Amavis

Amavis c'est pas mal, mais il est maintenant plus simple d'utiliser un outil nommé «Clamsmtp». Il est écrit pour être utilisé comme un filtre de contenu dans Postfix.

Comme «Spamassassin» peut également être utilisé comme un filtre de contenu, avec un peu d'astuce, il est possible de se passer d'Amavis, à moins de vouloir profiter de toutes ses subtilités.

Nous utilisons ici une Debian Stretch, Postfix est en version 3.1.8.

Postfix propose deux manières d'implémenter un filtre de contenu sur les messages entrants et nous en avons vu une au chapitre précédent pour exploiter amavis. Ici nous allons utiliser ces deux manières, l'une pour exploiter spamassassin et l'autre pour clamav sous sa forme clamsmtp.

Filtrer avec Spamassassin

Voici une nouvelle manière d'insérer un filtre de contenu après la file d'attente des messages entrants.

Spamc et spamd

Le client spamc est normalement installé étant recommandé par le paquet spamassassin. Il fait appel au service spamd qui, lui, est installé avec spamassassin. Vérifier que les paquets spamassassin et spamc sont bien installés.

Nous pouvons vérifier le fonctionnement correct du filtre en créant un fichier texte nommé par exemple spam.txt contenant juste ceci:

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

Il faut alors injecter ce fichier dans le filtre via spamc:

spamc < spam.txt

et observer le résultat:

Received: from localhost by ns236363.ovh.net
	with SpamAssassin (version 3.4.0);
	Tue, 24 May 2016 10:00:23 +0200
Subject: [SPAM] 
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ns236363.ovh.net
X-Spam-Flag: YES
X-Spam-Level: *******
X-Spam-Status: Yes, score=7.9 required=5.0 tests=EMPTY_MESSAGE,MISSING_DATE,
	MISSING_FROM,MISSING_HEADERS,MISSING_MID,MISSING_SUBJECT,NO_HEADERS_MESSAGE,
	NO_RECEIVED,NO_RELAYS autolearn=no autolearn_force=no version=3.4.0
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----------=_57440A17.FF47C9F8"

This is a multi-part message in MIME format.

------------=_57440A17.FF47C9F8
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: 8bit

------------------ Début de Rapport SpamAssassin ---------------------
Ce message est probablement du SPAM (message non sollicité envoyé en
masse, publicité, escroquerie...).

Cette notice a été ajoutée par le système d'analyse "SpamAssassin" sur
votre serveur de courrier "ns236363.ovh.net", pour vous
aider à identifier ce type de messages.

Le système SpamAssassin ajoute un en-tête "X-Spam-Flag: YES" aux
messages qu'il considère comme étant probablement du Spam.
Vous pouvez si vous le souhaitez utiliser cette caractéristique
pour régler un filtre dans votre logiciel de lecture de courrier,
afin de détruire ou de classer à part ce type de message.

Si ce robot a classifié incorrectement un message qui vous était
destiné, ou pour toute question, veuillez contacter l'administrateur
du système par e-mail @ the administrator of that system .

Voir http://spamassassin.apache.org/tag/ pour plus de détails (en anglais).

Détails de l'analyse du message:   (7.9 points, 5.0 requis)
-0.0 NO_RELAYS              Informational: message was not relayed via SMTP
 1.2 MISSING_HEADERS        Le message ne comporte pas l'en-tête To:
 1.0 MISSING_FROM           Missing From: header
 1.8 MISSING_SUBJECT        Missing Subject: header
 2.3 EMPTY_MESSAGE          Message appears to have no textual parts and no
                            Subject: text
-0.0 NO_RECEIVED            Informational: message has no Received headers
 1.4 MISSING_DATE           En-tête "Date:" absent
 0.1 MISSING_MID            Missing Message-Id: header
 0.0 NO_HEADERS_MESSAGE     Message appears to be missing most RFC-822 headers

-------------------- Fin de Rapport SpamAssassin ---------------------



------------=_57440A17.FF47C9F8
Content-Type: message/rfc822; x-spam-type=original
Content-Description: original message before SpamAssassin
Content-Disposition: inline
Content-Transfer-Encoding: 8bit

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X


------------=_57440A17.FF47C9F8--

Nous pouvons constater:

  1. que le filtrage fonctionne;
  2. que la sortie de spamc lui-même un message contenant:
    • les en-têtes spécifiques (X-Spam…);
    • un rapport détaillé, ici en français, de l'analyse.

Connexion à postfix

Il faut, dans master.cf, configurer postfix pour délivrer le message au filtre de contenu via l'agent de livraison pipe comme ceci:

# 
# spamassassin
# 
spamassassin unix -     n       n       -       -       pipe
  flags=R
  user=debian-spamd
  argv=/usr/bin/spamc -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}

Spamc va ainsi recevoir le message à transmettre à spamd qui va l'analyser et ressortir le résultat sur sendmail qui le ré-injectera dans le système.

Ensuite, toujours dans master.cf, d'ajouter au service smtp l'option content_filter=spamassassin comme ceci:

smtp      inet  n       -       -       -       -       smtpd
 # connexion à spamassassin :
  -o content_filter=spamassassin
La sortie de spamc que nous avons étudiée plus haut est ré-injectée dans le système avec la commande sendmail. Ce message, émis localement (Received: from localhost) ne sera pas traité par smtpd pas par pickup et donc ne repassra pas par le filtre, ce qui est bien entendu préférable faute de quoi une boucle sans fin serait créée.

Filtrer avec clamsmtp

ClamSMTP a été conçu pour être utilisé comme un filtre de contenu pour Postfix:

ClamSMTP aims to be lightweight, reliable, and simple rather than have a myriad of options. It's written in C without major dependencies. If you need more options then you could use something big like AMaViS which is written in PERL and can do almost anything. (Documentation officielle).

Nous allons ici utiliser ce filtre comme nous l'avons fait pour Amavis, en utilisant l'autre méthode proposée par Postfix. Nous devons avoir installé clamsmtp qui a son tour installera clamav et tous ses accessoires.

Ici, tous les messages passeront dans le filtre, y compris ceux qui sont émis localement.

Configuration de clamsmtp

Le fichier de configuration /etc/clamsmtpd.conf peut se résumer à 5 lignes:

OutAddress: 10025
Listen: 127.0.0.1:10026
ClamAddress: /var/run/clamav/clamd.ctl
TempDirectory: /var/spool/clamsmtp
PidFile: /var/run/clamsmtp/clamsmtpd.pid
User: clamav
Le filtre va ici écouter sur le port 10026 de l'interface localhost et transmettra ses résultats sur le port 10025. Ceci est la configuration par défaut sur la Debian Jessie, mais les deux ports peuvent bien entendu être inversés si l'on préfère placer l'entrée avant la sortie (ou la sortie après l'entrée).

Il est important en revanche, de faire fonctionner clamav-daemon et clamsmtp sous la même identité, pour éviter d'éventuels ennuis de droits d'accès lors des échanges entre clamsmtp et le service clamav.

Injection dans postfix

Dans master.cf nous créons un transport nommé par exemple scan comme ceci:

scan        unix   -    -       n       -       16      smtp
  -o smtp_send_xforward_command=yes
La méthode est tout à fait similaire à celle employée pour connecter Amavis, au chapitre précédent.

Nous devons aussi créer un socket pour ré-injecter les sorties de clamsmtp:

# For injecting mail back into postfix from the filter
127.0.0.1:10025 inet   n   -   n   -   16   smtpd
  -o content_filter=
  -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
  -o smtpd_helo_restrictions=
  -o smtpd_client_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=permit_mynetworks,reject
  -o mynetworks_style=host
  -o smtpd_authorized_xforward_hosts=127.0.0.0/8
Le port d'écoute doit naturellement correspondre au port de sortie de clamsmtp Enfin, nous devons invoquer ce filtre, mais cette fois-ci dans main.cf en ajoutant la ligne:
#
# clamsmtp
#
content_filter = scan:127.0.0.1:10026
Le port indiqué ici doit naturellement correspondre à celui qui est indiqué pour l'écoute de clamsmtp

Bilan

Cette méthode plus simple à appréhender que celle faisant appel à amavis répondra probablement à la plupart des besoins tout en chargeant un peu moins le système.