Netfilter pour faire la chasse aux spammeurs

Magazine
Marque
GNU/Linux Magazine
Numéro
125
Mois de parution
mars 2010


Résumé
Je vous propose de découvrir le mécanisme des NFQUEUE Netfilter, le filtrage réseau par un programme userland, appliqué à la lutte contre les spammeurs. Nous allons voir comment, avec très peu d'informations et de ressources, nous allons pouvoir détecter un spammeur potentiel et l'empêcher de se connecter à un serveur mail.

Body

1. Faites la queue comme tout le monde !

Le filtrage réseau classique que beaucoup connaissent est le filtrage basé sur les adresses et les ports source et de destination. Il existe un autre type de filtrage, souvent appelé DPI (Deep Packet Inspection) par les constructeurs ou vendeurs de firewalls propriétaires. Il consiste à filtrer en fonction des informations contenues dans les couches applicatives. Netfilter propose plusieurs moyens de faire cette analyse applicative, vous avez peut-être utilisé certaines d'entre elles, mais nous allons étudier un seul de ces moyens : les NFQUEUE. Le principe est simple : tout le trafic est placé dans une file d'attente qui est lue par un programme, ce dernier va pouvoir décider du filtrage de chaque paquet qu'il traite. Mais pour bien comprendre, rien de mieux qu'un schéma.

schema_nfqueue

1.2 Un petit exemple pour bien comprendre

Avant de nous jeter à corps perdu dans notre antispam utilisant NFQUEUE, voici un programme d'exemple permettant d'analyser les requêtes DNS émises par votre machine. Tout d'abord, nous redirigeons les requêtes vers une file d'attente :

# iptables -I OUTPUT -p udp --dport domain -j NFQUEUE --queue-num 0

Ensuite, nous lançons un simple programme :

#!/usr/bin/perl

use nfqueue;

use Socket qw(AF_INET);

use NetPacket::IP qw(:ALL);

use NetPacket::UDP qw(:ALL);

use Net::DNS::Packet;

sub callback {

        my ($dummy, $payload) = @_;

        if ($payload) {

        my $ip = NetPacket::IP->decode($payload->get_data());

        my $udp = NetPacket::UDP->decode($ip->{data});

        my $dns = Net::DNS::Packet->new($udp->{data});

        eval { $dns->string };

        $dns->print;

        if ($@) {

            $payload->set_verdict($nfqueue::NF_DROP);

        } else {

            $payload->set_verdict($nfqueue::NF_ACCEPT);

        }

    }

}

my $q = new nfqueue::queue();

$q->open();

$q->bind(AF_INET);

$q->set_callback(\&callback);

$q->create_queue(0);

$q->try_run();

On note dans ce programme deux parties, la création de la nfqueue et la fonction de callback à laquelle elle se rattache. Créer une file d'attente n'est pas bien dur comme vous le remarquez, on utilise l'API nfqueue-bindings, qui nous permet de créer notre file d'attente (méthode open), d'associer un traitement spécifique (méthode set_callback) puis de la rattacher à un numéro spécifique (create_queue(votre_numero)) avant de commencer à scruter la file d'attente pour récupérer les paquets (try_run). Parlons maintenant du callback lui-même : nous avons une règle iptables qui place pour nous les datagrammes UDP à destination du port 53 dans une file d'attente et la fonction nommée callback utilise deux bibliothèques tierces, Net::DNS et NetPacket, afin de pratiquer l'analyse protocolaire. Il est souvent plus confortable et/ou plus performant d'utiliser des bibliothèques toutes faites plutôt que réinventer la roue. Ici, nous pourrons donc afficher les requêtes émises par notre machine. Maintenant que vous avez compris le principe, vous vous posez probablement cette question : « A quoi ça sert ? Est-ce encore un jouet de geek inutile ? ». La seconde partie de l'article vous propose de voir une application concrète de ce principe : un antispam.

2. Un antispam basé sur Netfilter !

Les antispams « classiques » fonctionnent ainsi : le mail est récupéré dans son intégralité afin de passer une batterie de tests comme les filtres bayésiens, la comparaison à des expressions rationnelles, l'analyse des en-têtes, l'interrogation des listes noires sur Internet. Au final, beaucoup de ressources (CPU, mémoire, disque, réseau) sont utilisées. Nous allons voir qu'il est possible avec l'utilisation de NFQUEUE d'innover en matière d'antispam : je vais vous présenter synspam, ou comment empêcher les spammeurs de se connecter à votre serveur mail pour y déverser leur publicité pour des pilules bleues, des montres de luxe ou des jetons de casino.

2.1 Les limites des antispams classiques

