Guía de despliegue

Fail2Ban Enhanced en VPS: bloquear ataques repetidos

Desplegar en un VPS Cloud →

Tutorial

Fail2Ban Enhanced en VPS: bloquear ataques repetidos

Seguridad y monitorización11 min de lectura11 pasos

En cuanto un VPS expone SSH o una aplicación web, los intentos automatizados llegan enseguida. Fail2Ban Enhanced le da una red de seguridad sencilla: leer los logs, detectar los fallos repetidos y bloquear las IP que insisten. Esta guía va del ajuste inicial a la explotación diaria: jails y umbrales, elección del backend, comprobación de que el jail sigue vigilando, resolución de problemas con los mensajes de error reales, encaje con el firewall del VPS y copia de seguridad de la configuración. Las opciones citadas proceden de la documentación original de Fail2Ban.

Contenido· Por qué autoalojar Fail2ban en un VPS1/14
  1. 01Por qué autoalojar Fail2ban en un VPS
  2. 02Los beneficios concretos de esta plantilla
  3. 03Requisitos cifrados para alojarlo
  4. 04Instalar y configurar Fail2ban en su VPS
  5. 05ignoreip, duración del bloqueo y reincidencia
  6. 06Bloqueo progresivo: fórmula, tope y memoria
  7. 07Elegir el backend: auto, pyinotify, polling o systemd
  8. 08Los cuatro backends de Fail2ban
  9. 09Comprobar que el jail sigue vigilando
  10. 10Comprobar en cuatro pasos que el jail sigue leyendo
  11. 11Resolución de problemas: los mensajes de error reales
  12. 12Mensajes de error habituales y remedios
  13. 13nftables o iptables, firewall del VPS y copia de seguridad
  14. 14La documentación oficial

Por qué autoalojar Fail2ban en un VPS

Fail2ban es una de las herramientas de protección más sencillas y extendidas para un servidor expuesto: lee de forma continua sus logs, aplica expresiones regulares (los filtros) para detectar los intentos de intrusión y bloquea la IP culpable añadiéndola a nftables o iptables durante un tiempo configurable. En un VPS es una primera línea de defensa que conviene instalar antes que el resto, porque no depende de ningún servicio externo, consume poco y protege SSH contra la fuerza bruta desde que se activa el jail. Más allá de SSH, puede extenderlo a Nginx (intentos de autenticación, escaneos de URL), Postfix, WordPress o cualquier servicio que escriba logs. Todo funciona en local en su máquina: no sale ningún dato, no interviene ningún servicio de terceros. Es una solución autónoma y fácil de auditar, siempre que la revise de vez en cuando, como veremos más abajo.

Los beneficios concretos de esta plantilla

  • Bloqueo automático — las IP que fuerzan SSH se bloquean en cuanto se alcanza el umbral maxretry dentro de la ventana findtime.
  • Filtros para numerosos servicios — SSH, Nginx, Apache, Postfix, WordPress, y filtros personalizados escritos en filter.d.
  • Huella mínima — funciona sin problema en el más pequeño de los VPS.
  • Bloqueo progresivo (reincidencia) — cuanto más reincide una IP, más largo es el bloqueo.
  • Notificaciones por correo electrónico — posibles en cada bloqueo, con las acciones action_mw o action_mwl de jail.conf.
  • Autónomo y local — ninguna dependencia de red en el día a día, fácil de auditar y de versionar.

Requisitos cifrados para alojarlo

Fail2ban es frugal: un VPS de 1 vCPU y 512 MB de RAM basta para ejecutarlo, sin impacto perceptible (recomendación editorial, que debe medirse con su propia carga). En cuanto al software, el README original de la versión 1.1.1 pide Python 3.5 o superior. Dos componentes son opcionales: pyinotify 0.8.3 o superior para vigilar archivos (kernel Linux 2.6.13 o superior), y systemd 204 o superior con el paquete python-systemd para leer el journal. Fail2ban se instala directamente en el sistema (no hace falta Docker) y exige acceso root, un backend de firewall (nftables o iptables) y acceso a los logs de los servicios a proteger: el journal de systemd o /var/log/auth.log para SSH según la distribución, y los logs access y error de Nginx. Guarda su estado en una base SQLite, /var/lib/fail2ban/fail2ban.sqlite3 por defecto. No se necesita ningún dominio ni puerto adicional. La regla de oro: rellene ignoreip con su IP antes de activar el bloqueo, para no dejarse fuera de su propio servidor.

