Guide complet pour l'implémentation de Netfilter et Suricata sous Linux

Dernière mise à jour: 1 Mars 2026
  • NFQUEUE permet à Netfilter de déléguer les décisions de filtrage et de marquage à des processus en espace utilisateur, permettant ainsi des pare-feu et des routeurs IP dynamiques.
  • Suricata fournit un moteur IDS/IPS multiprocessus prenant en charge NFQUEUE, AF_PACKET et des règles compatibles avec Snort et Emerging Threats.
  • L'intégration de NFQUEUE avec Suricata, les bases de données, Memcached ou Pfsense vous permet de créer des solutions de sécurité et de routage avancées avec des logiciels gratuits.
  • Les performances dépendent largement de la conception des threads et de la logique de l'espace utilisateur, ce qui rend essentiel l'optimisation et la sélection rigoureuse du trafic à inspecter.

Implémentation de Netfilter et Suricata

Si vous travaillez avec des réseaux sous GNU/Linux ( les meilleures distributions Linux pour la sécurité et la confidentialité ) et que vous souhaitez aller au-delà du pare-feu statique classique, vous vous demandez probablement comment combiner Netfilter, NFQUEUE et Suricata pour créer un système IDS/IPS véritablement flexible sans investir une fortune dans du matériel propriétaire. C'est précisément ce que nous allons explorer dans cet article : l'association d'éléments de bas niveau (noyau, files d'attente, C) et d'outils de haut niveau (Suricata, règles, MySQL, Memcached, pfSense).

L'idée sous-jacente est très puissante : exploiter la capacité du noyau (voir comment optimiser le noyau Linux ) à mettre en file d'attente les paquets dans l'espace utilisateur et à laisser un programme personnalisé décider de leur traitement. Ceci peut servir au filtrage du trafic (pare-feu avancé, IPS), au routage dynamique ou à l'intégration de la logique métier (bases de données, caches, détection d'attaques d'applications web, VoIP, etc.). En y ajoutant Suricata comme moteur IDS/IPS multiprocessus, on obtient une solution très robuste pour des environnements allant des laboratoires aux centres de données à fort trafic.

NFQUEUE et Netfilter : élever le pare-feu à l’espace utilisateur

Dans un système GNU/Linux classique, les règles Netfilter/iptables (ou nftables) sont généralement utilisées comme des politiques statiques résidant entièrement dans l'espace noyau . Les interfaces et les appliances (dont de nombreuses solutions basées sur Netfilter ou le filtre de paquets BSD) stockent la configuration dans des fichiers texte, XML ou SQLite, et régénèrent et rechargent les règles en cas de modification. Cette approche est flexible, mais la logique reste une sorte d'instantané du pare-feu, avec quelques ajustements dynamiques mineurs (limites de connexions par seconde, suivi des connexions, correspondance avec le pays, couche 7 si disponible, etc.).

NFQUEUE propose une solution révolutionnaire : au lieu que le noyau prenne systématiquement la décision finale, cette décision peut être déléguée à un processus utilisateur . Le noyau place le paquet dans une file d'attente numérotée, et une application utilisant la bibliothèque libnetfilter_queue le récupère, l'analyse et rend un verdict : acceptation, rejet ou même marquage pour un routage basé sur des règles. C'est comme disposer d'un « juge » programmable, écrit en C, Python ou Perl, intégré au pare-feu.

L'avantage, c'est que notre programme peut littéralement tout faire : interroger /dev/urandom, une base de données, un service web, un cache distribué ou un algorithme complexe avant de répondre au noyau. En termes d'architecture, le pare-feu cesse d'être un simple ensemble de règles statiques et devient un pipeline où Netfilter, les files d'attente et les applications utilisateur s'imbriquent comme les pièces d'un puzzle.

NFQUEUE se compose de deux parties : la cible NFQUEUE dans iptables , qui envoie les paquets vers une file d'attente spécifique, et la bibliothèque utilisateur libnetfilter_queue , qui permet de lire ces paquets et d'émettre un verdict. Il ne s'agit pas d'un simple analyseur de trafic comme tcpdump : ici, nous avons la possibilité de déterminer directement le chemin emprunté par le paquet.

Moniteur système avancé pour Linux
Article connexe:
Moniteur système avancé pour Linux : Guide complet

Configuration de base d'iptables avec NFQUEUE

Du point de vue d'iptables, l'utilisation de NFQUEUE est assez simple : vous ajoutez une règle à la chaîne qui vous intéresse pour envoyer à la file d'attente les paquets qui répondent à certains critères (adresse IP source/destination, ports, états, modules supplémentaires tels que GeoIP ou layer7 si disponibles, etc.).

Par exemple, si nous voulons envoyer à NFQUEUE tous les pings qui arrivent sur l'hôte lui-même :

