Cualquier servidor, tarde o temprano, está sujeto a inundaciones (flooding), lo que conlleva un aumento de la carga en los servicios y un mayor uso de los recursos. Numerosos bots en internet escanean sitios web en busca de vulnerabilidades y para la recolección de datos.
Estos bots tienen un comportamiento malicioso y, para no malgastar los recursos del servidor en ellos, deben ser bloqueados.
En este artículo, analizamos específicamente una de las formas de combatir el flooding. Para combatir los ataques DDoS se utilizan otros servicios y métodos.
Ejemplo de este tipo de solicitudes:
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /aa.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /file.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /file.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /wp-file.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /wp-file.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /k.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /k.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /al.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /al.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /wp- HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /wp- HTTP/1.1" 404 48273 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /admin.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /admin.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /file2.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /file2.php HTTP/1.1" 404 27 "-" "-"
Como se desprende del registro, el bot realiza aproximadamente 9 solicitudes por segundo al servidor, lo cual es bastante, especialmente si se considera que podría haber varios bots con diferentes direcciones IP. Esto puede generar una carga significativa en un servidor virtual.
Nuestra tarea es bloquear las direcciones IP que realizan demasiadas solicitudes regulares, excluyendo los archivos estáticos; solo contaremos las solicitudes dinámicas, ya que estas son las que generan la carga.
1. Instalación de Fail2ban
apt install fail2ban
2. Configuración
nano /etc/fail2ban/jail.local
[DEFAULT]
# Configuraciones principales
ignoreip = 127.0.0.1/8 ::1
bantime = 3600
findtime = 600
maxretry = 200
# Configuraciones de correo electrónico
destemail = corp@domain.tld
sender = fail2ban@domain.tld
sendername = Fail2Ban
mta = sendmail
# Acción predeterminada (con envío de correo electrónico)
action = %(action_mwl)s
[nginx-flood]
enabled = true
port = http,https
filter = nginx-flood
logpath = /var/log/nginx/*access*.log
maxretry = 200
findtime = 60
bantime = 3600
# la acción se hereda de DEFAULT, por lo que no es necesario duplicarla
2.1 El Filtro en sí
nano /etc/fail2ban/filter.d/nginx-flood.conf
[Definition]
# Excluir archivos estáticos del conteo
failregex = ^<HOST> -.*"(GET|POST|HEAD) (?!.*\.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|eot|svg|pdf|txt|xml)(\?.*)?$).* HTTP/\d\.\d".*
ignoreregex =
datepattern = ^[^\[]*\[({DATE})\s+({TIME})\s+[^\]]*\]
2.2 Ediciones
No olvides cambiar el correo electrónico por el tuyo:
destemail = corp@domain.tld
sender = fail2ban@domain.tld
2.3 Umbral de Activación
Si es necesario, ajusta los parámetros según tus necesidades para evitar falsos positivos:
maxretry = 200
findtime = 60
bantime = 3600
3. Inicio de Servicios
systemctl restart fail2ban
systemctl enable fail2ban
4. Visualización y Gestión
4.1 Visualización de IPs Bloqueadas
Para iptables
iptables -L -n
Para fail2ban
fail2ban-client status nginx-flood
4.2 Prueba
Añadir temporalmente una IP de prueba a la lista de bloqueo
fail2ban-client set nginx-flood banip 1.2.3.4
Verificar el bloqueo y si se recibió el correo electrónico
fail2ban-client set nginx-flood unbanip 1.2.3.4