Mitigar ataques DDoS en un servidor web usando Fail2ban

¿Qué es Fail2ban?
Es un script programado en Python que "observa" los logs de Apache en busca de patrones sospechosos y es capaz de tomar medidas para bloquear a los atacantes ya sea con iptables o lanzando un comando de nuestra elección. Se distribuye bajo licencia GNU.

Instalar y configurar Fail2ban en Debian
apt-get install fail2ban
El directorio de configuración de Fail2ban se encuentra en: /etc/fail2ban/ en donde existen dos directorios mas: action.d y filter.d.
- action.d: Encontraremos las acciones que Fail2ban realizará cuando alguno de nuestros filtros encuentre alguna IP haciendo maldades. Estas acciones pasan por filtrado con iptables, envio de e-mails de aviso o hasta realizar una llamada utilizando Asterisk.
- filter.d: Tenemos todos los filtros que utilizaremos para identificar a nuestros atacantes.
Configuración para evitar DoS (Denial of Service)
Primer paso
Editamos el archivo /etc/fail2ban/jail.conf y agregamos las siguientes líneas al final:
[http-get-dos]
enabled = true
port = http,https
filter = http-get-dos
logpath = /var/log/apache2/ARCHIVO_ACCESS_LOG_DE_TU_SERVIDOR
maxretry = 300
findtime = 300
bantime = 300
action = iptables[name=HTTP, port=http, protocol=tcp]
- maxretry: Especifica cuantos intentos vamos a dejar antes de banear la ip.
- findtime: Es el período de tiempo en segundos que estamos contando los "reintentos" (300 segundos = 5 minutos).
- bantime: Es el tiempo que debemos esperar para liberar las peticiones, osea el tiempo que la IP estará baneada, en este caso se trata de 5 minutos.
Segundo paso
Ahora creamos el archivo de filtrado en /etc/fail2ban/filters.d/http-get-dos.conf y dentro de el colocamos el siguiente contenido:
[Definition]
failregex = ^HOST -.* "(GET|POST). *
ignoreregex =
El parámetro failregex es una expresión regular que coincidirá con cualquier entrada GET en sus registros, por lo que, básicamente, todas las entradas válidas y no válidas son una coincidencia. Se debe configurar en el archivo jail.conf, el maxretry y findtime cuidadosamente a fin de evitar falsos positivos.
Tercer paso
Reiniciamos Fail2ban
/etc/init.d/fail2ban restart
Hasta ahora con esta configuración ya tenemos un servidor bastante seguro ante ataques ocasionales de denegación de servicio, pero es probable que necesite ajustes mas estrictos en maxretry y findtime para controlar los ataques de denegación de servicio distribuido (DDoS).
Verifiquemos el funcionamiento
Una manera sencilla de comprobar el funcionamiento de nuestra configuración anterior es utilizando ab (Apache Benchmark - parte del paquete apache2-utils) , así:
ab -n 500 -c 10 http://tu-sitio-web-punto-com:80/
Si lo vamos a comprobar de manera local, debemos debemos comentar el parámetro ignoreip en el archivo de configuración /etc/fail2ban/jail.conf y luego reiniciamos Fail2ban, y hacemos la prueba así:
ab -n 500 -c 10 http://127.0.0.1:80/
Esto enviara 500 page-loads en 10 conexiones simultaneas al servior web. Y por las reglas de maxretry y findtime que colocamos, las peticiones GET entrantes desde nuestra IP serán baneadas, y luego de que se cumpla el bantime podremos acceder nuevamente al sitio web.
Echamos un vistazo al log en /var/log/fail2ban.log y deberíamos ver algo como esto:
2014-02-22 05:37:21,943 fail2ban.actions: WARNING [http-get-dos] Ban YOUR_IP_ADDRESS
2014-02-22 05:42:22,341 fail2ban.actions: WARNING [http-get-dos] Unban YOUR_IP_ADDRESS
Esto nos puede ayudar a controlar las peticiones en exceso que realizan scripts mal intencionados para realizar fuerza bruta en formularios de acceso, entre otros, con está técnica y los valores bien afinados deberíamos lograr evitar las peticiones inadecuadas a nuestro servidor.