iptables -I INPUT -p icmp -j NFQUEUE

Cette configuration envoie les paquets ICMP entrants à la file d'attente 0 (sauf indication contraire). Il est possible de spécifier une autre file d'attente avec l'option `--queue-num 3` . Lors de l'affichage des règles avec compteurs (`iptables -L -n -v -x`), les compteurs s'incrémentent, indiquant la mise en file d'attente des paquets . Détail important : si des paquets sont présents dans la file d'attente et qu'aucun processus utilisateur ne les récupère et ne les traite, le comportement par défaut est de les bloquer. Par conséquent, une défaillance d'application entraîne, de par sa conception, le blocage du trafic.

Programmation avec libnetfilter_queue : le « hello world » en C

Pour rejoindre la file d'attente depuis l'espace utilisateur, la bibliothèque libnetfilter_queue est utilisée (qui dépend elle-même de libnfnetlink). Sur les distributions comme Debian, il suffit d'installer les paquets de développement :

apt-get install libnfnetlink-dev libnetfilter-queue-dev gcc

Le squelette d'un programme minimal acceptant systématiquement les paquets se compose de quelques étapes très claires : ouvrir la bibliothèque, désactiver les gestionnaires existants, se lier au protocole AF_INET, créer la file d'attente avec une fonction de rappel, définir le mode de copie et entrer dans une boucle de réception . La fonction de rappel est exécutée pour chaque paquet en file d'attente, en extrayant l'identifiant et en renvoyant le résultat.

En pratique, le flux se déroule comme suit : `nfq_open` pour obtenir le descripteur, `nfq_unbind_pf` pour le libérer, `nfq_bind_pf` pour l'associer à AF_INET, `nfq_create_queue` pour enregistrer le rappel dans la file d'attente 0, `nfq_set_mode` pour indiquer si l'on souhaite recevoir les métadonnées ou le paquet entier, une boucle avec `recv()` sur le descripteur, et `nfq_handle_packet` pour traiter chaque paquet . À la sortie, la file d'attente est détruite avec `nfq_destroy_queue` et le descripteur est fermé avec `nfq_close`.

Ce type de programme « Hello World » permet de mesurer précisément l’impact de NFQUEUE. Si nous compilons l’exemple avec un code similaire à celui-ci :

gcc -o nftest code.c -lnfnetlink -lnetfilter_queue

Si l'on met en file d'attente le trafic d'iperf (par exemple, le port TCP 5001 en entrée et en sortie), on constate que le code qui se contente d'accepter les paquets n'a quasiment aucun impact sur les performances d'un réseau gigabit . Cependant, un détail important est à noter : l'affichage d'informations dans la fonction de rappel (printf, fflush, etc.) pénalise considérablement le débit, comme on peut le constater en comparant les performances d'iperf avec et sans débogage à l'écran.

Options avancées de NFQUEUE : contournement, équilibrage et défaillance ouverte

NFQUEUE intègre plusieurs options iptables intéressantes qui modifient le comportement par défaut des files d'attente et qu'il convient de connaître avant d'entrer dans un environnement de production ou à hautes performances, car elles affectent la manière dont les défaillances des applications utilisateur ou le remplissage des files d'attente sont gérés.

La commande `--queue-bypass` permet de garantir que si aucun processus n'écoute la file d'attente, les paquets ne sont pas abandonnés mais transmis au prochain nœud de la chaîne iptables. Ceci peut s'avérer utile pour maintenir le système ouvert en cas d'indisponibilité du service utilisateur, même si, du point de vue de la sécurité, c'est une arme à double tranchant.

L' option `--queue-balance` permet de répartir les paquets sur plusieurs files d'attente (par exemple, de 0 à 3) et d'exécuter plusieurs processus ou threads indépendants consommant les paquets de chaque file . Le code de Netfilter garantit que les paquets d'un même flux aboutissent toujours dans la même file d'attente, ce qui simplifie considérablement la cohérence de la logique de décision.

Il existe également le mode `--fail-open` , qui détermine le comportement du système lorsque la file d'attente est saturée en raison d'une lenteur excessive du processus utilisateur. Son activation force le noyau à accepter directement les paquets au lieu de les rejeter, évitant ainsi des interruptions de trafic importantes. Cependant, cela peut poser un problème de sécurité, car si l'on souhaite prendre des décisions au cas par cas, la perte de paquets de décision compromet la réalisation de cet objectif.

Pour surveiller ce qui se passe avec les files d'attente, Netfilter expose des informations dans le pseudo-système de fichiers /proc/net/netfilter/nfnetlink_queue , qui peut être facilement interrogé à partir de scripts ou d'outils de surveillance.

Intégration de la logique métier : tests avec Memcached et MySQL