Instalar y configurar Fail2ban en su VPS

  1. Instalar Fail2ban

    En Debian o Ubuntu: sudo apt update && sudo apt install fail2ban. El servicio arranca automáticamente. Compruébelo con sudo systemctl status fail2ban.

  2. Crear un jail.local

    No modifique nunca jail.conf directamente. Escriba sus ajustes en /etc/fail2ban/jail.local, que los sobrescribe: ahí es donde se definen bantime, findtime, maxretry y sobre todo ignoreip = 127.0.0.1/8 ::1 SU_IP para protegerse de un autobloqueo. Los valores por defecto de jail.conf son bantime = 10m, findtime = 10m y maxretry = 5.

  3. Activar la protección SSH

    Todos los jails están desactivados por defecto en jail.conf: active explícitamente [sshd] en jail.local con enabled = true, por ejemplo maxretry = 3 y bantime = 1h. Tras 3 fallos dentro de la ventana findtime, la IP queda bloqueada una hora a nivel de firewall.

  4. Añadir un jail para Nginx

    Active los jails [nginx-http-auth] y [nginx-botsearch], que incluye jail.conf, y compruebe que logpath apunta a sus logs de Nginx. Esto bloquea los intentos de autenticación repetidos y los escaneos de URL maliciosos.

  5. Probar la configuración y recargarla

    Compruebe primero la sintaxis: sudo fail2ban-client -t. Después aplíquela: sudo fail2ban-client reload (o sudo systemctl restart fail2ban). sudo fail2ban-client status lista los jails activos y sudo fail2ban-client status sshd muestra las IP bloqueadas en ese momento.

  6. Probar un bloqueo y el desbloqueo

    Compruebe el filtro con su propio journal mediante sudo fail2ban-regex systemd-journal sshd. Para simular un bloqueo sin atacar a nadie: sudo fail2ban-client set sshd banip 203.0.113.10, y lea después sudo fail2ban-client status sshd. Para liberar una IP legítima bloqueada por error: sudo fail2ban-client set sshd unbanip X.X.X.X.

  7. Conectarse por primera vez

    No hay ninguna interfaz web ni cuenta que crear: fail2ban es un demonio del sistema que, con el ajuste de la plantilla, bloquea las IP tras 4 fallos SSH en 10 minutos. Por SSH: fail2ban-client status sshd (IP bloqueadas), fail2ban-client set sshd unbanip <IP> (desbloquear). Ajuste estos umbrales en jail.local.

ignoreip, duración del bloqueo y reincidencia

ignoreip acepta direcciones IP, máscaras CIDR o nombres de host DNS, separados por espacios o comas. Por defecto ignoreself = true: las direcciones locales del propio servidor nunca se bloquean, pero su IP de oficina o de casa no queda cubierta por eso. Si cambia a menudo, declare un nombre de host dinámico o use ignorecommand, un comando externo que recibe la IP y responde si debe ignorarse. Mantenga también un acceso de emergencia que no dependa de SSH, como la consola de su proveedor de VPS: un autobloqueo se resuelve entonces sin ayuda externa. La duración se fija con bantime, en segundos o con los sufijos m, h, d, w, mo e y. Actúa como duración inicial cuando el bloqueo progresivo está activado. Para los reincidentes, jail.conf incluye además un jail recidive, que lee el propio log de fail2ban.

Bloqueo progresivo: fórmula, tope y memoria

