Cómo configurar fail2ban para proteger SSH

Fail2ban es una herramienta que protege tu servidor contra ataques de fuerza bruta monitoreando los logs del sistema y bloqueando automáticamente las direcciones IP que muestran comportamiento malicioso. Esta guía explica cómo instalar y configurar fail2ban para proteger el servicio SSH.

Cómo funciona

Fail2ban analiza los archivos de log en busca de patrones de intentos fallidos de autenticación. Cuando una IP supera el número de intentos permitidos en un período de tiempo, fail2ban añade una regla al firewall para bloquear esa IP temporalmente.

Requisitos previos

  • Acceso root o sudo al servidor
  • Servidor con Ubuntu/Debian o AlmaLinux/CentOS/RHEL

Paso 1: Instalar fail2ban

Ubuntu / Debian

sudo apt update
sudo apt install fail2ban -y

AlmaLinux / CentOS / RHEL

sudo dnf install epel-release -y
sudo dnf install fail2ban -y

Paso 2: Configurar fail2ban

Fail2ban utiliza archivos de configuración en /etc/fail2ban/. Nunca edites los archivos originales (jail.conf, fail2ban.conf) ya que se sobrescriben en las actualizaciones. En su lugar, crea archivos .local que tienen prioridad.

Crear el archivo de configuración local

sudo nano /etc/fail2ban/jail.local

Añade la siguiente configuración:

[DEFAULT]
# Tiempo de bloqueo en segundos (1 hora)
bantime = 3600

# Ventana de tiempo para contar intentos fallidos (10 minutos)
findtime = 600

# Número de intentos fallidos antes de bloquear
maxretry = 5

# Ignorar IPs locales y de confianza (separadas por espacio)
ignoreip = 127.0.0.1/8 ::1

# Acción por defecto: bloquear con iptables
banaction = iptables-multiport

# Email para notificaciones (opcional)
# destemail = admin@tudominio.com
# sender = fail2ban@tudominio.com
# action = %(action_mwl)s

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600

Nota: Si usas AlmaLinux/CentOS/RHEL, cambia la ruta del log:

logpath = /var/log/secure

Configuración con puerto SSH personalizado

Si cambiaste el puerto SSH predeterminado (por ejemplo, a 2222), modifica la línea port:

[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600

Configuración con bloqueo progresivo

Para bloqueos que aumentan con cada reincidencia, añade:

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600

[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
bantime = 604800
findtime = 86400
maxretry = 3

Esta configuración bloquea por una semana (604800 segundos) a las IPs que han sido bloqueadas 3 veces en las últimas 24 horas.

Paso 3: Iniciar y habilitar fail2ban

sudo systemctl start fail2ban
sudo systemctl enable fail2ban

Verifica que el servicio esté corriendo:

sudo systemctl status fail2ban

Paso 4: Verificar la configuración

Ver el estado de las jaulas activas

sudo fail2ban-client status

Salida esperada:

Status
|- Number of jail:      1
`- Jail list:   sshd

Ver detalles de la jaula SSH

sudo fail2ban-client status sshd

Salida esperada:

Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     5
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 1
   |- Total banned:     2
   `- Banned IP list:   192.168.1.100

Ver las reglas del firewall

sudo iptables -L -n | grep -A 10 fail2ban

Administración de fail2ban

Desbloquear una IP manualmente

sudo fail2ban-client set sshd unbanip 192.168.1.100

Bloquear una IP manualmente

sudo fail2ban-client set sshd banip 192.168.1.100

Recargar la configuración

Después de modificar los archivos de configuración:

sudo fail2ban-client reload

Ver el log de fail2ban

sudo tail -f /var/log/fail2ban.log

Configuraciones adicionales recomendadas

Proteger otros servicios

Puedes añadir jaulas para otros servicios en /etc/fail2ban/jail.local:

# Proteger Apache
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/*error.log
maxretry = 3
bantime = 3600

# Proteger Nginx
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/*error.log
maxretry = 3
bantime = 3600

# Proteger Postfix
[postfix]
enabled = true
port = smtp,465,submission
filter = postfix
logpath = /var/log/mail.log
maxretry = 3
bantime = 3600

# Proteger Dovecot
[dovecot]
enabled = true
port = pop3,pop3s,imap,imaps
filter = dovecot
logpath = /var/log/mail.log
maxretry = 3
bantime = 3600

Usar nftables en lugar de iptables

En sistemas modernos que usan nftables:

[DEFAULT]
banaction = nftables-multiport

Configurar notificaciones por email

Para recibir notificaciones cuando se bloquee una IP:

[DEFAULT]
destemail = admin@tudominio.com
sender = fail2ban@tudominio.com
mta = sendmail
action = %(action_mwl)s

Solución de problemas

Fail2ban no bloquea IPs

  • Verifica que la ruta del log sea correcta:
# Ubuntu/Debian
ls -la /var/log/auth.log

# AlmaLinux/CentOS
ls -la /var/log/secure
  • Confirma que el filtro detecta los intentos fallidos:
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
  • Revisa el log de fail2ban:
sudo tail -50 /var/log/fail2ban.log

El servicio no inicia

  • Verifica errores de sintaxis en la configuración:
sudo fail2ban-client -t
  • Revisa los logs del sistema:
sudo journalctl -u fail2ban -n 50

Me bloqueé a mí mismo

Si tienes acceso físico o por consola al servidor:

sudo fail2ban-client set sshd unbanip TU_IP

Si no tienes acceso, espera el tiempo de bantime configurado o accede por otro método (consola KVM, IPMI, panel del proveedor).

Para evitar esto, añade tu IP a la lista de ignorados:

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 TU_IP_FIJA

Las IPs se desbloquean después de reiniciar

Por defecto, fail2ban no persiste los bloqueos entre reinicios. Para habilitar persistencia, añade:

[DEFAULT]
banaction = iptables-multiport
banaction_allports = iptables-allports

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
# Guardar bloqueos en base de datos
backend = systemd

O crea un script que restaure los bloqueos desde /var/lib/fail2ban/fail2ban.sqlite3.

Buenas prácticas

  1. No bloquees por demasiado tiempo: Un bantime de 1-24 horas es suficiente para la mayoría de ataques.
  2. Añade tus IPs a ignoreip: Evita bloquearte accidentalmente.
  3. Monitorea los logs: Revisa periódicamente /var/log/fail2ban.log.
  4. Combina con llaves SSH: Fail2ban complementa, no reemplaza, la autenticación con llaves públicas.
  5. Mantén fail2ban actualizado: Las actualizaciones incluyen nuevos filtros y correcciones de seguridad.

Referencias