Une fois le processus « hello world » maîtrisé, l’étape suivante consiste à enrichir la fonction de rappel avec des appels à des systèmes externes . Une expérience typique consiste à décider d’accepter ou de rejeter un paquet selon que l’adresse IP source figure ou non dans un système de stockage en arrière-plan, comme une base de données MySQL ou un cache Memcached.

  LD_LIBRARY_PATH sous Linux : utilisation correcte, risques et alternatives

Dans le cas de Memcached, le démon est installé (commande : `apt-get install memcached`) et une clé, par exemple `authorized` , est chargée avec l'adresse IP recherchée. On peut effectuer cette opération avec une simple commande `echo` et `netcat`, puis vérifier avec une commande `get` que la valeur est correctement enregistrée. Ensuite, le programme NFQUEUE, outre l'obtention de l'identifiant du paquet, reçoit le paquet entier à l'aide de `NFQNL_COPY_PACKET` , extrait l'en-tête IP (structure `iphdr`) et convertit l'adresse source en une chaîne de caractères avec `inet_ntop`.

Pour éviter de perdre du temps à ouvrir des connexions pour chaque paquet, la connexion Memcached est initialisée une seule fois dans la méthode principale (memcached_create, memcached_server_list_append, memcached_server_push), et le gestionnaire est stocké dans des variables globales. Dans la fonction de rappel, memcached_get est appelée avec la clé souhaitée, l'adresse IP source est comparée à la valeur récupérée, et si elles correspondent, NF_ACCEPT est renvoyé ; sinon, NF_DROP est renvoyé. Si la clé n'existe pas ou en cas d'erreur, le paquet est abandonné par mesure de précaution.

Avec iperf, cette stratégie réduit le débit à environ 140 Mbit/s sur un réseau gigabit , et on observe des pertes dans la file d'attente (indiquées, par exemple, par des symboles dans le code). Autrement dit, le simple fait d'appeler un service de cache pour chaque paquet engendre déjà un coût important, même si cette solution reste viable pour des volumes de trafic moyens après optimisation.

Avec MySQL, l'approche est similaire mais plus complexe : les bibliothèques serveur et client sont installées, une base de données (par exemple, nfqueue) est créée avec une table simple nommée authorized(ip varchar(50)), et l'adresse IP autorisée est insérée. Dans le programme, les fonctions `mysql_init` et `mysql_real_connect` sont exécutées au démarrage, et dans la fonction de rappel, une requête du type `select * from authorized where ip like 'xxxx'` est construite. Si la requête s'exécute avec succès et qu'une ligne est trouvée, le paquet est accepté ; sinon, il est rejeté.

Avec la mise en cache des requêtes MySQL activée, les tests affichent un débit d'environ 188 Mbit/s , qui chute à 103 Mbit/s lorsque la mise en cache est désactivée. Ces chiffres, bien qu'éloignés des gigabits, démontrent que même avec l'approche la moins élégante (monothread, sans optimisation) , des volumes de trafic respectables peuvent être gérés grâce à des décisions basées sur la base de données ou sur la mise en cache.

Performances, multithreading et utilisation du processeur

Les tests effectués avec iperf, Memcached et MySQL montrent clairement que la limite de performance n'est pas tant imposée par NFQUEUE lui-même que par la logique ajoutée en espace utilisateur et son implémentation. Un exécutable ne renvoyant que NF_ACCEPT atteint presque un gigabit par seconde sans difficulté ; dès que des opérations d'entrée/sortie ou des appels réseau sont introduits, le débit chute et le processeur de la machine NFQUEUE, du démon Memcached ou de MySQL est poussé à ses limites.

D'un point de vue architectural, cela a deux implications. D'une part, cela confirme que déléguer la gestion du pare-feu aux applications utilisateur pour des volumes de trafic importants est parfaitement viable , à condition de prendre en compte le coût réel de chaque appel. D'autre part, cela démontre que pour exploiter pleinement les capacités de la plateforme , le multithreading ou le multiprocessing doivent être envisagés . NFQUEUE permet de répartir le trafic sur plusieurs files d'attente ; nous pourrions ainsi lancer plusieurs instances de notre application, chacune écoutant une file d'attente différente, et tirer parti de plusieurs cœurs sans avoir recours à pthreads ni à des forks massifs.

Une autre optimisation évidente consisterait à limiter le trafic transitant par NFQUEUE . Lors des tests, l'intégralité du flux iperf était mise en file d'attente, mais dans un scénario réel, nous pourrions ne mettre en file d'attente que les paquets à l'état NEW, autoriser le passage des paquets ESTABLISHED/RELATED et réserver la logique coûteuse aux connexions ou aux comportements suspects.

