Dónde fail2ban deja de bastar
fail2ban es una buena herramienta y la primera respuesta correcta. Aquí está exactamente dónde se queda corto, cómo exprimirlo más, y qué no puede hacer con ninguna configuración.
Primero, reconocerle el mérito
fail2ban está en los repositorios de todas las distribuciones, se instala con un comando y bloquea atacantes reales esa misma tarde. Si tienes un servidor expuesto sin nada vigilándolo, instalar fail2ban es una posición estrictamente mejor que la tuya, y nada de lo que sigue discute eso.
Esta guía trata del hueco entre «bloquea atacantes reales esta noche» y «sigue siendo correcto dentro de un año en todo un parque», porque en ese hueco viven las sorpresas y casi nunca está escrito.
Ninguno de los límites de abajo es un fallo. Son consecuencias de lo que fail2ban es: un demonio de análisis de registros diseñado en una época de servidores únicos y atacantes únicos.
Límite 1: banea direcciones, no rangos
Este es el grande. El tráfico de ataque viene de proveedores de hosting donde un operador tiene un bloque entero. Banea 203.0.113.47 y la botnet se mueve a .48 en una hora, y absorbes otra tanda completa de intentos antes de que esa también quede baneada. En un /24 son 256 tandas del umbral que configuraste.
Puedes aproximar una solución con una acción propia que amplíe cada baneo a su /24, pero entonces mantienes aritmética CIDR en shell, y equivocarte significa banear algo que necesitabas. La herramienta no tiene concepto de rango como objeto de primera clase.
El efecto medible: en un servidor bajo ataque sostenido, una defensa que banea rangos ve desplomarse el número de intentos, mientras que una que banea direcciones se estanca en el ritmo de rotación.
Límite 2: los baneos caducan y el estado no sobrevive
El bantime por defecto se mide en minutos. Es razonable en un hosting compartido donde un usuario real puede caer, y es erróneo en un servidor expuesto a internet: la misma botnet vuelve esta noche y empieza de cero.
Puedes poner bantime en -1 para baneos permanentes, y deberías — pero entonces aparece el segundo problema. La lista de baneos vive en la base de datos de fail2ban y en el firewall en marcha; reconstruye la máquina, restaura una imagen o migra a otro host y todo lo que el servidor aprendió desaparece.
Hay también una versión de tercer orden: un servidor que lleva dos años funcionando acumula un conjunto de firewall con decenas de miles de entradas, y nadie ha revisado nunca si las más antiguas siguen mereciendo la comparación.
Límite 3: cada servidor aprende solo
Este es estructural y ninguna configuración lo arregla. Cada uno de tus servidores descubre a cada atacante por su cuenta, y el coste de ese descubrimiento es el umbral que fijaste — cinco intentos, diez, el que sea.
Diez servidores, diez veces el mismo atacante, diez veces el umbral absorbido. Y cada uno de esos intentos es un fork real de sshd, una línea real de registro y una posibilidad real de que sea la tanda en la que una contraseña reutilizada acabe entrando.
fail2ban no tiene mecanismo para que el conocimiento de un servidor llegue a otro. Existen listas comunitarias a las que suscribirse, que ayudan, pero son genéricas y llegan con horas o días de retraso; nada te dice que la dirección que está golpeando el servidor tres ahora mismo es la que golpeaba el servidor uno esta mañana.
Límite 4: falla en silencio
Este es el límite que de verdad le cuesta servidores a la gente, y el que menos atención recibe.
fail2ban depende de hacer coincidir líneas de registro con expresiones regulares. Una actualización de distribución cambia el formato de un mensaje de sshd; el filtro deja de coincidir; la jail sigue «funcionando» y reporta cero baneos, lo que parece exactamente una semana tranquila. Ha habido actualizaciones de paquete que reiniciaron jail.local. Un cambio de backend de systemd deja el journal sin leer. El servicio no vuelve tras un reinicio.
En cada uno de esos casos, la monitorización que probablemente tengas — ¿está el servicio en marcha? — responde que sí. La pregunta que lo pillaría es «¿ha baneado a alguien últimamente, y esa cifra se parece al volumen de ataque que veo en el registro?», y casi nadie la hace.
Exprimir más a fail2ban
Si quieres quedarte con él — una elección legítima para un parque pequeño — estos son los cambios que más importan, más o menos por orden:
- Poner bantime = -1 y subir findtime, para que un atacante lento también caiga. Encima, la jail recidive, para escalar a los reincidentes.
- Añadir una acción propia que amplíe un baneo a su /24, probando antes con cuidado la aritmética contra tus propios rangos.
- Hacer que los baneos sobrevivan a los reinicios con un conjunto nftables marcado como persistente, o restaurarlos desde la base de datos al arrancar.
- Monitorizar el número de baneos, no el estado del servicio. Alertar cuando sea cero mientras el registro de autenticación no lo es.
- Poner tus direcciones de administración en ignoreip antes que nada, y verificar desde una segunda conexión que lo hiciste bien.
Qué añade un agente gestionado
Dos cosas, y la segunda no se puede construir en solitario con ninguna configuración.
La primera es la base operativa: baneos de subred como concepto de primera clase, baneos permanentes y restaurados al arrancar, el puerto SSH real leído de la configuración de sshd en lugar de asumido, tu dirección en la lista blanca desde la instalación, y una consola que responde «¿esto sigue funcionando?» — el modo de fallo que de verdad muerde.
La segunda es la reputación compartida. Cada servidor protegido alimenta una base común, de modo que una dirección que atacó a otro ayer ya está bloqueada cuando llega a ti, y nunca absorbes sus primeros N intentos. Un analizador de registros en un host solo puede aprender de los ataques a ese host.
SSH Protector decide localmente en el agente, así que la protección no depende de que la nube sea accesible: si se cae la conexión, la política local sigue. Un servidor es gratis para siempre, lo bastante para tenerlo una semana junto a fail2ban y comparar qué cazó cada uno.
FAQ
- ¿Sigue mereciendo la pena fail2ban?
- Sí, como base. Es gratuito, está en todos los repositorios, y en un servidor que nada más vigila bloqueará atacantes reales el mismo día que lo instales. Las salvedades honestas son baneos de direcciones sueltas frente a botnets que rotan rangos, baneos que caducan por defecto, ningún conocimiento compartido entre hosts, y un modo de fallo silencioso.
- ¿Cómo hago permanentes los baneos de fail2ban?
- Pon bantime = -1 en la jail correspondiente. Ten en cuenta que la lista vive entonces solo en la base de datos de fail2ban y en el firewall en marcha, así que una reconstrucción o restauración de imagen pierde todo lo aprendido, y el conjunto crece sin que nadie lo revise. Haz que el conjunto del firewall sobreviva también a los reinicios, o los baneos se pierden en cada reinicio.
- ¿Puede fail2ban banear una subred entera?
- De forma nativa, no. Banea la dirección que apareció en la línea de registro. Puedes escribir una acción propia que amplíe cada baneo al /24 que lo contiene, pero entonces mantienes tú la aritmética CIDR, y un error ahí bloquea un rango que necesitabas. La herramienta no tiene la noción de rango como tal.
- ¿Cómo compruebo que fail2ban funciona de verdad?
- Ejecuta fail2ban-client status sshd y mira el número de baneados, no solo si el servicio está activo. Una jail activa que no ha baneado a nadie mientras el registro de autenticación muestra fallos significa que el filtro dejó de coincidir — normalmente tras una actualización de distribución que cambió un formato de mensaje de sshd. Monitoriza el número de baneos, no el proceso.
