Fail2ban pour Windows : les vraies alternatives
Fail2ban n'existe pas sous Windows. Voici à quoi ressemble la version PowerShell maison, où elle casse exactement, et ce que les alternatives apportent réellement.
Pourquoi la question revient sans cesse
Sous Linux, fail2ban est la réponse réflexe au devinage de mots de passe : il suit un log, compare les lignes d'échec à une expression régulière et insère une règle de pare-feu pour toute adresse franchissant un seuil. Il est petit, il est standard, et il figure dans tous les guides de durcissement écrits depuis quinze ans.
Les administrateurs qui passent à Windows cherchent le même outil et ne trouvent rien. Fail2ban, c'est Python plus iptables, et il ne tourne sous Windows en aucun sens utile — il n'y a pas de syslog à suivre ni d'iptables où écrire. Windows possède à la place le journal d'événements de sécurité et le pare-feu Windows : les deux mêmes ingrédients, non reliés.
La question n'est donc pas vraiment « comment installer fail2ban sous Windows ». C'est « qu'est-ce qui relie l'événement 4625 à une règle de pare-feu, et quelle part dois-je construire moi-même ».
La version maison, et son coût
La réponse « faites-le vous-même » est une tâche planifiée PowerShell. Le squelette est vraiment court — ceci lit les échecs des dix dernières minutes, les groupe par source et bloque tout ce qui dépasse le seuil :
$Threshold = 10
$RuleName = 'Block-BruteForce'
$offenders = Get-WinEvent -FilterHashtable @{
LogName='Security'; Id=4625; StartTime=(Get-Date).AddMinutes(-10)
} -ErrorAction SilentlyContinue |
ForEach-Object { ([xml]$_.ToXml()).Event.EventData.Data |
Where-Object Name -eq 'IpAddress' | Select-Object -ExpandProperty '#text' } |
Where-Object { $_ -and $_ -ne '-' } |
Group-Object | Where-Object Count -ge $Threshold | Select-Object -ExpandProperty Name
$rule = Get-NetFirewallRule -DisplayName $RuleName -ErrorAction SilentlyContinue
if (-not $rule) {
New-NetFirewallRule -DisplayName $RuleName -Direction Inbound -Action Block `
-RemoteAddress $offenders | Out-Null
} else {
$existing = ($rule | Get-NetFirewallAddressFilter).RemoteAddress
$rule | Set-NetFirewallRule -RemoteAddress @($existing + $offenders | Select-Object -Unique)
}Là où le script commence à fuir
Ces trente lignes bloqueront de vrais attaquants dès ce soir. L'écart entre elles et quelque chose qu'on peut laisser tourner un an est fait de problèmes sans gloire, et chacun se découvre en production :
- Vous allez vous bloquer vous-même. Il n'y a pas de liste blanche dans le code ci-dessus. La première fois que votre adresse de bureau passe un mauvais après-midi — le classique étant un identifiant enregistré périmé qui réessaie en boucle —, vous êtes dehors, devant un serveur que vous n'atteignez que par RDP.
- Les adresses seules ne suffisent pas. Les botnets tournent dans une plage. Bloquer 203.0.113.47 vous achète une heure avant que .48 démarre. Bloquer le /24 met fin à la série, mais calculer et fusionner correctement des plages CIDR est nettement plus difficile que l'extrait ci-dessus.
- La fenêtre d'interrogation perd des événements. Tourner toutes les dix minutes, c'est manquer une rafale qui tient dans une fenêtre, ou la compter deux fois à cheval sur deux. Sous charge, le journal de sécurité tourne plus vite que votre intervalle et les événements disparaissent avant lecture.
- Rien ne vous dit que ça s'est arrêté. Les tâches planifiées échouent en silence — après un redémarrage, après un changement de mot de passe du compte d'exécution, après une mise à jour de stratégie PowerShell. Vous découvrez des mois plus tard que la protection ne tourne plus depuis mars.
- Le port RDP n'est peut-être pas 3389. S'il a été déplacé, le script bloque toujours la source mais rien ne vérifie quels ports la règle devrait couvrir, et FTP et MS SQL ne sont pas couverts du tout.
- Les bannissements ne survivent pas à une reconstruction. L'état vit dans le pare-feu d'une machine. Restaurez depuis une image et tous les attaquants que vous aviez appris sont oubliés.
Ce que Windows fournit nativement
Deux fonctions natives sont recommandées dans ce contexte, et il vaut la peine d'être précis sur ce que fait chacune.
La stratégie de verrouillage de compte désactive un compte après N échecs. Face à un RDP exposé à internet, c'est plus une faiblesse qu'une défense : l'attaquant choisit le nom du compte, donc n'importe qui peut verrouiller votre compte Administrator à la demande, depuis n'importe où. C'est un contrôle raisonnable sur des comptes internes et mauvais en périmètre.
Network Level Authentication exige que le client s'authentifie avant la création d'une session. Elle réduit réellement le coût de chaque tentative et supprime une classe d'exploits pré-authentification, et elle devrait être active. Elle ne réduit pas le nombre de tentatives, car les bots s'authentifient quand même — mal, indéfiniment.
Aucune des deux ne relie le journal d'événements au pare-feu. C'est précisément ce lien que fournit fail2ban, et Windows ne le livre pas.
Les options côte à côte
Classées par ce que vous dépensez et ce que vous obtenez :
- Script PowerShell — gratuit, contrôle total, environ une journée d'écriture et une obligation d'entretien permanente. Convient pour un serveur que vous regardez souvent. Son mode de défaillance est le silence.
- VPN ou passerelle RDP en amont — la réponse la plus solide, et la plus coûteuse en exploitation. Si chaque utilisateur peut atteindre un VPN, utilisez-le et arrêtez ici. La plupart des parcs ont des prestataires et des téléphones pour lesquels cela n'arrive jamais tout à fait.
- Liste blanche d'IP sur le pare-feu — excellente quand l'ensemble des adresses légitimes est petit et stable, inutilisable dès que quelqu'un travaille depuis un hôtel.
- Un agent managé — un installeur, une liste blanche remplie avant que quoi que ce soit ne soit bloqué, des bannissements de sous-réseaux, des ports détectés automatiquement et une console indiquant s'il tourne encore. C'est la catégorie de RDP Protector.
Ce qu'un agent managé ajoute au script
Deux choses que le script ne peut pas avoir, aussi bien l'écriviez-vous.
La première est le socle opérationnel : votre adresse en liste blanche dès l'installation, une règle de pare-feu consolidée au lieu de milliers, des ports détectés depuis le registre et les sockets en écoute, des bannissements qui survivent aux redémarrages, et un tableau de bord qui dit si la chose est vivante — c'est ce mode de défaillance qui mord réellement.
La seconde n'est pas constructible seul du tout. Chaque serveur protégé alimente une base de réputation partagée, si bien qu'une adresse ayant attaqué quelqu'un d'autre hier est déjà bloquée quand elle vous atteint. Un script sur un serveur ne peut apprendre que des attaques visant ce serveur.
La décision reste prise localement sur l'agent, la protection ne dépend donc pas de la joignabilité du cloud : si la connexion tombe, la politique locale continue de tourner.
FAQ
- Puis-je vraiment faire tourner fail2ban sous Windows ?
- Pas utilement. Fail2ban dépend de Python plus iptables et de la lecture de logs texte de type syslog ; Windows n'a ni iptables ni syslog, et les échecs d'authentification vivent dans le journal d'événements de sécurité binaire. Le faire tourner sous WSL protège l'environnement WSL, pas le RDP de l'hôte Windows. Ce qu'il vous faut est un outil bâti sur Get-WinEvent et le pare-feu Windows.
- Un script PowerShell suffit-il pour un seul serveur ?
- Pour un serveur que vous administrez quotidiennement et surveillez, oui — les trente lignes ci-dessus bloqueront de vrais attaquants. Prévoyez une journée pour ajouter une liste blanche, la gestion des sous-réseaux et une vérification de vie, et acceptez que son mode de défaillance soit le silence : les tâches planifiées s'arrêtent après les redémarrages et les changements de mot de passe sans prévenir personne.
- Pourquoi une seule règle de pare-feu vaut-elle mieux qu'une règle par IP bloquée ?
- Le pare-feu Windows évalue les règles en séquence et supporte bien mieux quelques règles portant de grandes listes d'adresses que des milliers de petites. Les règles par adresse sont la façon habituelle dont ces scripts meurent : tout va bien deux semaines, puis l'évaluation des règles coûte des minutes et la console d'administration devient inutilisable.
- Bloquer au pare-feu remplace-t-il les mots de passe forts ?
- Non — cela supprime le volume, pas l'exigence. Les mots de passe forts et NLA arrêtent les tentatives qui passent ; le bannissement au pare-feu empêche le devinage d'atteindre Windows, ce qui protège votre CPU, votre journal d'audit et votre capacité à y trouver de vrais événements. Les deux, pas l'un ou l'autre.