En définitive, l'utilisation du processeur et la conception des threads sont essentielles : si le processus utilisateur est insuffisant, la file d'attente se remplit et nous devons recourir à des solutions comme l'ouverture en cas de défaillance ou l'acceptation des abandons, ce qui entraîne une perte de contrôle précis, objectif principal de cette approche.

Routage dynamique avec la marque Netfilter

NFQUEUE ne se limite pas à simplement dire « accepter » ou « rejeter ». Il peut également être utilisé pour appliquer des indicateurs Netfilter (fwmark) aux paquets et les combiner avec ip rule et iproute2 pour créer des schémas de routage politique de type VRF très flexibles et presque légers.

La procédure, en résumé, serait la suivante : définir plusieurs tables de routage dans /etc/iproute2/rt_tables , par exemple lente et rapide ; attribuer à chaque table une route par défaut différente (l’une via la fibre et l’autre via une liaison plus limitée) ; utiliser une règle IP pour spécifier que les paquets avec fwmark 1 aillent à la table rapide, ceux avec fwmark 2 à la table lente, etc. ; et enfin, utiliser NFQUEUE pour marquer les paquets de manière appropriée avant de renvoyer le verdict.

Pour définir un verdict à partir du rappel, on utilise `nfq_set_verdict2` , similaire à `nfq_set_verdict`, mais qui permet de définir une valeur de verdict que `ip rule` pourra ensuite interpréter. En combinant tous ces éléments, il est possible de créer un routeur IP qui détermine le routage en fonction de critères arbitraires : allant de choses absurdes comme la taille paire/impaire des paquets à des entrées externes telles que des algorithmes de prédiction de trafic, des événements sur les réseaux sociaux ou des signaux provenant de systèmes de surveillance.

Il en résulte un système dans lequel le noyau continue à acheminer les paquets au débit habituel, mais le chemin exact emprunté par chaque flux est délégué à un logiciel externe qui peut changer d'avis en temps réel sans toucher aux règles statiques.

NFQUEUE et Suricata : IPS de haut niveau sous GNU/Linux

Tout ce qui précède peut être programmé manuellement en C, mais en matière de détection d'intrusion et d'inspection approfondie des paquets, il est généralement plus judicieux de s'appuyer sur un moteur IDS/IPS éprouvé . C'est là qu'intervient Suricata, conçu précisément comme une alternative multiprocessus à Snort, avec des fonctionnalités IPS intégrées dès le départ et une approche exploitant pleinement les nombreux cœurs de processeurs disponibles aujourd'hui.

Suricata est entièrement réécrit et distribué sous licence GPLv2 ; l’Open Information Security Foundation (OISF) assure la maintenance du moteur ainsi que d’un écosystème complet de règles et de documentation. Contrairement à Snort 2.x, qui reposait sur un noyau monothread auquel il était ajouté par des correctifs, Suricata a été conçu pour répartir la charge de travail sur plusieurs threads : capture, décodage, détection et sortie, selon différentes stratégies de partage de charge.

Sur le plan fonctionnel, Suricata offre une prise en charge native d' IPv6, une inspection de couche 7 (HTTP très avancé via la bibliothèque HTP), une reconnaissance de protocole indépendante des ports , une reconstruction de flux et un système très puissant de variables de session (flowbits) pour corréler les différentes étapes d'une attaque répartie sur plusieurs connexions TCP.

Un autre atout réside dans sa compatibilité avec les règles Snort et sa capacité à utiliser les ensembles de signatures Sourcefire VRT et Emerging Threats (versions gratuite ET Open et commerciale ET Pro). De plus, il exporte les événements dans des formats très utiles (fast.log, JSON dans eve.json) pour l'intégration avec les SIEM, ELK, Splunk et autres systèmes.

Suricata comme système de prévention des intrusions sous Linux : modes de capture et NFQUEUE

Sous GNU/Linux, Suricata peut fonctionner selon différents modes d'interception du trafic : NFQUEUE, AF_PACKET, PF_RING, libpcap, NFLOG, IPFW, DAG, Napatech … Chacun présente ses avantages et ses exigences. Au niveau IPS pur, les deux modes les plus importants sont NFQUEUE et AF_PACKET.

En mode NFQ (NFQUEUE) , le flux est similaire à celui décrit précédemment : un ensemble de règles iptables envoie les paquets à une file d’attente ; Suricata, exécuté dans l’espace utilisateur, lit cette file d’attente, en examine le contenu selon ses règles et renvoie un verdict au noyau : NF_ACCEPT, NF_DROP ou NF_REPEAT. Ce dernier peut être utilisé pour réinjecter le paquet dans la même table iptables après application de marques ou de modifications supplémentaires.

Ce mode est très flexible et facile à implémenter dans les infrastructures existantes , car il ne nécessite de modifier les règles qu'à certains points (par exemple, FORWARD, INPUT, OUTPUT) et de laisser le reste inchangé. Le coût réside dans la surcharge liée au transit des paquets via NFQUEUE, avec l'impact mentionné précédemment si le volume est très élevé ou si les règles sont gourmandes en ressources.

