CrowdSec en première ligne, bloque avant qu'on te frappe
Installer CrowdSec sur ton VPS durci, bloquer les IP malveillantes en amont avec le bouncer firewall, et faire remonter ses décisions dans Wazuh.
À l’épisode précédent, tu as enrôlé les agents Wazuh sur tout ton parc. Serveurs Linux, Mac, Windows, chaque machine remonte ses journaux au manager, entièrement par le Tailnet. Ton SIEM a levé le nez de ses propres journaux, ton parc entier s’affiche devant lui. Il voit tout, en réalité. Y compris les attaques.
Et c’est là que le bât blesse. Un agent Wazuh observe, on l’a répété tout l’épisode 3. Il te dit qu’une rafale d’échecs de connexion vient de frapper ton serveur, il te le dit très bien, très vite, très en détail. Mais il ne fait rien pour l’arrêter. Tu as des yeux, tu n’as pas de mains.
Aujourd’hui, on te donne les mains. On installe CrowdSec, la première ligne de défense active de la série. Un moteur qui lit tes journaux comme Wazuh, mais qui, lui, en tire une conclusion et bloque. L’IP qui martèle ton SSH, il la met dehors. L’attaquant déjà repéré ailleurs sur le réseau communautaire, il le refoule avant même qu’il ne toque à ta porte.
Un point posé dès l’épisode 1 et qui tient toujours. La quasi-totalité de tes services vit en Tailnet-only, invisible depuis l’internet ouvert. Mais certaines portes doivent rester ouvertes sur le monde, un serveur mail qui reçoit sur le port 25, une présence web publique. Ce sont ces portes-là, les seules exposées, que CrowdSec garde.
Cette stack, je l’utilise au quotidien. Les commandes qui suivent sont celles que tu vas taper toi-même, dans l’ordre, sur ton VPS durci puis dans ton manager Wazuh.
Avant de commencer
Trois choses à avoir en tête avant la première commande.
Ce qu’il te faut. Un VPS durci comme celui de l’épisode 1, à jour, avec au moins un service exposé sur l’internet ouvert à protéger. Le manager Wazuh de l’épisode 2, opérationnel, pour la partie intégration en fin de tuto. Un accès administrateur sur la machine. Et de quoi lire tes propres journaux, /var/log/auth.log et les logs de tes services, puisque c’est la matière première de CrowdSec.
Ce que ça change. À la fin, les IP malveillantes connues n’atteignent plus tes services, elles butent sur ton pare-feu avant. Tu bénéficies aussi de la liste communautaire, des millions de signaux remontés par les autres utilisateurs, donc tu bloques des attaquants que tu n’as jamais vus toi-même. Et ton SIEM voit enfin cette couche de défense, chaque blocage remonte dans Wazuh.
Ce que ça ne change pas. CrowdSec bloque au niveau réseau, sur l’adresse IP. Ce n’est ni un antivirus, ni un pare-feu applicatif exhaustif, ni un remplaçant de ton durcissement de l’épisode 1. C’est une couche de plus, la première que rencontre l’attaquant, pas la seule. Et il bloque l’IP, pas l’humain derrière, une IP change, la défense se joue sur le volume et la vitesse, pas sur l’infaillibilité.
Comment CrowdSec voit et bloque
Avant d’installer quoi que ce soit, comprends la mécanique, elle tient en trois pièces qui se passent le relais.
Le moteur de sécurité, l’agent local. Il lit tes journaux en continu, auth.log, les logs de ton serveur web, de ton serveur mail. Il les passe dans des scénarios, des règles de comportement du type « six échecs SSH en dix secondes depuis la même IP, c’est du bruteforce ». Quand un scénario se déclenche, le moteur prend une décision, en clair, il inscrit cette IP sur une liste noire pour une durée donnée, quatre heures par défaut sur du bruteforce.
Le bouncer, l’exécuteur. Le moteur décide, mais il ne touche pas lui-même à ton pare-feu, c’est un choix d’architecture propre. C’est le bouncer qui applique la décision. Le bouncer firewall, celui qui nous intéresse, va poser la règle qui jette l’IP fautive dans ton nftables ou ton iptables. Moteur et bouncer sont séparés, tu peux en avoir plusieurs, un pour le pare-feu, un devant un reverse proxy web, chacun applique les mêmes décisions à son niveau.
Le réseau communautaire, le CTI, pour Cyber Threat Intelligence, renseignement sur les menaces. C’est le multiplicateur. Quand ton moteur bloque une IP, il remonte le signal, l’adresse et le scénario, à l’API centrale de CrowdSec. En échange, tu télécharges la liste communautaire, l’agrégat des IP signalées par l’ensemble des utilisateurs. Résultat, une IP qui a attaqué un serveur en Pologne ce matin est déjà bloquée chez toi cet après-midi, avant sa première tentative.
Retiens le flux, il commande tout le reste. Journal lu par le moteur, scénario déclenché, décision prise, bouncer qui l’applique sur le pare-feu, signal partagé, liste communautaire téléchargée en retour.
Étape 1, installer le moteur
On commence par le cerveau, sur ton VPS durci. Deux commandes, une pour déclarer le dépôt officiel CrowdSec, une pour installer.
curl -s https://install.crowdsec.net | sudo sh
sudo apt install crowdsec
La première ligne ajoute le dépôt CrowdSec à ta liste de sources, la routine que tu connais depuis l’épisode 3 avec Wazuh. La seconde installe et démarre le moteur.
L’installation est maligne sur un point. À la fin, CrowdSec scanne les services qu’il détecte sur ta machine et installe automatiquement les collections correspondantes, les paquets de scénarios adaptés. Il voit un serveur SSH, il installe la collection crowdsecurity/sshd. Un Nginx, il ajoute les scénarios web. Tu n’as pas à deviner quoi surveiller, il le déduit de ce qui tourne.
Vérifie ce qu’il a mis en place.
sudo cscli collections list
Tu dois voir la liste des collections actives, avec la mention enabled. Si un service exposé n’est pas couvert, tu ajoutes sa collection à la main, par exemple sudo cscli collections install crowdsecurity/nginx puis un redémarrage du service crowdsec. Tout se pilote avec cscli, l’outil en ligne de commande du moteur, l’équivalent de ton agent_control côté Wazuh.
À ce stade, le moteur lit, analyse et décide. Mais il ne bloque encore rien. Il tient une liste noire que personne n’applique. Il lui manque ses mains.
Étape 2, poser le bouncer qui bloque vraiment
Les mains, c’est le bouncer firewall. Il lit les décisions du moteur et les traduit en règles de pare-feu qui refoulent réellement le trafic.
Il en existe deux variantes selon ton pare-feu, une pour nftables, une pour iptables. Les distributions récentes tournent sous nftables, c’est le cas par défaut.
sudo apt install crowdsec-firewall-bouncer-nftables
Si ta machine est sur l’ancien iptables, tu remplaces le paquet par crowdsec-firewall-bouncer-iptables. Le principe est identique. Un détail de cohérence avec l’épisode 1, si ton pare-feu tourne sous ufw, sache que ufw s’appuie sur l’un des deux backends selon ta version, vérifie lequel avant de choisir la variante du bouncer.
L’installation fait le branchement toute seule. Le paquet appelle cscli bouncers add pour lui, enregistre le bouncer auprès du moteur et lui remet une clé d’authentification. Aucune manipulation de clé à faire à la main.
Vérifie que le moteur et son bouncer se parlent.
sudo cscli bouncers list
Tu dois voir ton bouncer firewall listé, avec une date de dernière activité récente. À partir de maintenant, la boucle est fermée. Le moteur décide, le bouncer applique, l’IP fautive tombe dans un ensemble bloqué par ton pare-feu. Ton SIEM a des mains.
Étape 3, vérifier que ça mord
Trois commandes pour t’assurer que la machine tourne, et une pour la mettre à l’épreuve sans attendre une vraie attaque.
D’abord la vue d’ensemble.
sudo cscli metrics
Elle t’affiche combien de lignes de logs le moteur a lues, par source, et combien de fois chaque scénario s’est déclenché. Si les compteurs de lecture bougent, ton moteur voit bien tes journaux. S’ils restent à zéro, il ne lit rien, et là c’est un problème de source à régler avant d’aller plus loin.
Ensuite les décisions en cours, la liste noire vivante. Ajoute le drapeau -a, sinon CrowdSec ne t’affiche que tes décisions locales et masque les IP tirées du réseau communautaire.
sudo cscli decisions list -a
Sur une machine exposée depuis quelques heures, elle n’est déjà pas vide, entre tes propres blocages et la liste communautaire téléchargée. Chaque ligne, une IP, le scénario qui l’a fait tomber, la durée restante.
Regarde la colonne Source. Les lignes CAPI, ce sont les cadeaux de la communauté, des IP que tu n’as jamais vues toquer chez toi et qui sont déjà refoulées. La ligne crowdsec en gras, c’est la tienne, un scanner que ton propre serveur a chopé en plein http-probing et banni tout seul, trois heures au coin. Le collectif et le local, côte à côte, dans la même liste noire.
Enfin, l’épreuve. Plutôt que d’attendre un attaquant, tu fabriques une décision de test sur une IP bidon.
sudo cscli decisions add --ip 192.0.2.1 --duration 4h --reason "test blocage"
sudo cscli decisions list
L’IP 192.0.2.1 appartient à une plage réservée à la documentation, elle ne bloquera personne de réel. Tu la vois apparaître dans la liste, le bouncer la pousse dans ton pare-feu. Nettoie derrière toi une fois le test concluant.
sudo cscli decisions delete --ip 192.0.2.1
Si l’ajout, l’affichage et la suppression s’enchaînent proprement, ta chaîne moteur-décision-bouncer est opérationnelle de bout en bout.
Étape 4, le signal communautaire, ce qui sort et ce qui reste
C’est là que CrowdSec change d’échelle, et c’est aussi le seul endroit où la souveraineté demande une phrase d’honnêteté, alors posons-la sans détour.
Par défaut, ton moteur est inscrit à l’API centrale communautaire. Tu peux le vérifier.
sudo cscli capi status
Cet échange fonctionne dans les deux sens, et c’est important de savoir exactement quoi. Ce qui sort de chez toi, quand tu bloques une IP, c’est un signal minimal, l’adresse IP fautive, le scénario déclenché et l’horodatage. Ce qui ne sort jamais, ce sont tes journaux, tes noms de machines, tes utilisateurs, le contenu de quoi que ce soit. CrowdSec partage la conclusion « cette IP attaque », pas la matière première qui t’a permis d’y arriver. Ce qui rentre, c’est la liste communautaire, l’agrégat anonymisé de ces signaux à l’échelle de tout le réseau.
C’est un compromis, et il est net. Tu échanges l’adresse d’attaquants, une donnée qui n’est pas la tienne mais celle de tes agresseurs, contre une protection collective que tu ne pourrais jamais construire seul. Le moteur, lui, reste auto-hébergé chez toi, aucun tiers ne pilote tes blocages, aucune décision ne dépend d’un service distant qui pourrait être coupé. Tu peux même te désinscrire du partage et tourner en pur local, tu gardes ta défense, tu perds seulement la liste communautaire. Le curseur est entre tes mains, comme toujours dans cette série.
Si tu veux une console web pour visualiser tes alertes, CrowdSec en propose une, gratuite, où tu relies ton moteur avec sudo cscli console enroll <ta-clé>. Facultatif, et hébergé par CrowdSec, donc à peser selon ta ligne. Ton vrai tableau de bord, de toute façon, c’est Wazuh, et c’est l’étape suivante.
Étape 5, faire remonter CrowdSec dans Wazuh
Ton pare-feu bloque, très bien. Mais pour l’instant ton SIEM ne le sait pas. CrowdSec agit dans son coin, Wazuh regarde ailleurs. On les branche, pour que chaque décision CrowdSec devienne une alerte visible dans ton tableau de bord unique.
Le principe est simple et propre. CrowdSec sait écrire ses alertes dans un fichier, et Wazuh sait lire un fichier de logs. On fait se rencontrer les deux.
Côté CrowdSec, tu actives le plugin de notification par fichier. Il existe déjà, tu l’édites dans /etc/crowdsec/notifications/file.yaml pour qu’il écrive au format JSON, une alerte par ligne.
type: file
name: file_default
log_level: info
format: |
{{range . -}}
{ "crowdsec": { "program": "crowdsec", "alert": {{. | toJson }} }}
{{ end -}}
log_path: "/var/log/crowdsec/crowdsec_alerts.json"
rotate:
enabled: true
max_size: 500
compress: true
Puis tu déclares ce canal dans /etc/crowdsec/profiles.yaml, pour que le moteur y envoie ses alertes.
notifications:
- file_default
Un détail qui compte. Le tutoriel officiel de CrowdSec écrit ce fichier dans /tmp, qui est vidé à chaque redémarrage de la machine. On le pose plutôt dans /var/log/crowdsec/, pour que ton historique d’alertes survive à un reboot. Un redémarrage du service crowdsec, et le fichier /var/log/crowdsec/crowdsec_alerts.json se remplit à chaque décision.
Côté Wazuh, tu dis à l’agent local, celui de l’épisode 3 déjà installé sur ce serveur, de lire ce fichier. Tu ajoutes ce bloc à sa configuration, idéalement via la configuration partagée du groupe pour ne l’écrire qu’une fois.
<localfile>
<location>/var/log/crowdsec/crowdsec_alerts.json</location>
<log_format>json</log_format>
<label>crowdsec</label>
</localfile>
Tu reconnais la logique du <localfile>, c’est exactement le mécanisme par lequel Wazuh avale n’importe quelle source de journaux. Le format json lui dit de parser chaque ligne comme un objet structuré, et tes champs crowdsec.alert.* deviennent interrogeables dans le dashboard.
Redémarre l’agent Wazuh, et la boucle de la série se referme. Une IP attaque, CrowdSec la bloque, écrit l’alerte, l’agent Wazuh la lit, le manager la remonte, elle s’affiche dans ton tableau de bord à côté de tout le reste. Ton SIEM ne voit plus seulement les attaques, il voit ses propres ripostes.
Une note de version, parce qu’elle compte. Cette intégration par plugin fichier suppose une version récente du moteur et de Wazuh. Vérifie que ton CrowdSec est en 1.6.3 ou au-dessus et que ton Wazuh est en 4.9.0 ou au-dessus, les versions à partir desquelles cette intégration par plugin fichier est officiellement supportée. Tu tournes sur du Wazuh 4.x, cette intégration ne dépend pas de la future 5.0, elle marche sur ta stack actuelle.
Si ça ne marche pas
Le déploiement de CrowdSec est direct, et il coince presque toujours aux mêmes endroits. Voici les vrais, dans l’ordre où tu les rencontreras.
Problème, cscli metrics affiche zéro ligne lue
Cause probable, le moteur ne trouve pas tes journaux, ou n’a pas la collection correspondant à ton service. Il tourne, mais il lit dans le vide.
Solution, vérifie que la source de logs existe bien au chemin attendu et que la collection du service est installée avec sudo cscli collections list. Ajoute la collection manquante, puis redémarre le service crowdsec.
Problème, une IP est décidée mais rien n’est bloqué
Cause probable, le bouncer n’est pas là, ou ne parle pas au moteur. Le moteur décide dans son coin, personne n’applique.
Solution, sudo cscli bouncers list doit montrer ton bouncer firewall avec une activité récente. S’il est absent, réinstalle le paquet du bouncer. S’il est présent mais muet, vérifie que le service du bouncer tourne.
Problème, le mauvais backend de pare-feu
Cause probable, tu as installé la variante nftables du bouncer sur une machine en iptables, ou l’inverse. Le bouncer pose ses règles dans un système que ton pare-feu n’utilise pas.
Solution, identifie ton backend réel, puis installe la variante correspondante du bouncer, crowdsec-firewall-bouncer-nftables ou crowdsec-firewall-bouncer-iptables.
Problème, rien ne remonte dans Wazuh
Cause probable, attention, ce n’est en général pas un problème CrowdSec. Le fichier /var/log/crowdsec/crowdsec_alerts.json se remplit, mais l’agent Wazuh ne le lit pas, ou le manager ne digère pas le format.
Solution, vérifie d’abord que le fichier grossit côté CrowdSec. S’il grossit, le diagnostic est côté Wazuh, le bloc <localfile> et la version de l’agent, pas côté moteur. Ne réinstalle pas CrowdSec pour un souci de lecture Wazuh.
La liste communautaire fait la moitié du travail
Un dernier mot, parce que c’est le point qu’on sous-estime toujours au départ. Le jour où tu installes CrowdSec, tu t’attends à ce qu’il apprenne lentement, à ce qu’il faille des semaines de trafic pour qu’il devienne utile. Faux.
Dès la première synchronisation, tu télécharges la liste communautaire, et ton cscli decisions list -a se peuple d’IP que tu n’as jamais vues. Des attaquants repérés ailleurs, déjà refoulés chez toi. Tu bénéficies du travail de dizaines de milliers d’autres serveurs avant d’avoir subi ta première attaque.
Ce n’est pas magique, c’est du volume. Chaque serveur qui remonte un signal renforce la défense de tous les autres. C’est exactement le modèle que le SaaS américain te vend cher et sous sa juridiction, sauf qu’ici il est open source, auto-hébergé, et le signal partagé se limite à l’adresse de tes agresseurs.
Le tournant est franchi. Là où ton SIEM se contentait de constater, il refoule.
Pour les pressés
Ce que fait cet article. On installe CrowdSec sur le VPS durci pour bloquer en amont les IP malveillantes, connues localement comme signalées par le réseau communautaire. Le moteur lit les journaux et décide, le bouncer firewall applique le blocage sur nftables ou iptables, et chaque décision remonte dans Wazuh via un fichier d’alertes lu par l’agent. La défense passe de « voir » à « barrer la route ».
Concrètement, les commandes.
- Installer le moteur :
curl -s https://install.crowdsec.net | sudo shpuissudo apt install crowdsec. - Vérifier les collections détectées :
sudo cscli collections list. - Installer le bouncer firewall selon ton backend :
sudo apt install crowdsec-firewall-bouncer-nftables(ou-iptables). - Vérifier le branchement :
sudo cscli bouncers list. - Contrôler la machine :
sudo cscli metricsetsudo cscli decisions list -a(le-apour voir aussi la liste communautaire). - Tester le blocage :
sudo cscli decisions add --ip 192.0.2.1 --duration 4h --reason "test"puissudo cscli decisions delete --ip 192.0.2.1. - Vérifier le partage communautaire :
sudo cscli capi status. - Intégrer à Wazuh : activer le plugin fichier dans
/etc/crowdsec/notifications/file.yaml(sortie/var/log/crowdsec/crowdsec_alerts.json), l’appeler dans/etc/crowdsec/profiles.yaml, puis ajouter le bloc<localfile>JSON à la config de l’agent Wazuh.
En résumé
Tu es parti d’un SIEM qui voyait les attaques sans pouvoir les arrêter, tu repars avec une première ligne qui les refoule.
Tu as installé le moteur CrowdSec sur ton VPS durci, qui lit tes journaux et décide. Tu as posé le bouncer firewall, qui applique ces décisions sur ton pare-feu et bloque réellement. Tu as branché la liste communautaire, qui te protège d’attaquants que tu n’as jamais croisés, en ne partageant que l’adresse des tiens. Et tu as fait remonter tout ça dans Wazuh, pour que ta salle de contrôle voie enfin la couche de défense réseau.
Le tout reste chez toi. Le moteur est auto-hébergé, aucune décision ne dépend d’un tiers, et le seul signal qui sort, c’est l’IP de tes agresseurs. La protection collective sans la dépendance, c’est précisément le troisième chemin, le souverain, ouvert à l’épisode d’introduction.
Tu bloques désormais au niveau réseau. Mais tes attaques les plus fréquentes n’arrivent pas par le port SSH, elles arrivent par la boîte mail. À l’épisode 5, on monte le filtre anti-spam et anti-hameçonnage devant ton serveur de messagerie, la porte la plus exposée de toutes.
Rappel de la série
Sept épisodes pour monter ta plomberie de sécurité souveraine, brique par brique.
- Épisode 0, le fondement de la série. Pourquoi une PME a besoin d’un SIEM souverain, NIS2, RGPD, et le coût du statu quo.
- Épisode 1, le socle. Le VPS durci hors CLOUD Act.
- Épisode 2, Wazuh en tout-en-un. Manager, indexeur et tableau de bord sur un seul nœud.
- Épisode 3, les agents partout. Déploiement sur tes serveurs, Mac et Windows.
- Épisode 4, la défense réseau communautaire. Bloquer les attaquants connus avant qu’ils n’arrivent. Tu viens de le lire.
- Épisode 5, le filtre mail. Anti-spam et anti-hameçonnage devant ton serveur de messagerie.
- Épisode 6, le contrôle d’exécution sur les Mac. Décider quelles applications ont le droit de démarrer.
- Épisode 7, alerting et coût total. Notifications calibrées et bilan financier honnête face au SaaS.
Des termes techniques ? Consulte le glossaire.