Categoría: Homelab

  • Fail2Ban: instalación, monitoreo con diagnóstico y desbloqueo de IPs

    Fail2Ban es una herramienta que monitorea logs del sistema (como los intentos de login de SSH) y bloquea automáticamente, vía iptables o nftables, las IPs que superan un número de intentos fallidos configurado. Cada servicio protegido (SSH, Nginx, Postfix, etc.) tiene su propio jail — una configuración independiente con sus propias reglas de detección y tiempo de bloqueo.

    Instalación

    Fail2Ban está disponible en los repositorios oficiales de las principales distribuciones.

    Debian / Ubuntu:

    sudo apt update
    sudo apt install fail2ban
    sudo systemctl enable --now fail2ban

    Red Hat / CentOS / Rocky / AlmaLinux:

    sudo dnf install epel-release
    sudo dnf install fail2ban
    sudo systemctl enable --now fail2ban

    Por defecto, Fail2Ban trae solo el jail de SSH activo (o ninguno, según la distribución). La configuración recomendada es nunca editar /etc/fail2ban/jail.conf directamente, ya que se sobrescribe con las actualizaciones — en su lugar, se crea /etc/fail2ban/jail.local con las secciones que se quieran personalizar o activar:

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

    Jails más comunes

    Un jail se activa agregando o editando su sección en jail.local con enabled = true. Estos son los más usados en un servidor típico:

    • sshd — protege el servicio SSH contra ataques de fuerza bruta en intentos de login. Es el jail más usado y suele venir activo por defecto.
    • nginx-http-auth — bloquea IPs que fallan repetidamente la autenticación básica HTTP en Nginx.
    • nginx-limit-req — banea IPs que exceden los límites de tasa (limit_req) configurados en Nginx, útil contra scraping o abuso de API.
    • postfix — protege el servidor de correo contra intentos de relay no autorizado o fuerza bruta en autenticación SMTP.
    • apache-auth — equivalente a nginx-http-auth pero para servidores Apache.
    • recidive — un jail «de segundo nivel»: vigila el propio log de Fail2Ban y aplica bloqueos más largos a IPs que son baneadas repetidamente por otros jails (reincidentes).

    Ejemplo de activación del jail sshd con parámetros personalizados en jail.local:

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

    Donde maxretry es el número de intentos fallidos permitidos, findtime la ventana de tiempo (en segundos) en la que se cuentan esos intentos, y bantime cuánto dura el bloqueo. Tras cualquier cambio en jail.local, se debe reiniciar el servicio:

    sudo systemctl restart fail2ban

    Administración: ver lo baneado

    Para consultar el estado general y por jail:

    # Listar todos los jails activos
    sudo fail2ban-client status
    
    # Ver detalle de un jail específico (intentos totales, IPs baneadas)
    sudo fail2ban-client status sshd

    La salida de status sshd muestra, entre otros datos, Total failed (intentos fallidos acumulados) y Banned IP list (las IPs actualmente bloqueadas). Para ver el detalle de logs de baneos recientes directamente:

    sudo grep 'Ban' /var/log/fail2ban.log | tail -20

    Y para revisar las reglas realmente aplicadas a nivel de firewall (la capa que efectivamente bloquea el tráfico):

    sudo iptables -L -n -v -x f2b-sshd

    El resto de esta guía documenta un caso real de troubleshooting: un jail con un volumen alto de intentos fallidos, donde el desbloqueo estándar no reflejaba cambios correctamente.

    Diagnóstico del problema

    Se detectó un alto volumen de intentos fallidos (Total failed: 50634) con 15 IPs bloqueadas activamente. Se intentaron realizar desbloqueos manuales, pero se identificó que la IP objetivo no estaba en la lista de bloqueados actual (Banned IP list).

    Esto es más común de lo que parece: el jail puede tener la IP bloqueada a nivel de iptables/nftables sin que la base de datos interna de Fail2Ban (SQLite, normalmente en /var/lib/fail2ban/fail2ban.sqlite3) refleje el mismo estado — de ahí la necesidad de verificar ambas capas por separado.

    1. Consulta y monitoreo

    Para verificar el estado del jail e identificar las direcciones bajo sanción:

    # Ver IPs actualmente bloqueadas en el jail sshd
    sudo fail2ban-client status sshd
    
    # Listar todos los jails activos en la instancia de Fail2Ban
    fail2ban-client status
    
    # Verificar reglas activas dentro de la cadena específica de iptables
    sudo iptables -L -n -v -x f2b-sshd

    2. Ejecución de desbloqueo (unban)

    Comandos para liberar IPs individuales o masivamente:

    # Desbloquear una IP específica por su dirección
    sudo fail2ban-client set sshd unbanip <IP_ADDRESS>
    
    # Intentar el desbloqueo masivo de todas las IPs en el jail 'sshd'
    sudo fail2ban-client set sshd unbanip ALL
    
    # Limpiar la cadena de iptables (uso extremo si persiste el bloqueo)
    sudo iptables -F f2b-sshd

    3. Automatización y troubleshooting

    En caso de que los comandos estándar no reflejen cambios en iptables, se sugiere este bucle para procesar cada IP individualmente:

    # Bucle Bash para desbloqueo manual iterativo
    for ip in $(sudo fail2ban-client status sshd | awk '/Banned IP list:/ {print $4}'); do 
        sudo fail2ban-client set sshd unbanip $ip; 
    done
    
    # Reinicio del servicio para refrescar la base de datos interna y reglas
    sudo systemctl restart fail2ban

    Whitelist: prevenir el auto-bloqueo

    Para evitar volver a quedar bloqueado por accidente (por ejemplo, tu propia IP fija o la red interna), conviene agregar excepciones permanentes en jail.local:

    [DEFAULT]
    ignoreip = 127.0.0.1/8 ::1 192.168.100.0/24

    Cualquier IP dentro de ignoreip nunca será bloqueada por ningún jail, sin importar cuántos intentos fallidos genere.

    Notas técnicas adicionales

    • Retorno 0: en fail2ban-client, el retorno 0 indica que la operación se ejecutó exitosamente, aunque no necesariamente significa que haya habido cambios si la IP ya estaba libre.
    • Persistencia en iptables: si las IPs siguen bloqueadas tras usar unbanip ALL, es necesario verificar reglas manuales con sudo nft list ruleset o limpiar directamente la cadena de iptables.
    • Diferencia entre capas: un unbanip exitoso a nivel de Fail2Ban no siempre elimina la regla correspondiente en el firewall si hubo inconsistencias previas — por eso conviene verificar ambos lados (Fail2Ban y iptables/nftables) tras cualquier operación de desbloqueo masivo.
  • Crear una ISO desde una carpeta en Linux

    Instalación de herramientas

    Antes de crear la ISO, instala genisoimage según tu distribución:

    sudo apt install genisoimage        # Debian/Ubuntu
    sudo dnf install genisoimage        # Fedora/RHEL/CentOS

    ISO estándar con Rock Ridge + Joliet + Joliet Long

    genisoimage -o salida.iso -R -J -joliet-long /ruta/a/tu/carpeta
    • Rock Ridge — preserva permisos y atributos de Linux
    • Joliet — compatibilidad con Windows
    • Joliet Long — nombres largos hasta 103 caracteres

    ISO booteable BIOS (El Torito)

    Requiere un archivo de arranque, por ejemplo isolinux.bin.

    genisoimage -o boot.iso \
      -b isolinux.bin \
      -c boot.cat \
      -no-emul-boot \
      -boot-load-size 4 \
      -boot-info-table \
      -R -J -joliet-long \
      /ruta/a/tu/carpeta

    ISO booteable UEFI + BIOS (dual boot)

    Requiere un archivo EFI, por ejemplo efiboot.img.

    genisoimage -o boot-uefi.iso \
      -eltorito-alt-boot \
      -e efiboot.img \
      -no-emul-boot \
      -b isolinux.bin \
      -c boot.cat \
      -no-emul-boot \
      -boot-load-size 4 \
      -boot-info-table \
      -R -J -joliet-long \
      /ruta/a/tu/carpeta

    Alternativa moderna con xorriso

    xorriso -as mkisofs -o salida.iso -R -J -joliet-long /ruta/a/tu/carpeta

    Verificar el ISO montándolo

    sudo mount -o loop salida.iso /mnt