Ce document rassemble les précautions communes au reporter Fail2ban et au synchroniseur de blocklists.

1. Deux flux indépendants

Ne confondez pas :

Fail2ban -> POST /api/v1/reports

et :

GET /blocklists/{slug}/ipv4.txt
GET /blocklists/{slug}/ipv6.txt -> pare-feu

Le premier enregistre une observation. Le second récupère un instantané publié.

La politique REPORT_AUTO_BLOCK_ENABLED=true crée par défaut une décision automatique à chaque rapport (12 h, réglable via REPORT_AUTO_BLOCK_HOURS, minimum 12 h). La permission reports:create donne donc accès à cet effet ; limiter les clés aux sources de confiance. Never Block reste prioritaire. Les publications restent générées séparément, avec les exclusions Allowlist et la validation finale.

2. Moindre privilège des clés API

Pour un serveur qui ne fait qu'envoyer des événements :

reports:create

suffit.

Créer une source/clé distincte par serveur permet de :

  • révoquer une machine sans couper les autres ;
  • identifier la source ;
  • suivre last_used_at ;
  • appliquer le quota par clé ;
  • éviter de distribuer une clé reports:read inutile.

Les publications Phase 19 sont publiques et ne nécessitent pas cette clé.

3. Stockage des secrets

Linux :

/etc/blocklist-reporter/api.key   mode 0600
/etc/blocklist-reporter/config.json

Ne pas :

  • passer la clé dans l'URL ;
  • l'inscrire dans jail.local ;
  • la committer ;
  • la journaliser ;
  • la copier dans metadata.

4. HTTPS

Les exemples production supposent HTTPS.

Le reporter et le synchroniseur ne doivent pas désactiver la validation du certificat. Une option HTTP n'est acceptable que dans un laboratoire ou un réseau explicitement considéré comme sûr.

5. Quotas des reports

Valeur documentée par défaut :

120 POST / 60 secondes / ID de clé

Une requête mal formée avec une clé autorisée consomme aussi le quota.

Si une jail produit des centaines de bans par minute :

  • vérifier si le filtre est trop large ;
  • augmenter findtime/maxretry selon le besoin ;
  • éviter de reporter des micro-événements qui ne correspondent pas à un ban ;
  • n'augmenter le quota serveur qu'après mesure.

6. Idempotence et retries

L'API n'implémente pas d'en-tête d'idempotence ni de déduplication des reports.

Donc :

  • HTTP 201 : succès certain ;
  • HTTP 400/401/403/413/422/429 : résultat HTTP connu ;
  • timeout / coupure réseau / certaines erreurs 500 : issue potentiellement incertaine.

Le helper fourni n'effectue pas de retry automatique après résultat ambigu.

Si vous ajoutez une file locale, séparez :

  • les événements définitivement refusés et rejouables après correction (429, par exemple) ;
  • les événements ambigus, qu'un replay peut dupliquer.

Vous pouvez ajouter un identifiant client dans metadata pour faciliter les recherches, mais cela ne crée pas de déduplication serveur.

7. Never Block / allowlist

Le serveur applique les protections/exceptions pendant la génération des publications. Les exports sont ensuite des instantanés.

Après modification d'une protection ou allowlist, il faut donc générer/publier une nouvelle version pour modifier ce que les clients reçoivent.

Avant d'activer un blocage global sur une machine distante :

  • protéger les bastions et adresses d'administration nécessaires ;
  • tester la publication ;
  • disposer d'une console hors bande ou d'un chemin de secours.

8. 404, 503 et liste vide

Ces trois cas ne doivent jamais être confondus :

Réponse Action cliente recommandée
200 + contenu valider puis appliquer
200 + fichier vide appliquer une liste vide, si la validation réussit
304 conserver/réutiliser le cache local validé
404 garder la dernière version active, alerter
503 garder la dernière version active, alerter
timeout/TLS garder la dernière version active, alerter

Le serveur garantit qu'un export corrompu est signalé en 503 plutôt que servi comme liste partielle ; le client doit conserver le même principe conservateur.

9. Journaux

Reporter : journaliser au minimum :

  • succès + ID de report si disponible ;
  • code HTTP d'échec ;
  • Retry-After sur 429 ;
  • erreur réseau générique.

Ne pas journaliser :

  • clé API ;
  • header Authorization ;
  • cookies de session admin ;
  • corps complet si celui-ci peut contenir des données sensibles.

Synchroniseur : journaliser :

  • slug ;
  • nombre IPv4/IPv6 ;
  • backend ;
  • succès/échec de validation ;
  • conservation de la dernière version en cas d'échec.

10. Supervision

Linux :

systemctl status blocklist-sync.timer
systemctl status blocklist-sync.service
journalctl -u blocklist-sync.service --since today

nftables :

nft list set inet blocklist blocklist4
nft list set inet blocklist blocklist6

ipset :

ipset list blocklist4 | head -50
ipset list blocklist6 | head -50

Windows :

Get-NetFirewallRule | Where-Object Name -Like 'BlocklistSync-*'

11. Tests de non-régression

Avant production, tester au moins :

  1. publication normale ;
  2. même publication → ETag / 304 ;
  3. nouvelle publication → remplacement ;
  4. fichier vide valide ;
  5. mauvais certificat TLS ;
  6. DNS indisponible ;
  7. HTTP 404 ;
  8. HTTP 503 ;
  9. ligne IP invalide simulée sur un serveur de test ;
  10. redémarrage machine avec source Phase 19 temporairement indisponible ;
  11. restauration automatique de la synchronisation quand la source revient ;
  12. adresse d'administration protégée par Never Block/allowlist.

12. Vérifier avant de bloquer

Pour un changement de politique important :

curl -fsS https://blocklist.example.net/blocklists/all/ipv4.txt > /tmp/blocklist4.txt
curl -fsS https://blocklist.example.net/blocklists/all/ipv6.txt > /tmp/blocklist6.txt

Rechercher manuellement vos préfixes critiques avant la première activation.

Attention : un simple grep ne détecte pas qu'une IP est contenue dans un supernet. Utilisez un outil CIDR ou le normaliseur Python ipaddress pour une vérification correcte.

13. Performances

Les publications peuvent contenir jusqu'à 100 000 entrées par profil selon les limites par défaut de génération de l'application.

Conséquences :

  • éviter une règle pare-feu par entrée ;
  • utiliser nftables sets ou ipset ;
  • sur Windows, regrouper de nombreuses adresses dans RemoteAddress ;
  • mesurer CPU/mémoire et durée d'application sur le matériel réel ;
  • étaler les timers sur un parc important.

14. Limites actuelles à documenter auprès des utilisateurs

  • aucune route REST de création/suppression des blocages locaux ;
  • aucune route REST de gestion des profils/flux/clés ;
  • aucune route REST pour déclencher une publication ;
  • aucun batch pour POST /api/v1/reports ;
  • aucun mécanisme d'idempotence des reports ;
  • les reports seuls ne contribuent pas aux fichiers générés ;
  • les exports Phase 19 sont des instantanés, pas des vues temps réel ;
  • un déblocage Fail2ban ne supprime pas le report historique.

15. Références internes

Ces guides ont été écrits à partir de :

  • README.md de l'application, notamment Phases 14, 16, 18 et 19 ;
  • REST_API.md, notamment Authentification, Reports, Publications et Erreurs/quotas.

Les exemples Fail2ban, systemd, nftables/ipset/UFW/Shorewall et Windows sont des intégrations clientes proposées ; ils ne sont pas présentés comme des composants déjà fournis par le projet source.

Fichiers prêts à adapter