Les méthodes classiques ont leurs limites, je citerai ici 3 exemples :

  • Le bug du 1er Janvier 2010 de Spamassassin : la règle FH_DATE_PAST_20XX s'est déclenchée et a commencé à générer des faux positifs, le score attribué étant compris en 2.0 et 3.5 en fonction des environnements, les sysadmins ont eu du travail le 1er Janvier pour comprendre l'erreur et rectifier le tir afin d'éviter de marquer comme spams des messages légitimes.
  • Le contrôle de contenu mal configuré peut donner des résultats très déplaisants, voici un exemple dans lequel l'antispam refuse purement et simplement les mails contenant les types MIME .movie, .mpg, mais aussi text/plain :

Objet : BANNED (text/plain,.movie,.mpg) IN MAIL FROM YOU

BANNED CONTENTS ALERT

Our content checker found

   banned name: text/plain,.movie,.mpg

Il s'en suit que l'utilisateur ne recevra plus beaucoup de messages (ceci dit, c'est aussi une méthode assez efficace contre les spams si on se fiche des faux positifs !)

  • Les mails de reconnaissance : en envoyant un faux mail innocent (une carte de vœux en plain/text, par exemple, sans rien d'autre), un spammeur pourra découvrir les adresses mails valides sur votre serveur. L'antispam ne trouvant rien à redire à ce type de message, il se peut que le message passe.
  • Le dernier exemple est celui du filtrage bayésien, pour rappel un filtrage probabilistique basé sur une base de données de hams (messages légitimes) et de spams : les spammeurs emploient déjà depuis un moment une technique dite de « désapprentissage » des filtres bayésiens. Il s'agit d'envoyer des messages parfaitement « normaux » aux yeux des filtres bayésiens pour que ceux-ci apprennent les messages envoyés depuis une certaine adresse mail comme des messages légitimes. Le spammeur enverra ensuite ses spams avec la même adresse d'expéditeur et le filtre bayésien sera moins efficace sur la détection de ce spam.

2.2 Synspam à la rescousse !

La méthode de synspam est d'intercepter le tout premier paquet TCP d'une connexion sur le port 25 afin de donner un indice sur la probabilité que la machine source est émettrice de spams. Cette probabilité n'a rien à voir avec les filtres bayésiens évoqués précédemment, une série de tests est déroulée à l'arrivée de chaque paquet SYN, chaque test positif ajoute des points à un score, si ce dernier dépasse un seuil prédéfini, la connexion est tout simplement refusée car considérée comme émanant d'un spammeur.

Tout d'abord, reprenons les bases de TCP. Pour qu'une connexion s'établisse, le client envoie au serveur une demande (un SYN). C'est ici que nous allons récupérer toutes les informations nécessaires à l'identification des spammeurs : son adresse IP que nous pouvons confronter à différentes listes noires ainsi qu'à une comparaison de son enregistrement DNS à une expression rationnelle, les en-têtes IP et TCP peuvent même nous permettre de faire de l'OS fingerprinting.

Voyons tout d'abord le cœur du logiciel :

sub main {

  close(STDOUT); # to prevent nfqueue-bindings verbose debugging

$queue = new nfqueue::queue();

  $queue->set_callback(\&cb);

$queue->fast_open($queuenum, AF_INET);

$SIG{INT} = \&cleanup;

  $SIG{HUP} = \&cleanup;

  $SIG{TERM} = \&cleanup;

$queue->set_queue_maxlen(5000);

  $queue->try_run();

}

sub cb()

{

        my ($dummy,$payload) = @_;

        if ($payload) {

        my $ip_obj = NetPacket::IP->decode($payload->get_data());

        my $ipsrc = $ip_obj->{src_ip};

        my $result = "";

        $debugstr = " ";

        $score = 0;

        run_tests($ipsrc);

        my $connection = "$ipsrc score=".$score;

}

sub run_tests {

         my ($ipsrc) = @_;

         my $reverse = rdns_testsuite($ipsrc);

         check_dnsbl($ipsrc, $score_dnsbl_high, "dnsbl_high ", @dnsbl_high);

         check_dnsbl($ipsrc, $score_dnsbl_med, "dnsbl_med ", @dnsbl_med);

         check_dnsbl($ipsrc, $score_dnsbl_low, "dnsbl_low ", @dnsbl_low);

}

}

Comme dans notre programme d'exemple, tout commence par la mise en place d'une file d'attente NFQUEUE avec sa fonction de callback dans laquelle on décortique les en-têtes IP grâce à NetPacket, puis viennent les tests proprement dits via un appel à la fonction run_tests. Examinons en détail les tests en question :

  • Les tests sur les listes noires sont classés par ordre de confiance : de low à high, respectivement pour les DNSBL auxquelles nous accordons le moins de confiance jusqu'à celles considérées comme les plus performantes (que ce soit en termes de détection que de faux positifs). Il ne faut jamais faire confiance à un seul système en matière de sécurité. Aussi, chaque DNSBL se voit attribuer un score, ce qui réduit l'impact d'une liste qui bloquerait une machine désirant envoyer un message légitime.
  • Le deuxième système sur lequel repose synspam est... le DNS, ou plus précisément une analyse des enregistrements liés à la machine source. Comme vous le savez peut-être déjà, une très large majorité des spams sont envoyés depuis des machines faisant partie de botnets. Ces machines ont (très) souvent les caractéristiques suivantes : une connexion dialup de type modem, adsl ou cable avec un enregistrement DNS qui contient l'adresse IP sous une forme ou une autre et parfois des mots-clés. Nous allons donc analyser ce reverse afin de savoir si une machine dialup tente de se connecter. Voici le code en charge du test :

sub check_words {

   my ($name) = @_;

   my @clientwords = ('.*dsl.*', 'cable', 'catv', 'ddns', 'dhcp',

    'dial(-?up)?', 'dip', 'docsis', 'dyn(amic)?(ip)?', 'modem', 'ppp(oe)?',

    'res(net|ident(ial)?)?', 'bredband', 'broadband', 'triband'

    , 'client', 'fixed', 'ip', 'pool', 'static', 'user' # controversial ones

    );

   my $wordre = '((\b|\d)' . join('(\b|\d))|((\b|\d)', @clientwords) . '(\b|\d))';

   my $wordexp = '(' . $wordre . ')\S*\.\S+\.\S+$';

   if (($name ne "") && ($wordexp ne "") && ($name =~ /(?:$wordexp)/i) ) {

      $score += $score_botnet_reverse;

      $debugstr .= "botnet_reverse ";

      return (1);

}

   return (0);

}

code

Le système de détection d'adresse IP contenue dans le reverse DNS emploie une méthode similaire. Nous avons donc ici nos 2 premières séries de tests : les DNSBL et la comparaison des enregistrements DNS à une expression rationnelle.

Une troisième méthode pourrait être employée, il s'agit de l'OS fingerprinting ou, en bon français, la détection de système d'exploitation. Pourquoi donc ce besoin ? Car si la majorité des spams sont envoyés par des machines compromises et rattachées à des botnets, ces machines sont quasiment toutes des machines faisant tourner une version de Windows (2000, 2003, Vista, mais surtout les différentes versions de XP). Les serveurs de mails des FAI, hébergeurs sont très souvent des machines Unix, même si on croise de temps à autre des plates-formes basées sur Exchange, mais ces exemples sont marginaux. Détecter une machine Windows, c'est une probabilité de plus que le message délivré soit un spam.

2.3 Oui à l'OS fingerprinting, mais comment ?

Comme vu dans le paragraphe précédent, le logiciel intercepte les paquets SYN avant que ceux-ci n'atteignent le port 25 de la machine, nous ne disposons donc que de ce paquet pour faire notre reconnaissance d'OS qui sera donc passive. Il existe plusieurs logiciels capables de réaliser ce que nous voulons (parmi eux, on compte p0f, sinfp), mais ils utilisent la bibliothèque pcap et ne peuvent pas se rattacher à une file d'attente Netfilter. Deux solutions sont envisageables : la première est de coder en perl notre propre moteur, la deuxième est de se reposer sur Netfilter pour la détection d'OS. Fort heureusement pour nous, depuis la version 2.6.31 du noyau Linux, un module Netfilter a fait son apparition. Il s'agit de xt_osf, qui utilise le format de p0f pour réaliser la détection d'OS, fantastique ! Voyons un peu en détail ce que cela donne :

Pour reconnaître les différents OS, il nous faut 2 choses : un fichier de définition, par exemple, pf.os (fichier mis à disposition par le projet OpenBSD) et l'outil userland permettant d'intégrer ledit fichier :

# modprobe xt_osf

# wget http://www.ioremap.net/archive/osf/osf-2009_06_07.tar.gz

# tar xzf osf-2009_06_07.tar.gz && cd osf-2009_06_07

# make

# wget http://www.openbsd.org/pf.os

# ./nfnl -f pf.os

Nous avons donc notre système prêt à l'emploi. Il ne reste plus qu'à faire 2 files d'attente : la première pour les machines de type Windows, la deuxième pour le reste.

# iptables -I INPUT -m osf ! --genre Windows -p tcp --syn --dport 25 -j NFQUEUE --queue-num 0

# iptables -I INPUT -m osf --genre Windows -p tcp --syn --dport 25 -j NFQUEUE --queue-num 1

Un premier processus synspam rattaché à la file d'attente 0, qui aura pour score de base 0, un deuxième processus synspam rattaché à la file d'attente 1, qui ajoutera une pondération supplémentaire pour toutes les connexions, le score de base sera alors de 1, 2, 3... ou 42 au gré de l'humeur de l'administrateur ;-)

3. Alors, on peut conclure ?

Le système antispam proposé ne tombe pas dans les travers des systèmes classiques. Ceci dit, il n'est pas parfait non plus dans le sens où il ne détectera probablement pas 100% des connexions ayant pour but l'envoi de spams. Cette solution a l'avantage de pouvoir être utilisée en amont d'un MTA, qui aura un logiciel antispam classique qui inspectera alors le contenu des messages passés au travers des mailles du premier filet. Alors profitez-en pour croiser les technologies pour un filtrage encore plus performant. Pour reprendre une formule d'un très bon enseignant : « en sécurité, c'est ceinture + bretelles ».




Article rédigé par

Par le(s) même(s) auteur(s)

Permissions : découverte d’AppArmor

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
84
Mois de parution
mai 2016
Spécialité(s)
Résumé

Le système de permissions hérité du monde UNIX peut parfois sembler limité. Même s’il a fait ses preuves, d’autres modèles de sécurité existent ; nous vous proposons aujourd’hui de découvrir  le modèle MAC grâce à AppArmor et les possibilités offertes par cette implémentation.

Les derniers articles Premiums

Les derniers articles Premium

La place de l’Intelligence Artificielle dans les entreprises

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

L’intelligence artificielle est en train de redéfinir le paysage professionnel. De l’automatisation des tâches répétitives à la cybersécurité, en passant par l’analyse des données, l’IA s’immisce dans tous les aspects de l’entreprise moderne. Toutefois, cette révolution technologique soulève des questions éthiques et sociétales, notamment sur l’avenir des emplois. Cet article se penche sur l’évolution de l’IA, ses applications variées, et les enjeux qu’elle engendre dans le monde du travail.

Petit guide d’outils open source pour le télétravail

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Ah le Covid ! Si en cette période de nombreux cas resurgissent, ce n’est rien comparé aux vagues que nous avons connues en 2020 et 2021. Ce fléau a contraint une large partie de la population à faire ce que tout le monde connaît sous le nom de télétravail. Nous avons dû changer nos habitudes et avons dû apprendre à utiliser de nombreux outils collaboratifs, de visioconférence, etc., dont tout le monde n’était pas habitué. Dans cet article, nous passons en revue quelques outils open source utiles pour le travail à la maison. En effet, pour les adeptes du costume en haut et du pyjama en bas, la communauté open source s’est démenée pour proposer des alternatives aux outils propriétaires et payants.

Sécurisez vos applications web : comment Symfony vous protège des menaces courantes

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Les frameworks tels que Symfony ont bouleversé le développement web en apportant une structure solide et des outils performants. Malgré ces qualités, nous pouvons découvrir d’innombrables vulnérabilités. Cet article met le doigt sur les failles de sécurité les plus fréquentes qui affectent même les environnements les plus robustes. De l’injection de requêtes à distance à l’exécution de scripts malveillants, découvrez comment ces failles peuvent mettre en péril vos applications et, surtout, comment vous en prémunir.

Bash des temps modernes

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Les scripts Shell, et Bash spécifiquement, demeurent un standard, de facto, de notre industrie. Ils forment un composant primordial de toute distribution Linux, mais c’est aussi un outil de prédilection pour implémenter de nombreuses tâches d’automatisation, en particulier dans le « Cloud », par eux-mêmes ou conjointement à des solutions telles que Ansible. Pour toutes ces raisons et bien d’autres encore, savoir les concevoir de manière robuste et idempotente est crucial.

Les listes de lecture

9 article(s) - ajoutée le 01/07/2020
Vous désirez apprendre le langage Python, mais ne savez pas trop par où commencer ? Cette liste de lecture vous permettra de faire vos premiers pas en découvrant l'écosystème de Python et en écrivant de petits scripts.
11 article(s) - ajoutée le 01/07/2020
La base de tout programme effectuant une tâche un tant soit peu complexe est un algorithme, une méthode permettant de manipuler des données pour obtenir un résultat attendu. Dans cette liste, vous pourrez découvrir quelques spécimens d'algorithmes.
10 article(s) - ajoutée le 01/07/2020
À quoi bon se targuer de posséder des pétaoctets de données si l'on est incapable d'analyser ces dernières ? Cette liste vous aidera à "faire parler" vos données.
Voir les 65 listes de lecture

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous