Fail2ban: Bloquea accesos no deseados a tu servidor

Un servidor expuesto a Internet es susceptible de ser atacado constantemente. No siempre podemos estar completamente protegidos, pero al menos sí podemos cubrirnos ante ataques de fuerza bruta si necesitamos exponer servicios delicados como SSH o servicios web

Fail2ban: Bloquea accesos no deseados a tu servidor

En mi casa tengo una raspberry pi que uso para gestionar mi LAN y que no está expuesta al exterior por ninguno de los puertos del router. No me preocupa mucho que un atacante se pueda conectar a ella desde el exterior, y mucho menos mediante ataques de fuerza bruta, ya que tengo cerrados los puertos del router de entrada y con la cantidad de wifis vulnerables que hay en mi zona, la mía de seguro no sería la primera en ser atacada.

Sin embargo, no pasa lo mismo en mi servidor, el cual sí está expuesto a Internet directamente y precisa de tener abiertos algunos puertos, como por ejemplo el SFTP, accesos web o el SSH, para poder gestionarlo de manera remota. Aunque una manera de securizar un poco más este último caso sería permitiendo el acceso sólo a través de una VPN, no siempre puedo conectarme haciendo uso de ella, por lo que desgraciadamente necesito el acceso SSH abierto al exterior.

IMPORTANTE: Si tienes el servicio SSH expuesto al exterior, es casi obligatorio que no esté en el puerto por defecto (22). Configura el servicio para que use cualquiera de los puertos no comunes, y más en este caso.

Es por ello que necesito vigilar estrechamente las conexiones a este puerto. Una opción la vimos en Notificaciones en Telegram: Eventos SSH, pero ese caso nos vale para saber cuándo alguien inicia una sesión en nuestro sistema. La idea en este momento es poner una vigilancia antes de que eso ocurra y bloquear el acceso a ese posible atacante, de manera que no pueda seguir intentándolo (y, de paso, aliviar un poco la carga de peticiones contra nuestro servidor).

Para lograr este objetivo, tenemos la increíble herramienta que es Fail2Ban. Dicha herramienta monitorizará los registros de los programas o servicios que especifiquemos y aplicará las reglas definidas por nosotros para bloquear o permitir el acceso a las fuentes que lo están solicitando.

Lo primero que tenemos que hacer es instalar la herramienta. En entornos Debian lo podemos hacer simplemente ejecutando el comando:

apt install fail2ban
Comando para instalar Fail2Ban
Recuerda que para instalar este tipo de herramientas necesitas permisos de administrador, por lo que deberás poder ser root o tener permisos sobre sudo para ello. Y recuerda siempre tener el sistema acualizado en la medida de lo posible antes de instalar nada.

Una vez instalado, necesitamos configurar los servicios que queremos proteger. Si accedemos a /etc/fail2ban veremos un archivo llamado jail.conf, el cual contiene la configuración de nuestras jaulas. Se llaman así porque serán las "jaulas" o "prisiones" en las que configuraremos las reglas para entrar y salir de ellas. Se pueden tener tantas como queramos, pero lo recomendable es no modificar este archivo, sino hacerlo sobre una copia del mismo.

Comenzamos copiando el fichero /etc/fail2ban/jail.conf a uno que llamaremos /etc/fail2ban/jail.local y que abriremos para configurar a nuestro gusto. Lo abrimos con nuestro editor favorito y buscamos la entrada [sshd], la cual completaremos con algo como:

[sshd]

# To use more aggressive ssh modes set filter parameter "mode":
# normal (default), ddos, extra or aggressive (combines all).
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
#mode     = normal
port      = ssh
enabled   = true
filter     = sshd
ignoreip  = 192.168.1.0/24
banaction = iptables-multiport
bantime   = 3600
maxretry  = 3
logpath   = %(sshd_log)s
backend   = %(sshd_backend)s
action    = sendnotif
Configuración de la jaula para SSH

La configuración se explica por sí misma, por lo que sólo resaltaré ciertos campos:

  • port: Indicamos que use el puerto definido por SSH (insisto, ¡no tengáis abierto el puerto 22 al exterior!)
  • ignoreip: Podemos definir una IP, lista de ellas o una subred para la cual fail2ban no entrará en acción si sobrepasamos el máximo número de reintentos (por ejemplo: dentro de nuestra red local o incluso aquí podemos meter nuestra sub-red de VPN si la tenemos)
  • bantime: El tiempo, en segundos, en los que la IP del atacante estará bloqueada o baneada en nuestra máquina.
  • maxretry: El máximo número de intentos antes de bloquear el acceso, típicamente suelen ser 3, pero podemos poner desde bloquear el acceso al primer intento o permitir incluso 10 o N si somos muy patosos introduciendo contraseñas 🤦🏽‍♂️
  • action: Si queremos que, además de bloquear el acceso, se desencadenen algunas acciones, aquí definiríamos dicha acción.

¡Y ya estaría! Guardamos los cambios del fichero y reiniciamos el servico para que comiencen a aplicar, mediante el comando:

systemctl restart fail2ban
Comando para reiniciar el servicio de Fail2Ban

Tras reiniciarlo, podremos consultar el estado y las jaulas creadas ejecutando la orden:

fail2ban-client status
Comando para mostrar el estado del servicio Fail2Ban y las jaulas creadas

Para ver con más detalle el estado de una jaula, como por ejemplo el de la sshd que hemos creado, basta con ejecutar:

fail2ban-client status sshd
Comando para mostrar el detalle del estado de la jaula sshd

Lo cual nos sacará información de la misma: cuántos fallos de acceso ha habido, actualmente y desde el inicio del servicio, el log donde se registra todo, cuántas IP están bloqueadas, la lista de las mismas...

Status for the jail: sshd
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     33
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 2
   |- Total banned:     4
   `- Banned IP list:   113.107.244.124 111.229.211.66
Ejemplo de estado de la jaula sshd

Y, si además vemos el contenido del fichero /var/log/auth.log podremos ver cómo aparecen los intentos de acceso, de bloqueo y de desbloqueo de las IP que están intentando acceder a nuestro sistema.

Para mejorar aún más la seguridad, el usuario root debería tener bloqueado el acceso por SSH, por ser un "usuario conocido" y, obviamente, por sus altos privilegios en el sistema.

Desencadenar acciones secundarias

Como comentaba anteriormente, dentro de la configuración del fichero jail.local había un atributo action que nos permitía definir acciones a desencadenar en función de los eventos que se produzcan desde fail2ban. Para ello, y siguiendo con el ejemplo, crearemos un fichero en /etc/fail2ban/action.d/myactions.conf que tendrá la siguiente forma:

[Definition]

# Option: actionstart
# Notes : command executed once at the start of Fail2Ban
# Tags  : 
# Values: CMD
actionstart =

# Option: actionstop
# Notes : command executed once at the end of Fail2Ban
# Tags  : 
# Values: CMD
actionstop = /home/yo/publicarNotif.sh "Fail2Ban se está deteniendo..."

# Option: actioncheck
# Notes : command executed once before each actionban command
# Tags  : 
# Values: CMD
actioncheck = 

# Option: actionban
# Notes : command executed when banning an IP. Take care that the
#         command is executed with Fail2Ban user rights.
# Tags  : <ip> IP address
#         <failures> number of failures
#         <time> unix timestamp of the ban time
# Values: CMD
actionban = /home/yo/publicarNotif.sh "<failures> intento(s) de acceso con la IP <ip>"

# Option: actionunban
# Notes : command executed when unbanning an IP. Take care that the
#         command is executed with Fail2Ban user rights.
# Tags  : <ip> IP address
#         <failures> number of failures
#         <time> unix timestamp of the ban time
# Tags  : 
# Values: CMD
actionunban = 

[Init]

name = sendnotif
Ejemplo de acción personalizada a ejecutar en cada acción de Fail2Ban

Como podemos ver en el fichero, para las acciones de "detener fail2ban" y "acción de bloqueo" llamo a un script que envía una notificación (por Telegram, por Gotify... ¡lo que sea!) informándome de cuándo se detiene el servicio (cosa que, salvo que haya ordenado yo, no debería de ocurrir) y también que me notifique cada vez que se bloquee una IP... aunque si tenéis el SSH abierto a Internet, os pueden abrumar las notificaciones de bloqueo. 😱

Y hasta aquí un pedacito más de cómo securizar nuestro servidor. ¡Espero que os haya resultado útil!