Anti-spam : le greylisting

, par Nil

Vous êtes inondés de spam, nous sommes inondés de spam, tout le monde est inondé de spam.... Que faire ? Les moyens d’action sont de toute manière limités, car il s’agit toujours d’une course entre les pollueurs numériques et les utilisateurs, chacun tentant de contrecarrer les innovations techniques de l’autre, et de prendre un peu d’avance à l’occasion.

Chez Globenet et No-log, on a mis en place un système de greylisting. Explications.

Principes

Installer un filtre anti-spam « classique » (genre SpamAssassin) sur No-log est exclu pour l’instant, car la charge de travail occasionnée par la vérification de tous les courriels serait beaucoup trop lourde pour nos serveurs. Sur les serveurs de l’hébergement mutualisé, cette solution n’est pas non plus mise en place pour le moment.

De plus, scanner les messages signifierait un peu utiliser un logiciel pour les ouvrir, les lire et décider à la place de leur destinataire de les jeter, et on n’aime pas trop ça... Alors pour contrer les spams, No-log utilise une autre technique, celle du greylisting ; elle est un peu différente des méthodes anti-spam habituelles, et cela a quelques conséquences pour les utilisateurs.

En gros, elle consiste à bloquer a-priori l’arrivée des courriels inconnus, jusqu’à ce que le serveur de l’émetteur essaye de nouveau. Attention, on parle ici du serveur de messagerie, pas de la personne qui a envoyé le message, qui, elle, ne se rendra compte de rien. En envoyant à nouveau le courriel, ce qui est prévu par les protocoles de distribution de courrier électronique, le serveur nous prouve qu’il est un véritable émetteur de courriels, et pas un virus ou un serveur piraté. En pratique, cela bloque l’essentiel des messages envoyés par les virus, et laisse un peu de temps pour s’apercevoir qu’un serveur a été piraté. Mais il y a un inconvénient : pendant le temps que prend cette vérification, la réception du message est retardée. Cela peut concerner quelques uns de vos messages par mois (plus exactement, cela concerne le premier message de chacun de vos interlocuteurs, de chaque serveur utilisé pour envoyer le message, lorsque vous n’avez pas reçu de ceux-ci un message au cours du dernier mois).

Ces messages seront retardés de quelques minutes à quelques heures, selon la charge des serveurs qui les transmettent. Et ça peut être très gênant en cas d’informations urgentes.

Inconvénients

Sur vos comptes mails, le greylisting est activé par défaut. Pour les comptes mail No-log, si vous ne pouvez pas accepter le risque de délai introduit dans la réception des messages par cette technique de filtrage, si la rapidité de distribution des messages est essentielle [1], vous pouvez choisir délibérément de ne pas utiliser cette protection anti-spam.
Dans ce cas, tous les messages (vrais messages et spams) qui vous seront adressés vous parviendront sans délai. Pour cela, inscrivez-vous sur la liste blanche.

Confidentialité

Le greylisting a besoin pour fonctionner de conserver le triplet (adresse IP du serveur, adresses de l’expéditeur, adresse du destinataire) des messages. Mais, histoire de mériter son nom, No-log n’en conserve que l’empreinte cryptée (ou hash) à partir de laquelle il est quasi-impossible de retrouver les données initiales [2]. On ne peut donc pas utiliser la base de données du greylisting pour reconstituer vos carnets d’adresses.
Par contre, absolument rien n’est conservé si le greylisting est désactivé.

Notes

[1Le mode habituel de transmission des courriels sur Internet ne garantit pas de délai de distribution, mais vous ne voulez peut-être pas ajouter un risque supplémentaire de retard.

[2Pour les curieux, le code a été modifié comme suit :

--- postgrey-1.21.orig/postgrey
+++ postgrey-1.21/postgrey
@@ -15,6 +15,7 @@
 use Fcntl ':flock'; # import LOCK_* constants
 use Sys::Hostname;
 use POSIX qw(strftime setlocale LC_ALL);
+use Digest::SHA1 qw(sha1_hex);
         
 use vars qw(@ISA);
 @ISA = qw(Net::Server::Multiplex);
@@ -244,7 +245,7 @@
     my $sender = $self->do_sender_substitutions($attr->{sender});
     my ($client_net, $client_host) =
         $self->do_client_substitutions($attr->{client_address}, $attr->{client_name});
-    my $key    = lc "$client_net/$sender/$attr->{recipient}";
+    my $key    = sha1_hex(lc "$client_net/$sender/$attr->{recipient}");
     my $val    = $db->{$key};
 
     my $first;
@@ -293,7 +294,7 @@
     #   - client whitelisted already? -> update last-seen timestamp
     if($self->{postgrey}{awl_clients}) {                      
         my $cawl_db  = $self->{postgrey}{db_cawl};
-        my $cawl_key = $attr->{client_address};
+        my $cawl_key = sha1_hex($attr->{client_address});
         my $cawl_val = $cawl_db->{$cawl_key};
         my ($cawl_count, $cawl_last);
         ($cawl_count, $cawl_last) = split(/,/,$cawl_val) if defined $cawl_val;