En mode AF_PACKET , Suricata fonctionne au plus près de l'interface réseau, en copiant les paquets via les sockets AF_PACKET. Cette approche sans copie est beaucoup plus rapide , mais elle exige que le système fonctionne comme une passerelle à deux interfaces et que le blocage du trafic soit effectué au niveau du transfert entre les cartes réseau : le paquet à bloquer n'est tout simplement pas transmis de l'interface d'entrée à l'interface de sortie.

  GNOME 50 Tokyo : VRR stable, Wayland pur et bureau à distance amélioré

Dans les deux modes, Suricata peut être combiné avec Netfilter, mais NFQUEUE convient particulièrement bien aux scénarios où nous voulons réutiliser toute la logique iptables (politiques, plages, règles précédentes) et n'envoyer à Suricata que le trafic que nous souhaitons examiner en détail.

Installation de base de Suricata à partir du code source

Pour ceux qui préfèrent compiler Suricata plutôt que d'utiliser des paquets, le processus sur les distributions de type Debian/Ubuntu implique d'abord l'installation des dépendances de compilation (build-essential, libpcre, libpcap-dev, libnet-dev, libyaml-dev, zlib, libcap-ng-dev, libjansson-dev, etc.), le téléchargement de l'archive tar depuis le site web officiel et l'exécution de la commande classique ./configure, make, make install.

Lors de la phase de configuration, le script indiquera les fonctionnalités de support activées : AF_PACKET oui/non, PF_RING, NFQUEUE oui/non, NFLOG, IPFW, prise en charge de libnss, libjansson, Prelude, PCRE JIT, Lua, GeoIP, etc. Il est important de vérifier que NFQUEUE est activé si l’on souhaite travailler dans ce mode , et que la bibliothèque de capture souhaitée a bien été localisée.

Après avoir installé le binaire, vous pouvez exécuter `make install-conf` pour déployer une configuration par défaut dans `/etc/suricata` et `make install-rules` pour télécharger et placer un ensemble de règles Emerging Threats dans `/etc/suricata/rules`. Ces ensembles peuvent ensuite être mis à jour à l'aide d'outils tels que `suricata-update`.

Sur les systèmes Red Hat/CentOS, la logique est similaire : on utilise yum ou dnf pour les dépendances (libpcap-devel, pcre-devel, libnet-devel, libyaml-devel, jansson-devel, etc.) puis on compile en suivant les mêmes étapes. Pour des raisons de performance, il est également conseillé de désactiver LRO/GRO dans l'interface de capture à l'aide d'ethtool, car ces fonctions de déchargement peuvent affecter la visibilité des paquets au niveau du système de détection d'intrusion (IDS).

Configuration de Suricata : YAML, variables et multithreading

La configuration principale de Suricata se trouve dans /etc/suricata/suricata.yaml . Il s'agit d'un fichier YAML assez lisible et abondamment commenté, où sont définis tous les éléments, des chemins d'accès aux journaux et des ensembles de règles aux politiques du système d'exploitation cible et aux paramètres de gestion des threads.

L'un des champs de base est `default-log-dir` , qui spécifie l'emplacement de stockage des fichiers journaux (par défaut, `/var/log/suricata`). La section `vars` contient des variables telles que `HOME_NET`, `EXTERNAL_NET`, `HTTP_PORTS`, `SHELLCODE_PORTS` et `SSH_PORTS`, qui servent d'abréviations dans les règles. `HOME_NET` est généralement configuré avec la plage d'adresses réseau locale à protéger, tandis que `EXTERNAL_NET` est généralement défini comme `!HOME_NET`.

Un autre élément important est la politique relative au système d'exploitation hôte , qui indique à Suricata quel système d'exploitation doit gérer certaines plages d'adresses IP. Cela lui permet d'ajuster la façon dont il réassemble le protocole TCP ou interprète certains comportements de la pile réseau , rendant ainsi plus difficile le contournement des protocoles basé sur les différences entre les piles (Windows vs Linux, etc.). Des plages spécifiques peuvent être attribuées à des catégories telles que Windows, Linux, BSD, Vista, Windows 2003, etc.

Concernant le multithreading, la section correspondante permet d'ajuster l'affinité CPU et le nombre de threads de détection. Par défaut, `set-cpu-affinity` est généralement désactivé, laissant ainsi le planificateur système répartir les threads entre les cœurs. Le paramètre `detect-thread-ratio` indique le nombre de threads de détection créés par cœur disponible ; avec `detect-thread-ratio: 1.5` sur une machine à 8 cœurs, Suricata générera 12 threads de détection, ainsi que des threads de capture et de gestion.