Active el bloqueo progresivo en jail.local con bantime.increment = true. La fórmula por defecto multiplica bantime por 1, 2, 4, 8, 16 y así sucesivamente en cada reincidencia; bantime.factor (1 por defecto) es un multiplicador común, y bantime.maxtime limita la duración en segundos, por ejemplo bantime.maxtime = 604800 para siete días. Hay un punto que suele pasarse por alto: fail2ban encuentra los bloqueos anteriores en su base de datos, que se purga según dbpurgeage (un día por defecto en fail2ban.conf). Para que se encuentren reincidencias muy espaciadas, auméntelo; el comentario del jail recidive en jail.conf cita 648000 segundos. Combine todo con la desactivación de la autenticación por contraseña (solo claves SSH): Fail2ban se convierte entonces en una red de seguridad y no en su única muralla.

Elegir el backend: auto, pyinotify, polling o systemd

El backend es la forma en que un jail lee sus logs. El valor por defecto de jail.conf es backend = auto, que cada jail puede sobrescribir. En Debian y Ubuntu, el archivo paths-debian.conf del paquete original 1.1.1 fija sshd_backend = systemd: sshd se lee entonces del journal de systemd, no de /var/log/auth.log. Lea sudo fail2ban-client status sshd para saber qué se vigila realmente: la línea File list indica archivos, la línea Journal matches indica el journal. Una distribución puede cambiar estos valores, así que no dé nada por supuesto: compruébelo. Cambiar de backend se hace jail por jail, en jail.local, seguido de sudo fail2ban-client reload.

Los cuatro backends de Fail2ban

Desplace la tabla

BackendQué vigilaA tener en cuenta
autoArchivos (pyinotify y luego polling); pasa a systemd si no existe ningún archivo de `logpath` y el filtro define `journalmatch`Valor por defecto de `jail.conf`
pyinotifyArchivos, mediante los eventos inotify del kernelSolo Linux, requiere el módulo Python pyinotify; según la documentación, más adecuado para archivos que polling
pollingArchivos, releyéndolos a intervalos regularesSin biblioteca externa, el recurso más sencillo
systemdEl journal de systemd, mediante python-systemd`logpath` no es válido; el filtro usa `journalmatch`; ajustes `journalflags` y `rotated`

Comprobar que el jail sigue vigilando

Un jail iniciado no es necesariamente un jail que lee. Caso comunicado, no confirmado por los mantenedores: en la incidencia 4250 de fail2ban, abierta en octubre 2026, un administrador con Debian y fail2ban 1.1.1 describe un jail sshd con backend systemd que deja de bloquear entre uno y dos días después del arranque, mientras sus jails de Nginx y Postfix siguen funcionando. Otros dos administradores, ambos con FreeBSD según sus mensajes, comunican un síntoma parecido con el backend pyinotify; uno dice que todo se estabilizó al pasar a polling. Un mantenedor señaló que la incidencia original trataba del backend systemd y que quizá los dos síntomas no estén relacionados. Un último participante, con Arch y el backend systemd, describe la misma parada tras una rotación del journal y plantea una hipótesis sobre el ajuste rotated: sigue sin confirmarse. La causa no está establecida a día de hoy, y nada permite generalizar a su servidor. La comprobación, en cambio, lleva un minuto.

Comprobar en cuatro pasos que el jail sigue leyendo

  1. Leer el estado del jail

    sudo fail2ban-client status sshd muestra Currently failed y Total failed para el filtro, File list o Journal matches para la fuente, y después Currently banned, Total banned y Banned IP list para la acción. Anote Total failed.

  2. Comparar con el log

    Cuente los fallos reales en el mismo periodo: sudo journalctl _COMM=sshd --since "1 hour ago" | grep -c "Failed password", o sudo grep -c "Failed password" /var/log/auth.log si el jail lee ese archivo. Vuelva a leer Total failed: debería haber aumentado. Compare la tendencia, no la igualdad exacta, porque las IP de ignoreip no cuentan.

  3. Leer el log de fail2ban

    sudo tail -n 50 /var/log/fail2ban.log: un jail sano escribe líneas Found seguidas de Ban. Varios días de líneas Unban solas, mientras el log de autenticación muestra intentos, delatan un jail ciego.

  4. Reiniciar y cambiar de backend si hace falta

    sudo systemctl restart fail2ban reanuda la lectura; la incidencia describe un funcionamiento normal durante uno o dos días tras cada arranque. Para un jail de archivos, backend = polling es el recurso más sencillo. Programe esta comprobación (cron o una herramienta de supervisión) en lugar de confiar en la ausencia de alertas.

