Linux en español
Herramientas

Fail2ban: Cómo proteger servicios en un servidor Linux

Fail2ban
22 minutos de lectura

¿Qué es fail2ban?

Fail2ban es una aplicación escrita en Python para la prevención de intrusos en un sistema, que actúa penalizando o bloqueando las conexiones remotas que intentan accesos por fuerza bruta. Se distribuye bajo licencia GNU y típicamente funciona en sistemas POSIX que tengan interfaz con un sistema de control de paquetes o un firewall local (como iptables).

¿Cómo funciona fail2ban?

La idea básica detrás de fail2ban es monitorear los registros de servicios comunes para detectar patrones en fallas de autenticación.

Cuando fail2ban está configurado para supervisar los registros de un servicio, mira un filtro que se ha configurado específicamente para ese servicio. El filtro está diseñado para identificar fallas de autenticación para ese servicio específico a través del uso de expresiones regulares complejas. Define estos patrones de expresiones regulares en una variable llamada failregex.

Afortunadamente, fail2ban incluye archivos de filtro para servicios comunes. Cuando una línea en el archivo de registro del servicio coincide con la failregexde su filtro, la acción definida se ejecuta para ese servicio. El actiones una variable que se puede configurar para hacer muchas cosas diferentes, dependiendo de las preferencias del administrador.

La acción predeterminada es prohibir el host / dirección IP ofensiva modificando las iptablesreglas del firewall. Puede expandir esta acción para enviar también un correo electrónico al administrador con el whoisinforme del atacante o las líneas de registro que desencadenaron la acción.

También puede modificar el objetivo de acción para que sea diferente de lo habitual iptables. Esto puede ser tan complejo o tan simple como lo hace y hay muchos archivos de configuración de firewall y opciones de notificación disponibles.

De forma predeterminada, se tomarán medidas cuando se detecten tres fallas de autenticación en 10 minutos y el tiempo de prohibición predeterminado sea de 10 minutos. El valor predeterminado para el número de fallas de autenticación necesarias para activar una prohibición se anula en la parte SSH del archivo de configuración predeterminado para permitir 6 fallas antes de que se produzca la prohibición. Esto es completamente configurable por el administrador.

Al usar el iptablesobjetivo predeterminado para el tráfico SSH, fail2bancrea una nueva cadena cuando se inicia el servicio. Agrega una nueva regla a la cadena INPUT que envía todo el tráfico TCP dirigido al puerto 22 a la nueva cadena. En la nueva cadena, inserta una regla única que regresa a la cadena ENTRADA.

Esto solo hace que el tráfico salte a la nueva cadena y luego salta de regreso. Esto no tiene ningún efecto en el tráfico al inicio. Sin embargo, cuando una IP alcanza el umbral de fallas de autenticación, se agrega una regla a la parte superior de la nueva cadena para eliminar el tráfico de la IP infractora. Esto se ocupa de la prohibición real. Cuando expira el período de prohibición, se elimina la regla de iptables. La cadena y las reglas asociadas se eliminan cuando sale el servicio fail2ban.

Explorando la configuración del servicio Fail2ban

Fail2ban se configura a través de una variedad de archivos ubicados dentro de una jerarquía debajo del directorio /etc/fail2ban/.

El archivo fail2ban.conf  contiene algunas configuraciones operacionales básicas, como la forma en que el daemon registra la información, y el socket y el archivo pid que usará. La configuración principal, sin embargo, tiene lugar en los archivos que definen las “cárceles”.

Por defecto, fail2ban se envía con un jail.confarchivo. Sin embargo, esto se puede sobrescribir en las actualizaciones, por lo que se recomienda a los usuarios copiar este archivo en un jail.localarchivo y realizar ajustes allí.

Si ya tiene un archivo jail.local ábralo ahora para seguirlo:

sudo nano /etc/fail2ban/jail.local

