Mod Evasive: Evitando una Denegación de Servicio Distribuida
Una denegación de servicio (DoS) es un tipo de ataque (muy común en ámbitos de servidores web) donde un atacante se encarga de realizar una serie muy numerosa de peticiones a un servidor (usualmente una petición de naturaleza muy costosa) con el objetivo de que se sobrecargue atendiéndolas y se colapse, denegando el servicio a otros posibles usuarios.
Este tipo de ataques, muy simples, no suelen tener mayor gravedad a no ser que se combinen con algún tipo de vulnerabilidad del sistema, ya que como se trata de un único usuario, basta con identificarlo y bloquearlo.
Sin embargo, existe otra variante, denegación de servicio distribuida (DDoS) en la que se utiliza el mismo concepto anterior, sólo que esta vez en lugar de tratarse de un sólo atacante se trata de una red distribuida de atacantes (conjunto de usuarios «sincronizados» como uno).
Este último caso si está considerado de los más peligrosos, ya que no se trata de una sola entidad la que intenta atacar, sino de una «flota» de atacantes muy numerosa, en la que un sólo servidor normalmente se desborda al recibir tantas peticiones.
Tengamos también en cuenta que, normalmente, estas redes distribuidas están formadas por miles de atacantes, que a su vez son víctimas (usuarios o servidores infectados con troyanos o virus, sin saberlo) que silenciosamente forman parte de botnets.
Para intentar frenar estos ataques vamos a utilizar un módulo para Apache llamado mod_evasive. Y digo intentar frenar, porque siempre hay que tener en cuenta cuál es el objetivo del DDoS: Si es provocar una denegación de nuestro servidor web (u otro) nos servirá perfectamente. Si se trata de provocar una denegación de nuestra red local, router u otro elemento relacionado con el flujo de red, de poco nos servirá, ya que el módulo actua a nivel de aplicación.
Este módulo se encarga de gestionar una tabla hash con las IPs con accesos más frecuentes al servidor. Así, si detecta un número desmesuradamente alto de peticiones desde una misma IP, las anulará por un tiempo.
Preparación y compilación de mod_evasive
Este módulo es compatible tanto con Apache 1.3 como con Apache 2.0 (además también de iPlanet), sin embargo esta guía está especificada concretamente para Apache en su versión 2.
Descargar mod_evasive: Desde la página oficial de mod_evasive se puede descargar la última versión o desde una terminal escribiendo:
wget http://www.zdziarski.com/blog/wp-content/uploads/2010/02/mod_evasive_1.10.1.tar.gz
Desempaquetar mod_evasive: Procedemos a desempaquetar el módulo fuente de apache:
tar -xzvf mod_evasive_1.10.1.tar.gz
Compilar y obtener el módulo: El paquete de mod_evasive descargado es el código fuente, así que hay que compilarlo para obtener el módulo de Apache. Para ello nos ayudaremos de la utilidad apxs (Apache Extension Tool).
apxs -i -a -c mod_evasive20.c
Si no tienes la utilidad apxs, asegurate e instala el paquete de desarrollo de Apache, Apache-devel, antes. También puedes utilizar el clásico make mediante el fichero Makefile.tmpl.
Una vez realizados estos pasos, la compilación nos habrá creado el fichero mod_evasive20.so en nuestra carpeta de módulos de Apache (/usr/lib/httpd/modules).
Instalación y carga de mod_evasive
Generalmente el apxs se encarga de realizar la compilación del módulo, copiarlo en la carpeta de módulos de Apache e incluir la linea de carga en la configuración de Apache. No obstante, no estaría de más que lo comprobaramos.
Comprobar carga de mod_evasive: En una terminal escribimos lo siguiente (NOTA: la carpeta puede variar según la distro de linux)
grep evasive /etc/httpd/httpd.conf
Lo que nos debería devolver algo similar a lo siguiente:
LoadModule evasive20_module /usr/lib/httpd/modules/mod_evasive20.so
Si no es así, debemos incluir dicha linea en el fichero de configuración de Apache, para cargar correctamente el módulo.
Incluir configuración mod_evasive: Finalmente, añadimos también la siguiente linea en el fichero anterior:
Include mod_evasive.conf
Creando, por consiguiente, un fichero llamado mod_evasive.conf en la misma carpeta, donde estableceremos las distintas directivas del módulo, que veremos a continuación.
Configuración de mod_evasive
Con la linea vim /etc/httpd/mod_evasive.conf cargaremos el fichero de configuración de nuestro modulo, preparandolo para adaptarlo a nuestro gusto.
DOSHashTableSize 3097
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
Esta es la configuración que trae por defecto mod_evasive. Sin embargo, pasaremos a repasar todas las directivas para una mayor personalización.
DOSHashTableSize: Tamaño de la tabla hash que almacenará las IPs (nodos). Por defecto el valor es de 3097.
DOSPageCount / DOSPageInterval: Máximo (umbral) que se debe alcanzar para ser incluído en la lista de bloqueados. En este caso el objetivo será una página concreta. (Entiendase como «Máximo de DOSPageCount páginas en DOSPageInterval segundos»).
Por defecto el máximo está establecido a 2 páginas por segundo.
DOSSiteCount / DOSSiteInterval: Máximo (umbral) que se debe alcanzar para ser incluído en la lista de bloqueados. En este caso el objetivo será cualquier objeto (imagenes, css...). (Entiendase como «Máximo de DOSSiteCount objetos en DOSSiteInterval segundos»).
Por defecto el máximo está establecido a 50 objetos por segundo.
DOSBlockingPeriod: Tiempo en segundos (contador) que permanecerá bloqueada la IP de la lista. Dentro de este periodo, los accesos desde dicha IP obtendrán un error HTTP 403 (prohibido).
En el caso de que la IP intente acceder dentro del periodo de bloqueo, el contador vuelve a ponerse en su valor inicial y tendrá que volver a transcurrir el número de segundos desde el principio de nuevo.
DOSEmailNotify: Opcional. Dirección de email a la que serán enviadas (mediante el comando mail) notificaciones cuando se bloqueen IPs. Incorpora sistema lock para no repetir varios emails y notificar una sola vez.
DOSSystemCommand: Opcional. Comando que será ejecutado cada vez que se añada una IP a la lista. Se reemplazará %s por la IP. De este modo, una buena técnica es hacer lo siguiente:
DOSSystemCommand "/sbin/iptables -I INPUT -p tcp --dport 80 -s %s -j DROP"
Lo que hará que se ejecute el firewall de Linux (iptables) y bloquee todas las peticiones entrantes por el puerto TCP/80 (web).
DOSLogDir: Opcional. Selecciona una carpeta como directorio temporal para los logs. Por defecto, si no es especificado, tiene el valor /tmp.
DOSWhitelist: Opcional. Incluye una lista blanca para IPs que no tendremos en cuenta para bloquear. Ideal para añadir por ejemplo, el rango de IPs de los bots de Google (rango CIDR 66.249.64.0/19):
DOSWhitelist 66.249.73.*
Puedes usar varias directivas DOSWhitelist y comodin de rangos de hasta los 3 últimos octetos.
Finalmente, guardamos el fichero de configuración y reiniciamos el servidor Apache /etc/init.d/httpd restart. Ya tenemos listo el mod_evasive para funcionar.
Testeo de mod_evasive
Para realizar una prueba y comprobar si funciona correctamente, utilizaremos el fichero test.pl incluido en el paquete descargado. Ojo con tener la opción del firewall activada, aconsejo desactivarla para la prueba. Se trata de un pequeño programa en Perl, que realiza 100 peticiones secuenciales a nivel local (muy rápido, menos de 1 segundo). Así, si sistema está funcionando bien, al ejecutar el programa perl test.pl, aparecería algo similar a esto:
[…]
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
[…]
A medida que se efectuan las conexiones, se irán sirviendo correctamente, hasta que el mod_evasive detecta que se ha sobrepasado el umbral e incluye la IP local (127.0.0.1) en la lista de bloqueados.