Ce modèle complet se reflète dans la sortie au démarrage du démon : un thread de capture (par exemple, pcap) et plusieurs threads de détection sont visibles, ainsi que des gestionnaires de flux et de statistiques. Cette architecture multiprocessus permet à Suricata d'offrir une montée en charge bien supérieure aux moteurs monothread face à des liaisons de 10/40 Gbit/s.

Règles et mises à jour des signatures dans Suricata

Suricata s'appuie sur des ensembles de règles pour détecter les schémas d'attaque, les comportements anormaux et les abus de protocole. Outre l'acceptation des règles au format Snort , l'écosystème le plus courant est celui des menaces émergentes : ET Open (gratuit) et ET Pro (commercial), avec des règles adaptées aux menaces actuelles.

De nombreuses distributions modernes intègrent l' outil `suricata-update` , qui simplifie la gestion des règles : il met à jour les sources, active ou désactive certains fournisseurs et télécharge les dernières versions des ensembles de signatures. Un flux de travail typique consiste à installer `suricata-update` (par exemple, via pip), à exécuter une première fois `suricata-update` pour télécharger ET Open, à lister les sources avec `suricata-update list-sources`, à activer des sources supplémentaires telles que `ptresearch/attackdetection`, `oisf/trafficid` ou `sslbl/ssl-fp-blacklist`, puis à exécuter à nouveau `suricata-update` pour régénérer le fichier de règles.

Le fichier suricata.yaml est configuré pour pointer vers le chemin d'accès correct aux règles. Suricata générera alors des alertes qui seront consignées dans fast.log (texte concis et lisible) et eve.json (JSON structuré contenant des informations très complètes) . Ce dernier format est particulièrement utile pour alimenter des tableaux de bord, des systèmes de corrélation ou des scripts personnalisés.

En plus des signatures, Suricata intègre des décodeurs et des analyseurs pour de multiples protocoles , ce qui lui permet d'être moins dépendant des ports : il peut identifier le trafic HTTP même s'il passe par des ports non standard, détecter SSH, TLS, DNS, etc. sur différents ports et niveaux d'encapsulation (y compris les tunnels IPv4/IPv6 mixtes).

Utilisation pratique : de la détection des failles de sécurité Web au blocage automatique

L'un des cas d'utilisation les plus recherchés dans les environnements d'hébergement ou les centres de données est la détection en temps réel des tentatives d'exploitation des vulnérabilités des applications web (par exemple, WordPress et ses plugins) et la réaction automatique, généralement en bloquant ou en mettant sur liste noire l'adresse IP source dans le pare-feu.

Suricata, grâce à des règles mises à jour, est capable de reconnaître des schémas d'attaque spécifiques ciblant les URL, les paramètres, les charges utiles HTTP et même les séquences de requêtes correspondant à des vulnérabilités connues. Le système de détection d'intrusion (IDS) peut fonctionner en mode passif, recevant le trafic par duplication depuis un port de commutateur (SPAN). Toutefois, pour agir comme un système de prévention d'intrusion (IPS) et bloquer les attaques, il doit être intégré au plan de transfert.

Deux approches sont courantes : configurer le système de détection d'intrusion (IDS) comme un pont en ligne, de sorte que le trafic transite physiquement par la machine (via iptables, AF_PACKET ou PF, selon la plateforme), ou conserver la topologie existante tout en combinant la mise en miroir avec des actions sur le pare-feu central via une API, des scripts ou NFQUEUE . La première approche minimise la latence entre la détection et le blocage, au prix de l'ajout d'un élément supplémentaire au sein du réseau ; la seconde offre une plus grande flexibilité et une meilleure résilience, mais complexifie l'orchestration.

Il est tout à fait possible pour un système de détection d'intrusion (IDS) de détecter une tentative d'exploitation d'une extension WordPress vulnérable, puis d'ajouter l'adresse IP de l'attaquant à une liste noire iptables, soit directement, soit par l'intermédiaire d'un composant associé. Cela peut se faire via la sortie JSON de Suricata et des scripts appelant iptables/nftables , ou en déléguant une partie de la logique à NFQUEUE. Dans ce cas, le moteur lui-même, ou un processus associé, prend la décision à la volée sans attendre la mise à jour d'une liste externe.