Si aún no tiene un archivo jail.local o el archivo que abrió estaba en blanco, copie el jail.conf y luego abra el nuevo archivo:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Examinaremos las opciones disponibles aquí y veremos cómo este archivo interactúa con otros archivos de configuración en el sistema.

La sección predeterminada

La primera parte del archivo definirá los valores predeterminados para la política fail2ban. Estas opciones pueden anularse en la sección de configuración de cada servicio individual.

Con los comentarios eliminados, la totalidad de la sección predeterminada se ve más o menos así:

[DEFAULT]

ignoreip = 127.0.0.1/8
bantime = 600
findtime = 600
maxretry = 3
backend = auto
usedns = warn
destemail = root@localhost
sendername = Fail2Ban
banaction = iptables-multiport
mta = sendmail
protocol = tcp
chain = INPUT
action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
%(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s", sendername="%(sendername)s"]
action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
%(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s", sendername="%(sendername)s"]
action = %(action_)s

Repasemos lo que realmente significa algo de esto:

  • ignoreip: este parámetro identifica la dirección IP que debe ser ignorada por el sistema de prohibición. De manera predeterminada, esto está configurado para ignorar el tráfico proveniente de la máquina, que es una configuración bastante buena de tener.
  • bantime: este parámetro establece la duración de una prohibición, en segundos. El valor predeterminado es 600 segundos o 10 minutos.
  • findtime: este parámetro establece la ventana a la que fail2ban prestará atención cuando busque intentos de autenticación fallidos repetidos. El valor predeterminado se establece en 600 segundos (10 minutos nuevamente), lo que significa que el software contará el número de intentos fallidos en los últimos 10 minutos.
  • maxretry: establece el número de intentos fallidos que se tolerarán dentro de la findtimeventana antes de que se establezca una prohibición.
  • backend: esta entrada especifica cómo fail2ban supervisará los archivos de registro. La configuración de los automedios que fail2ban probará pyinotify, entonces gamin, y luego un algoritmo de sondeo basado en lo que está disponible.
  • usedns: Esto define si DNS inverso se usa para ayudar a implementar prohibiciones. Si se establece en “no”, se prohibirán las direcciones IP en lugar de nombres de host. La configuración de “advertencia” intentará usar DNS inverso para buscar el nombre de host y prohibir de esa manera, pero registrará la actividad para su revisión.
  • destemail: esta es la dirección a la que se enviará el correo de notificación si se configura su acción para enviar alertas por correo.
  • sendername: se usará en el campo de correo electrónico para correos electrónicos de notificación generados.
  • banaction: establece la acción que se usará cuando se alcance el umbral. De hecho, el nombre de un archivo se encuentra en /etc/fail2ban/action.d/llamado iptables-multiport.conf. Esto maneja la iptablesmanipulación real para prohibir una dirección IP. Veremos esto más tarde.
  • mta: este es el agente de transferencia de correo que se usará para enviar correos electrónicos de notificación.
  • protocolo: este es el tipo de tráfico que se eliminará cuando se implemente una prohibición de IP. Este es también el tipo de tráfico que se envía a la nueva cadena de iptables.
  • cadena: esta es la cadena que se configurará con una regla de salto para enviar tráfico al embudo fail2ban.

El resto de los parámetros definen diferentes acciones que se pueden especificar. Pasan algunos de los parámetros que hemos definido anteriormente utilizando una interpolación de cadenas como esta:

%(var_name)s

La línea de arriba sería reemplazada por el contenido de var_name. Al usar esto, podemos decir que la actionvariable se establece en la action_definición por defecto (solo prohibición, sin alertas por correo).

Esto, a su vez, se configura llamando a la iptables-multiportacción con una lista de parámetros (nombre del servicio, puerto, protocolo y cadena) que se necesitan para realizar la prohibición. Se __name__sustituye por el nombre del servicio según lo especificado por los encabezados de las secciones a continuación.

Secciones específicas del servicio

Debajo de la sección predeterminada, hay secciones para servicios específicos que se pueden usar para anular la configuración predeterminada. Esto sigue una convención de solo modificar los parámetros que se alejan de los valores normales (convención sobre configuración).

Cada encabezado de sección se especifica así:

[service_name]

Cualquier sección que tenga esta línea será leída y habilitada:

enabled = true

Dentro de cada sección, los parámetros están configurados, incluido el archivo de filtro que se debe usar para analizar los registros (menos la extensión del archivo) y la ubicación del archivo de registro.

Teniendo esto en cuenta, la sección que especifica las acciones para el servicio SSH se ve así:

[SSH]

enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 6

Esto habilita esta sección y establece el puerto en el puerto “ssh” (puerto 22). Le dice a fail2ban que mire el registro ubicado en /var/log/auth.logesta sección y que analice el registro utilizando los mecanismos de filtrado definidos en el /etc/fail2ban/filters.ddirectorio en un archivo llamado sshd.conf.

Todas las demás piezas de información que necesita se toman de los parámetros definidos en la [DEFAULT]sección. Por ejemplo, la acción se establecerá para action_prohibir la dirección IP ofensiva utilizando la función iptables-multiportbanaction, que hace referencia a un archivo llamado iptables-multiport.conffound in /etc/fail2ban/action.d.

Como puede ver, las acciones en la [DEFAULT]sección deben ser generales y flexibles. Un uso intensivo de la sustitución de parámetros junto con parámetros que proporcionan valores predeterminados razonables hará que las definiciones sean fáciles de anular cuando sea necesario.

Examinando el archivo de filtro

Para comprender qué está pasando en nuestra configuración, debemos comprender los archivos de filtro y acción, que hacen la mayor parte del trabajo.

El archivo de filtro determinará las líneas que fail2ban buscará en los archivos de registro para identificar las características ofensivas. El archivo de acción implementa todas las acciones requeridas, desde la creación de una estructura de firewall cuando se inicia el servicio, hasta la adición y eliminación de reglas y el derribo de la estructura del firewall cuando se detiene el servicio.

Miremos el archivo de filtro que solicitó nuestro servicio SSH en la configuración anterior:

sudo nano /etc/fail2ban/filter.d/sshd.conf
[INCLUDES]

before = common.conf

[Definition]

_daemon = sshd
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
^%(__prefix_line)sFailed \S+ for .*? from <HOST>(?: port \d*)?(?: ssh\d*)?(: (ruser .*|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".*", client host ".*")?))?\s*$
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$
^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
ignoreregex =

Esto se ve muy complicado. Eso es porque es bastante complicado. Vamos a romper esto un poco.

El encabezado [INCLUDES] de sección especifica otros archivos de filtro que se leen antes o después de este archivo. En nuestro ejemplo, el archivo common.conf se lee y se coloca antes que las otras líneas en este archivo. Esto configura algunos parámetros que usaremos en nuestra configuración.

A continuación, tenemos una sección [Definition] que define las reglas reales para nuestras coincidencias de filtro. Primero, establecemos el nombre del daemon que estamos monitoreando usando el parámetro _daemon.

Después de eso, pasamos por la failregexdefinición real , que establece los patrones que se activarán cuando se encuentre una línea coincidente en el archivo de registro. Estas son expresiones regulares que coinciden en función de los diferentes errores y fallas que pueden producirse cuando un usuario no se autentica correctamente.

Algunas partes de la línea como %(__prefix_line)sse sustituirán por el valor de una configuración de parámetro en el archivo common.conf que obtuvimos. Esto se usa para que coincida con la información líder diferente que los sistemas operativos escriben en los archivos de registro cuando utilizan métodos estándar. Por ejemplo, algunas líneas del /var/log/auth.log podría ser algo como esto:

May 6 18:18:52 localhost sshd[3534]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=101.79.130.213 
May 6 18:18:54 localhost sshd[3534]: Failed password for invalid user phil from 101.79.130.213 port 38354 ssh2
May 6 18:18:54 localhost sshd[3534]: Received disconnect from 101.79.130.213: 11: Bye Bye [preauth]

La parte que está en rojo es un patrón estándar que el sistema operativo inserta para proporcionar más contexto. Después de eso, hay bastantes formas diferentes en que el servicio iptables escribe intentos de falla en el registro.

Vemos dos fallas separadas en las primeras dos líneas anteriores (un error de autenticación PAM y un error de contraseña). Las expresiones regulares definidas en el filtro están diseñadas para coincidir con cualquiera de las posibles líneas de falla. No debería tener que ajustar ninguna de estas líneas, pero debe tener en cuenta la necesidad de capturar todas las entradas de registro que indiquen un error de uso no autorizado para la aplicación que intenta proteger si alguna vez tiene que crear un archivo de filtro usted mismo .

En la parte inferior, puede ver un ignoreregexparámetro, que actualmente está en blanco. Esto se puede usar para excluir patrones más específicos que normalmente coincidirían con una condición de falla en caso de que desee anular el desencadenante de falla para fail2ban para ciertos escenarios. No ajustaremos esto.

Guarde y cierre el archivo cuando haya terminado de examinarlo.

Examinando el archivo de acción

Ahora, echemos un vistazo al archivo de acción. Este archivo es responsable de configurar el firewall con una estructura que permite modificaciones fáciles para prohibir hosts maliciosos y para agregar y eliminar esos hosts según sea necesario.

Como recordará, se llama a la acción que invoca nuestro servicio SSH iptables-multiport. Abra el archivo asociado ahora:

sudo nano /etc/fail2ban/action.d/iptables-multiport.conf

Con los comentarios eliminados, este archivo se ve así:

[INCLUDES]
before = iptables-blocktype.conf

[Definition]
actionstart = iptables -N fail2ban-<name>
iptables -A fail2ban-<name> -j RETURN
iptables -I <chain> -p <protocol> -m multiport --dports <port> -j fail2ban-<name>

actionstop = iptables -D <chain> -p <protocol> -m multiport --dports <port> -j fail2ban-<name>

actioncheck = iptables -n -L <chain> | grep -a 'fail2ban-<name>[ \t]'

actionban = iptables -I fail2ban-<name> 1 -s <ip> -j <blocktype>

actionunban = iptables -D fail2ban-<name> -s <ip> -j <blocktype>

[Init]
name = default
port = ssh
protocol = tcp
chain = INPUT

El archivo comienza por buscar otro archivo de acción llamado iptables-blocktype.confque simplemente define el blocktypeparámetro que configura la restricción que se establecerá cuando un cliente está prohibido. Por defecto, blocktypeestá configurado para rechazar paquetes y responder a los pings enviados por clientes prohibidos con un mensaje de rechazo de que el puerto es inalcanzable. Usaremos esto en nuestras reglas de prohibición a continuación.

Luego, llegamos a las definiciones de reglas en sí mismas. Las acciones son bastante directas. La actionstartacción configura el firewall de iptables cuando se inicia el servicio fail2ban. Crea una nueva cadena, agrega una regla a esa cadena para regresar a la cadena de llamadas, y luego inserta una regla al principio de la cadena de ENTRADA que pasa el tráfico que coincide con el protocolo correcto y los destinos del puerto a la nueva cadena.

Hace esto usando los valores que pasamos con el actionque definimos en nuestro jail.localarchivo. El namese toma de la cabecera de sección para cada servicio, el chain, protocoly portse han tomado de la actionpropia línea en ese archivo.

Puede recordar que esos, a su vez, se agregaron a la línea de acción al interpolar otros parámetros establecidos en otras ubicaciones en ese archivo. Puede que se esté dando cuenta en este punto de que fail2ban pasa y convierte muchos parámetros entre las diversas partes de sus archivos de configuración.

Aquí, se hace referencia a todos los parámetros establecidos por el otro archivo incluyendo el nombre del parámetro entre corchetes angulares:

<param_name>

Cuando pasamos a la actionstopdefinición complementaria , podemos ver que los comandos del firewall simplemente están implementando una inversión de los actionstartcomandos. Derribamos la estructura de firewall que creamos cuando detuvimos el servicio fail2ban.

Otra acción llamada actioncheckasegura que se haya creado la cadena adecuada antes de intentar agregar reglas de prohibición.

A continuación, llegamos a la regla de prohibición real, llamada actionban. Esta regla funciona al agregar una nueva regla a nuestra cadena creada. La regla coincide con la dirección IP de origen del cliente infractor (este parámetro se lee desde los registros de autorización cuando maxretryse alcanza el límite) e instituye el bloque definido por el blocktypeparámetro que obtuvimos en la [INCLUDE]sección en la parte superior del archivo.

La actionunbanregla simplemente elimina esta regla. Esto se hace automáticamente por fail2ban cuando ha transcurrido el tiempo de prohibición.

Finalmente, llegamos a la [Init]sección. Esto solo proporciona algunos valores predeterminados en caso de que se llame al archivo de acción sin pasar todos los valores apropiados.

Cómo el servicio Fail2ban procesa archivos de configuración para implementar prohibiciones

Ahora que hemos visto los detalles, repasemos el proceso que ocurre cuando se inicia fail2ban.

Cargando los archivos de configuración inicial

Primero, el archivo principal fail2ban.conf se lee para determinar las condiciones bajo las cuales debe operar el proceso principal. Crea los archivos socket, pid y log si es necesario y comienza a usarlos.

A continuación, fail2ban lee el jail.confarchivo para detalles de configuración. Sigue esto leyendo, en orden alfabético, cualquier archivo encontrado en el jail.ddirectorio que finaliza en .conf. Agrega la configuración encontrada en estos archivos a su configuración interna, dando a los nuevos valores preferencia sobre los valores descritos en el jail.confarchivo.

Luego busca un jail.localarchivo y repite este proceso, adaptando los nuevos valores. Finalmente, busca jail.dnuevamente en el directorio, leyendo en orden alfabético los archivos que terminan en .local.

De esta forma, podemos ver que fail2ban tiene una gran cantidad de archivos que pueden usarse para manipular el comportamiento final del proceso. En nuestro caso, solo tenemos un jail.confarchivo y un jail.localarchivo. En nuestro jail.localarchivo, solo necesitamos definir los valores que difieren del jail.confarchivo.

El proceso fail2ban ahora tiene un conjunto de directivas cargadas en la memoria que representan una combinación de todos los archivos que encontró.

Examina cada sección y busca una enabled = truedirectiva. Si encuentra uno, usa los parámetros definidos en esa sección para crear una política y decidir qué acciones se requieren. Cualquier parámetro que no se encuentre en la sección del servicio usa los parámetros definidos en la [DEFAULT]sección.

Analizar los archivos de acción para determinar las acciones de inicio

Fail2ban busca una actiondirectiva para descubrir qué secuencia de comandos de acción se debe invocar para implementar las políticas de prohibición / desprotección. Si no se encuentra uno, se recurre a la acción predeterminada determinada anteriormente.

La directiva de acción consiste en el nombre del archivo (s) de acción que se leerá, así como un diccionario de clave-valor que pasa los parámetros necesarios para esos archivos. Los valores de estos a menudo toman la forma de sustituciones de parámetros al hacer referencia a las configuraciones configuradas en la sección del servicio. La clave “nombre” generalmente se pasa el valor de la __name__variable especial que se establecerá en el valor del encabezado de la sección.

Fail2ban luego utiliza esta información para encontrar los archivos asociados en el action.ddirectorio. Primero busca el archivo de acción asociado que termina en .confy luego enmienda la información que se encuentra allí con cualquier configuración contenida en un .localarchivo adjunto que también se encuentra en el action.ddirectorio.

Analiza esos archivos para determinar las acciones que debe realizar ahora. Lee el actionstartvalor para ver las acciones que debería llevar a configurar el entorno. Esto a menudo incluye la creación de una estructura de firewall para acomodar las reglas de prohibición en el futuro.

Las acciones definidas en este archivo usan los parámetros que se le pasaron de la actiondirectiva. Utilizará estos valores para crear dinámicamente las reglas apropiadas. Si no se configuró una determinada variable, puede ver los valores predeterminados establecidos en el archivo de acción para completar los espacios en blanco.

Análisis de los archivos de filtro para determinar las reglas de filtrado

Los parámetros para el servicio en los jail.*archivos también incluyen la ubicación del archivo de registro, así como el mecanismo de sondeo que se debe usar para verificar el archivo (esto está definido por el backendparámetro). También incluye un filtro que se debe usar para determinar si una línea en el registro representa una falla.

Fail2ban busca en el filter.ddirectorio para encontrar el archivo de filtro coincidente que termina con .conf. Lee este archivo para definir los patrones que se pueden usar para hacer coincidir las líneas ofensivas. A continuación, busca un archivo de filtro coincidente que finaliza con .localpara ver si se sobrescribió alguno de los parámetros predeterminados.

Utiliza las expresiones regulares definidas en estos archivos a medida que lee el archivo de registro del servicio. Prueba cada failregexlínea definida en los filter.darchivos con cada nueva línea escrita en el archivo de registro del servicio.

Si la expresión regular devuelve una coincidencia, verifica la línea con las expresiones regulares definidas por ignoreregex. Si esto también coincide, fail2ban lo ignora. Si la línea coincide con una expresión en el, failregexpero no coincide con una expresión en el ignoreregex, se incrementa un contador interno para el cliente que causó la línea y se crea una marca de tiempo asociada para el evento.

A medida que se alcanza la ventana de tiempo establecida por el findtimeparámetro en los jail.*archivos (según lo determina la marca de tiempo del evento), el contador interno se vuelve a decrementar y el evento ya no se considera relevante para la política de prohibición.

Si, con el transcurso del tiempo, se registran fallas de autenticación adicionales, cada intento incrementa el contador. Si el contador alcanza el valor establecido por el maxretryparámetro dentro de la ventana de tiempo configurada, fail2ban instituye una prohibición llamando a la actioncheckacción para el servicio como se define en los action.d/archivos para el servicio. Esto es para determinar si la actionstartacción configuró la estructura necesaria. Luego llama a la actionbanacción para prohibir el cliente infractor. Establece una marca de tiempo para este evento también.

Cuando ha transcurrido el tiempo especificado por el bantimeparámetro, fail2ban deshace al cliente invocando la actionunbanacción.

Cuando se detiene el servicio fail2ban, intenta eliminar cualquiera de las reglas de firewall que creó llamando a la actionstopacción. Esto generalmente elimina la cadena que contiene las reglas fail2ban y elimina las reglas de la cadena INPUT que causó que el tráfico saltara a esa cadena.

Conclusión

Con suerte, a estas alturas ya tiene una comprensión bastante profunda de cómo funciona fail2ban. El servicio en sí es increíblemente fácil para la mayoría de los usuarios porque la configuración más difícil se ha cuidado por usted.

Sin embargo, cuando se desvía de la configuración estándar, es útil saber cómo funciona fail2ban para manipular su comportamiento de una manera predecible.

Entradas relaccionadas

Listado de navegadores web para linux

Diego García Cuesta

Las mejores aplicaciones para escuchar la radio en Linux

Diego García Cuesta

Wine 4.0: Ya disponible con soporte para Vulkan y Direct3D 12

Linux en Español

Netrunner: Lanzada la versión 2019.01 con mas webapps

Linux en Español

9 herramientas de escritorio remoto para Linux

Diego García Cuesta

Ephemeral: el navegador web siempre incógnito para Linux

Linux en Español