Contenu

Automatiser le ban d'IPs avec Cloudflare WAF, CrowdSec et AbuseIPDB

⚡ En bref

Le monitoring passif ne suffit pas. Ce pipeline automatise la fermeture de la boucle en moins de 5 minutes entre une attaque détectée par Cloudflare WAF et le ban effectif de l’IP dans CrowdSec, sa synchronisation vers Cloudflare et son signalement sur AbuseIPDB. Un script Python poll l’API GraphQL Cloudflare toutes les 5 minutes, applique un seuil de 3 hits, et déclenche le ban avec escalade récidiviste.

🧠 Pourquoi

Voir une attaque dans les logs BetterStack après coup n’empêche pas l’IP malveillante de continuer à frapper. Sans automatisation, la boucle détection → ban prend des heures ou ne se ferme jamais. Les actions WAF Cloudflare (block, challenge, managed_challenge, jschallenge) sont des signaux clairs d’attaque, mais ils restent confinés dans le dashboard Cloudflare — sans pont vers CrowdSec, aucune IP n’est bannie localement, aucune n’est signalée à la communauté AbuseIPDB.

🔧 Ce qui a été fait

Architecture du pipeline

Cloudflare WAF (block / challenge / managed_challenge)
        ↓  poll toutes les 5 minutes (API GraphQL)
crowdsec-cf-sync.py  →  seuil : 3 hits / 5 min par IP
        ↓
CrowdSec (cscli decisions add)  →  escalade récidivistes
        ↓
Cloudflare IP Access Rules (ban synchronisé)
        ↓
AbuseIPDB (report catégories 19 + 21)
        ↓
BetterStack (log enrichi source crowdsec-decisions)

1. Collecte des événements WAF Cloudflare

La fonction poll_cloudflare_waf() interroge l’API GraphQL Cloudflare toutes les 5 minutes et récupère les événements avec les actions suivantes :

  • block
  • challenge
  • managed_challenge
  • jschallenge

Un fichier d’état (cf_waf_state.json) conserve le timestamp du dernier événement traité pour éviter tout doublon entre deux cycles.

2. Détection et seuil

Les événements sont regroupés par IP source. Le ban se déclenche uniquement si une IP cumule 3 hits ou plus dans une fenêtre glissante de 5 minutes. Ce seuil évite les faux positifs liés aux challenges légitimes (bots de monitoring, scanners déclarés comme Palo Alto Xpanse, etc.).

3. Whitelist

La whitelist CrowdSec existante (my_allowlist) est consultée avant tout ban. Elle inclut notamment les IPs des bots de monitoring, les plages Cloudflare et BetterStack. Aucune IP whitelistée ne peut être bannie par ce mécanisme.

4. Escalade des bans (récidivistes)

Le système applique la même logique d’escalade que les autres sources de ban :

OccurrenceDurée du ban
1er ban4 heures
2ème ban24 heures
3ème ban et +168 heures (7 jours)

Le compteur de récidive est partagé avec les bans CrowdSec classiques via recidivists.json.

5. Signalement AbuseIPDB

Chaque IP bannie est automatiquement signalée sur AbuseIPDB avec :

  • Catégorie 19 : Web Application Attack
  • Catégorie 21 : Web App Scan
  • Un commentaire incluant le nombre de hits Cloudflare et les URIs ciblées

6. Logging BetterStack

Chaque ban génère une entrée enrichie dans la source crowdsec-decisions avec les champs spécifiques :

{
  "source": "cloudflare_waf",
  "cf_action": "managed_challenge",
  "hit_count": 23,
  "uris_targeted": ["/wp.php", "/shell.php", "/backdoor.php"],
  "cs_scenario": "cloudflare-waf/23-hits",
  "cs_duration": "168h"
}

Exemple réel — nuit du 9 avril 2026

Un scan massif de webshells PHP a été détecté et neutralisé automatiquement :

ChampValeur
IP sourceAzure France
Hits détectés23 en < 1 minute
URIs ciblées/wp.php, /shell.php, /gpt-sh.php, /wp-content/plugins/hellopress/wp_filemanager.php
Action Cloudflaremanaged_challenge (Bot Fight Mode)
Ban appliqué168h (récidiviste)
Score AbuseIPDB100%
Délai détection → ban< 5 minutes

Aucune de ces ressources n’existe sur le serveur (Grav CMS, pas WordPress).

Fichiers et services impliqués

ComposantEmplacement
Script principal/usr/local/bin/crowdsec-cf-sync.py
État WAF/var/log/crowdsec/cf_waf_state.json
Récidivistes/var/log/crowdsec/recidivists.json
Service systemdcrowdsec-cf-sync.service
Config Vector/etc/vector/vector.yaml

Commandes utiles

# Surveiller les bans WAF en temps réel
journalctl -fu crowdsec-cf-sync | grep -i "waf\|cloudflare"

# Voir les récidivistes
cat /var/log/crowdsec/recidivists.json | python3 -c "
import json,sys
d=json.load(sys.stdin)
for ip,v in sorted(d.items(), key=lambda x: x[1]['count'], reverse=True):
    print(f'{ip:20} count={v[\"count\"]} last={v[\"last_seen\"]}')
"

# Voir l'état du dernier poll WAF
cat /var/log/crowdsec/cf_waf_state.json | python3 -m json.tool

# Redémarrer le service
systemctl restart crowdsec-cf-sync

🏁 Conclusion

Ce pipeline réduit le délai de réponse à une attaque de plusieurs heures à moins de 5 minutes. Les IPs agressives sont bannies localement, synchronisées vers Cloudflare et signalées à la communauté AbuseIPDB de façon automatique et sans intervention manuelle. L’escalade récidiviste garantit que les attaquants persistants accumulent des bans de plus en plus longs.

Pour aller plus loin :

  • 💡 Ajouter une intégration avec VirusTotal pour scorer les IPs avant signalement sur AbuseIPDB
  • 💡 Implémenter un tableau de bord BetterStack dédié avec alertes sur les pics de bans WAF