Resolución de problemas: los mensajes de error reales

Estos mensajes proceden del código fuente de Fail2ban 1.1.1 (clientes y lectores de configuración); el nivel de registro por defecto es INFO. En cada caso el comando de partida es el mismo: sudo fail2ban-client -t prueba la configuración, sudo journalctl -u fail2ban da el principio de la historia.

Mensajes de error habituales y remedios

  • Have not found any log file for 'sshd' jail. — el logpath del jail no apunta a ningún archivo existente y el arranque falla, salvo con skip_if_nologs = true. Con el backend auto, un jail cuyo filtro define journalmatch pasa a systemd. Corrija la ruta o fije backend = systemd.
  • No file(s) found for glob /var/log/nginx/error.log — un patrón de logpath no coincide con nada. Compruebe la ubicación real de los logs de Nginx con ls /var/log/nginx.
  • Unable to read the filter 'nginx-xyz' — el nombre dado a filter = no existe en filter.d. Corrija la errata o añada su archivo de filtro.
  • Failed to access socket path: /var/run/fail2ban/fail2ban.sock. Is fail2ban running? — el cliente no encuentra el socket del servidor. El servicio está detenido o falla: sudo systemctl status fail2ban y después su log.
  • Permission denied to socket: ... (you must be root) — el comando fail2ban-client se lanzó sin los derechos suficientes. Vuelva a lanzarlo con sudo.
  • Unable to contact server. Is it running? — el socket existe pero el servidor no responde. Reinicie el servicio y lea su log de arranque.
  • [sshd] Journal reader seems to be offline, reopen journal — fail2ban detectó que su lectura del journal de systemd se había interrumpido (rotación) y lo reabre. Este mensaje es de nivel MSG, por debajo de INFO: su ausencia en un log normal no prueba nada, de ahí la comprobación de la sección anterior.
  • Error reading line from systemd journal — error de lectura del journal de systemd, seguido de la causa del sistema. Compruebe los permisos del servicio y el estado del journal con journalctl --verify.

nftables o iptables, firewall del VPS y copia de seguridad

La acción de bloqueo se elige con banaction. jail.conf propone iptables-multiport como ejemplo comentado; el archivo paths-debian.conf del paquete 1.1.1 fija banaction = nftables y banaction_allports = nftables[type=allports]. La acción nftables crea por defecto la tabla f2b-table (familia inet) y la cadena f2b-chain, enganchada a la entrada con prioridad -1; sudo nft list table inet f2b-table muestra las IP bloqueadas. Elija una sola familia de acciones, la misma que el resto de su firewall, o buscará sus reglas en la tabla equivocada. El firewall del VPS actúa antes: filtra lo que llega a la máquina, por ejemplo limitando SSH a sus direcciones, mientras que Fail2ban reacciona a lo que cuentan los logs. Se complementan, pero mantenga ignoreip coherente con sus reglas. Detrás de un proxy o de una CDN, los logs muestran la IP del proxy: restituya la IP real antes de bloquear, o bloqueará el proxy. Para la copia de seguridad, archive la configuración (sudo tar czf fail2ban-config.tar.gz /etc/fail2ban) y la salida de sudo fail2ban-client --dp, que documenta la configuración efectiva. La base /var/lib/fail2ban/fail2ban.sqlite3 conserva la memoria de los bloqueos.

La documentación oficial

Para la configuración avanzada, las opciones propias de la herramienta y los cambios de versión, consulte la documentación oficial de Fail2Ban. Esta guía cubre la puesta en línea en un VPS ServOrbit; la documentación del editor sigue siendo la referencia para los ajustes finos.

Blinde el acceso a su VPS

El VPS Cloud de ServOrbit le da el acceso root y un firewall listo para usar para configurar Fail2ban en unos minutos y detener en seco los ataques por fuerza bruta.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva