Fail2ban para Windows: las alternativas reales

En Windows no hay fail2ban. Así es la versión casera en PowerShell, dónde falla exactamente, y qué ofrecen de verdad las alternativas.

8 min de lectura

Por qué la pregunta vuelve una y otra vez

En Linux, fail2ban es la respuesta refleja a la adivinación de contraseñas: sigue un log, compara las líneas de fallo con una expresión regular e inserta una regla de firewall para cualquier dirección que cruce un umbral. Es pequeño, es estándar, y está en todas las guías de endurecimiento escritas en los últimos quince años.

Los administradores que pasan a Windows buscan la misma herramienta y no encuentran nada. Fail2ban es Python más iptables y no funciona en Windows en ningún sentido útil — no hay syslog que seguir ni iptables donde escribir. Windows tiene en su lugar el registro de eventos de seguridad y el Firewall de Windows: los mismos dos ingredientes, sin conectar.

Así que la pregunta no es realmente «cómo instalo fail2ban en Windows». Es «qué conecta el evento 4625 con una regla de firewall, y cuánto de eso tengo que construir yo».

La versión casera y su coste

La respuesta de hazlo-tú-mismo es una tarea programada de PowerShell. El esqueleto es realmente corto: esto lee los fallos de los últimos diez minutos, los agrupa por origen y bloquea todo lo que supere el umbral:

powershell
$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)
}

Dónde empieza a gotear el script

Esas treinta líneas bloquearán atacantes reales esta misma noche. La distancia entre eso y algo que puedas dejar funcionando un año está hecha de problemas poco glamurosos, y cada uno se descubre en producción:

  • Te bloquearás a ti mismo. En el código de arriba no hay lista blanca. La primera vez que la dirección de tu oficina tenga una mala tarde — el clásico es una credencial guardada obsoleta reintentando en bucle — estarás fuera de un servidor al que solo llegas por RDP.
  • Las direcciones sueltas no bastan. Las botnets rotan por un rango. Bloquear 203.0.113.47 te compra una hora antes de que arranque .48. Bloquear el /24 termina la serie, pero calcular y fusionar rangos CIDR correctamente es bastante más difícil que el fragmento de arriba.
  • La ventana de sondeo pierde eventos. Ejecutar cada diez minutos significa perderte una ráfaga que quepa en una ventana, o contarla dos veces a caballo entre dos. Bajo carga el registro de seguridad rota más rápido que tu intervalo y los eventos desaparecen antes de que los leas.
  • Nada te avisa de que se ha parado. Las tareas programadas fallan en silencio — tras un reinicio, tras cambiar la contraseña de la cuenta que las ejecuta, tras una actualización de directiva de PowerShell. Te enteras meses después de que la protección no se ejecuta desde marzo.
  • El puerto RDP puede no ser el 3389. Si alguien lo movió, el script sigue bloqueando el origen pero nada verifica qué puertos debería cubrir la regla, y FTP y MS SQL no están cubiertos en absoluto.
  • Los baneos no sobreviven a una reconstrucción. El estado vive en el firewall de una máquina. Restaura desde una imagen y todos los atacantes que habías aprendido quedan olvidados.

Lo que Windows trae de serie

Dos funciones nativas se recomiendan en este contexto, y conviene ser preciso sobre qué hace cada una.

La directiva de bloqueo de cuentas deshabilita una cuenta tras N intentos fallidos. Frente a un RDP expuesto a internet esto es más un riesgo que una defensa: el atacante elige el nombre de cuenta, así que cualquiera puede bloquear tu cuenta Administrator a voluntad desde cualquier sitio. Es un control razonable en cuentas internas y malo en el perímetro.

Network Level Authentication exige que el cliente se autentique antes de crear una sesión. Reduce de verdad el coste de cada intento y elimina una clase de exploits previos a la autenticación, y debería estar activo. No reduce el número de intentos, porque los bots se autentican igualmente — mal, eternamente.

Ninguna de las dos conecta el registro de eventos con el firewall. Esa conexión es justo lo que aporta fail2ban, y Windows no la trae.

Las opciones, una al lado de otra

Ordenadas por lo que gastas y lo que obtienes:

  • Script de PowerShell — gratis, control total, aproximadamente un día de escritura y una obligación de mantenimiento permanente. Sirve para un servidor que miras a menudo. Su modo de fallo es el silencio.
  • VPN o pasarela RDP por delante — la respuesta más sólida y la más cara en términos operativos. Si todos los usuarios pueden llegar a una VPN, úsala y deja de leer. En la mayoría de los parques hay contratistas y teléfonos para los que eso nunca acaba de cumplirse.
  • Lista blanca de IP en el firewall — excelente cuando el conjunto de direcciones legítimas es pequeño y estable, inservible en cuanto alguien trabaja desde un hotel.
  • Un agente gestionado — un instalador, una lista blanca que se rellena antes de bloquear nada, baneos de subred, puertos detectados automáticamente y una consola que muestra si sigue funcionando. Esta es la categoría de RDP Protector.

Qué añade un agente gestionado sobre el script

Dos cosas que el script no puede tener, por bien que lo escribas.

La primera es la base operativa: tu dirección en la lista blanca desde la instalación, una regla de firewall consolidada en lugar de miles, puertos detectados desde el registro y los sockets en escucha, baneos que sobreviven a los reinicios, y un panel que dice si la cosa sigue viva — que es el modo de fallo que de verdad muerde.

La segunda no se puede construir en solitario en absoluto. Cada servidor protegido alimenta una base de reputación compartida, de modo que una dirección que atacó a otro ayer ya está bloqueada cuando llega a ti. Un script en un servidor solo puede aprender de los ataques a ese servidor.

La decisión se sigue tomando localmente en el agente, así que la protección no depende de que la nube esté accesible: si se cae la conexión, la política local sigue funcionando.

FAQ

¿Puedo ejecutar fail2ban de verdad en Windows?
No de forma útil. Fail2ban depende de Python más iptables y de seguir logs de texto tipo syslog; Windows no tiene ni iptables ni syslog, y los fallos de autenticación viven en el registro binario de eventos de seguridad. Ejecutarlo bajo WSL protege el entorno WSL, no el RDP del host Windows. Lo que necesitas es una herramienta construida sobre Get-WinEvent y el Firewall de Windows.
¿Basta con un script de PowerShell para un solo servidor?
Para un servidor que administras a diario y revisas, sí — las treinta líneas de arriba bloquearán atacantes reales. Reserva un día para añadir lista blanca, manejo de subredes y una comprobación de vida, y asume que su modo de fallo es el silencio: las tareas programadas dejan de ejecutarse tras reinicios y cambios de contraseña sin avisar a nadie.
¿Por qué una sola regla de firewall es mejor que una regla por IP bloqueada?
El Firewall de Windows evalúa las reglas en secuencia y lleva mucho mejor unas pocas reglas con listas grandes de direcciones que miles de reglas pequeñas. Las reglas por dirección son la forma habitual en que mueren estos scripts: un par de semanas todo va bien, luego evaluar las reglas cuesta minutos y la consola de administración se vuelve inutilizable.
¿Bloquear en el firewall sustituye a las contraseñas fuertes?
No — elimina el volumen, no el requisito. Las contraseñas fuertes y NLA detienen los intentos que pasan; el baneo en el firewall impide que la adivinación llegue siquiera a Windows, lo que protege tu CPU, tu registro de auditoría y tu capacidad de encontrar en él eventos reales. Ambas cosas, no una u otra.

Sáltate el script

Lista blanca, baneos de subred, detección de puertos y reputación compartida, instalados en un minuto. Un servidor gratis para siempre, sin tarjeta.