Cela vous permet de vous concentrer sur les menaces qui comptent vraiment (exploits, tentatives d'escalade, analyses très agressives), en ignorant ou en enregistrant simplement le bruit de fond tel que les analyses de ports de base qui, dans de nombreux contextes, ne sont pas inquiétantes en elles-mêmes.

Suricata sur pfSense : pare-feu open source avec IDS/IPS intégré

Tout le monde ne peut pas ou ne souhaite pas s'offrir un pare-feu propriétaire haut de gamme comme Palo Alto. Dans de nombreux environnements, il est plus avantageux de mettre en place une solution open source avec pfSense et Suricata , qui couvre à la fois les besoins avancés en matière de pare-feu (multi-WAN, VLAN, VPN, NAT, etc.) et de détection/prévention d'intrusion (IDS/IPS).

Pfsense, basé sur FreeBSD et Packet Filter, fonctionne particulièrement bien avec les environnements virtualisés (Proxmox, KVM, etc.), à l'exception du fait qu'il est recommandé d'utiliser des cartes E1000 au lieu de Virtio dans les machines KVM si vous souhaitez éviter les problèmes de performances et les plantages en cas de forte charge, à moins d'appliquer les recommandations de Netgate (désactiver le déchargement de la somme de contrôle matérielle dans Système > Avancé > Réseau et redémarrer, sachant que cela peut ne pas suffire en cas de charges très élevées).

La configuration matérielle minimale requise pour un laboratoire avec Suricata sur Pfsense peut être modeste (1 processeur 500 MHz, 1 Go de RAM, 4 Go de disque), mais pour une utilisation sérieuse, il est recommandé d'avoir au moins 2 processeurs, 4 Go de RAM et 16 Go de stockage , sans oublier de disposer de plusieurs interfaces réseau (une pour le WAN, une autre pour le LAN, et plus encore si vous souhaitez plusieurs WAN ou des VLAN complexes).

  Guide complet des flux de travail des agents d'IA et de sécurité des applications

L'installation de pfSense est très rapide : il suffit de démarrer sur l'ISO, d'accepter la licence, de choisir l'installation, de sélectionner la langue et la disposition du clavier, de laisser le partitionnement en mode automatique (Auto UFS si vous comptez utiliser la totalité du disque), et en quelques minutes, le système est prêt pour son premier démarrage. La console propose un menu permettant d'attribuer les interfaces, de redémarrer, de lancer le shell, etc.

Dans un laboratoire, par exemple dans VirtualBox, il est courant de désactiver temporairement le pare-feu Pfsense depuis la console avec pfctl -d afin d'accéder à l'interface web via le WAN (nom d'utilisateur admin, mot de passe pfsense) et de terminer l'assistant initial : données générales, serveurs NTP, configuration WAN (DHCP est généralement suffisant dans le laboratoire), LAN, changement du mot de passe administrateur et application de la configuration.

Une fois l'accès stabilisé, vous pouvez créer une règle dans le pare-feu WAN autorisant le trafic HTTPS depuis n'importe quelle source vers l'adresse IP de pfSense, en ajoutant des séparateurs descriptifs pour une meilleure lisibilité (par exemple, « Accès pare-feu »). Il est également conseillé de désactiver le blocage des réseaux privés sur le WAN dans un environnement de test avec des adresses RFC 1918, afin d'éviter d'avoir à utiliser constamment la commande `pfctl -d`.

Installation et présentation de Suricata sur pfSense

Une fois pfSense installé et fonctionnel, l'installation de Suricata est très simple : il suffit d'aller dans Système > Gestionnaire de paquets > Paquets disponibles , de rechercher Suricata et de l'installer. Le processus télécharge plusieurs fichiers et peut prendre un certain temps selon votre configuration matérielle, mais il est entièrement guidé par l'interface web.

Une fois installé, Suricata fait apparaître une entrée dans l'onglet Services. Vous pouvez y configurer les instances par interface (WAN, LAN, VLAN, etc.), choisir les ensembles de règles à utiliser, activer le mode IDS ou IPS et ajuster les paramètres de performance et de journalisation. L'éventail d'options est vaste (de quoi consacrer des articles entiers à la seule configuration), mais l'avantage est que de nombreuses tâches qui sous Linux nécessitent une modification manuelle du fichier YAML sont ici gérées par des formulaires et des cases à cocher.

Remarque importante : Bien qu’il puisse être tentant d’ouvrir l’interface d’administration de pfSense directement sur Internet en environnement de test, en production, il est crucial de limiter l’accès aux adresses IP statiques, d’utiliser des VPN pour la gestion à distance et d’éviter à tout prix de laisser la console web exposée . pfSense est très flexible, mais il doit également être traité comme l’élément critique qu’il est.

Avec Suricata activé sur pfSense, le trafic transite par pfSense pour le pare-feu et la NAT, puis Suricata l'inspecte selon ses règles et peut le bloquer en mode IPS . Cette solution, gérée depuis une interface web unique, simplifie considérablement le déploiement de la protection DPI dans les réseaux de petite et moyenne taille.

Dans de nombreux déploiements, cette solution est complétée par une connexion de Pfsense/Suricata à un SIEM ou à une plateforme de journalisation centralisée, tirant parti des formats de sortie structurés pour corréler les événements et détecter des campagnes plus vastes.

Surveillance des événements et exemples de journaux dans Suricata

Une fois Suricata lancé, les événements sont consignés dans le répertoire défini par default-log-dir, généralement /var/log/suricata . Le fichier fast.log utilise un format texte compact avec horodatage, identifiants de règles, classifications et priorité, ce qui permet une consultation rapide depuis le terminal (tail -f).

Par exemple, en cas de trafic présentant des sommes de contrôle TCP incorrectes, nous pourrions voir des lignes comme celles-ci : un horodatage avec la date et l’heure, suivi de l’identifiant de la règle (par exemple, 1:2200074:1), du message « SURICATA TCPv4 somme de contrôle invalide », de la classification, de la priorité et de la paire adresse IP/port source-destination. Ces types d’alertes permettent d’identifier rapidement les problèmes d’intégrité des paquets ou les tentatives d’évasion.

Le fichier eve.json contient les mêmes événements au format JSON, avec des champs tels que timestamp, event_type, src_ip, dest_ip, src_port, dest_port, proto, et un sous-fichier d'alerte contenant action, gid, signature_id, rev, signature, category et severity. Ce format est facilement compatible avec Logstash, Fluentd, Filebeat et tout autre agent de journalisation , permettant ainsi des analyses bien plus poussées qu'avec du texte brut.

Lors du déploiement de Suricata sur un serveur multicœur (par exemple, 8 cœurs), la compression des threads est clairement visible dans des outils comme htop en mode thread, affichant un ou plusieurs threads de capture (pcap, AF_PACKET ou NFQ) et un grand nombre de threads de détection répartis sur les cœurs. Ajuster le ratio des threads de détection et l'affinité du processeur peut avoir un impact significatif sur le débit et la latence lorsque le volume de trafic approche les limites de la plateforme.

Avant le déploiement en production, il est conseillé de bien paramétrer les ensembles de règles activés afin d'éviter un afflux de faux positifs susceptibles de bloquer le trafic légitime ou d'encombrer les journaux. Suricata-update permet de désactiver des catégories entières ou des règles individuelles pour trouver un juste équilibre entre sensibilité et facilité d'utilisation.

Applications spécifiques : VoIP, analyse audio et NFQUEUE créatif

Au-delà des usages classiques (protection des services web, détection de logiciels malveillants, analyse des attaques DDoS), le duo Netfilter + NFQUEUE permet des solutions très innovantes dans des domaines tels que la VoIP. Il est par exemple possible de configurer un filtre anti-SPIT (spam sur IP) ou un système de censure des grossièretés dans les flux RTP.

L'idée serait la suivante : identifier le trafic RTP par ports ou par reconnaissance de protocole et l'envoyer à NFQUEUE ; depuis l'application utilisateur, reconstruire le flux RTP à l'aide d'une bibliothèque comme librtp , extraire l'audio au format WAV et le transmettre à un moteur de reconnaissance de mots clés (repérage de mots), tel qu'une bibliothèque de synthèse ou de reconnaissance proposée par un tiers.

En fonction des mots détectés, le processus NFQUEUE peut autoriser, bloquer ou même modifier la lecture en insérant un bip dans le flux. Cette dernière option exige toutefois un contrôle très précis du protocole RTCP, des séquences de paquets et de la synchronisation, ce qui s'apparente à une attaque de l'homme du milieu. Bien que complexe, cette solution est théoriquement réalisable en utilisant le même système de file d'attente et de décision.

Il est vrai que certaines de ces opérations pourraient être réalisées à l'aide d'un simple analyseur de trafic transmettant des données à un processeur externe, puis agissant sur la signalisation SIP ou via un SBC (Asterisk, Kamailio, etc.). La différence avec NFQUEUE réside dans le fait que l'action sur le flux RTP est immédiate et directe , sans nécessiter la coordination de plusieurs composants ni l'attente de la fin de l'appel par la couche de signalisation.

Ces scénarios illustrent clairement le potentiel de la combinaison GNU/Linux + Netfilter + Suricata + bibliothèques tierces : il ne s’agit pas seulement de bloquer des ports et des adresses IP, mais d’ orchestrer des décisions complexes en matière de trafic en temps réel grâce à un écosystème logiciel 100 % libre.

En considérant l'ensemble du parcours, depuis le petit programme C qui accepte toujours les paquets jusqu'à un déploiement Suricata multiprocessus intégré à NFQUEUE, Pfsense, des bases de données et des caches, on peut apprécier la flexibilité qu'offre cette pile technologique pour construire tout, des pare-feu dynamiques simples aux architectures IDS/IPS à l'échelle d'un centre de données, avec de véritables capacités d'inspection approfondie et une réponse automatisée à des attaques de plus en plus complexes.