Securizando el servidor web apache: Instalando mod_evasive

Primero: mod_evasive es un módulo para apache o apache2 que intentar ayudar a detener ataques DOS o incluso dDOS.

Para ello, permite definir unas reglas en un archivo de configuración (como por ejemplo que X conexiones por segundo a Y páginas permitan bloquear una cierta IP).

Instalarlo en debian bajo apache2 es relativamente fácil, he aquí un minihowto (supongo un debian stable con apache2 instalado con apt-get):

Primero como root creamos un directorio para guardar los fuentes del mod_evasive, por ejemplo: /usr/src/mod_evasive/:

# mkdir /usr/src/mod_evasive
# cd /usr/src/mod_evasive

Posteriormente descargamos el código fuente desde la web oficial:

# wget http://www.zdziarski.com/projects/mod_evasive/mod_evasive_1.10.1.tar.gz (enlace roto)

Extraemos:

# tar -xvzf mod_evasive_1.10.1.tar.gz
# rm -rf mod_evasive_1.10.1.tar.gz

Instalamos (en caso que no lo tengamos ya) el paquete apache2-threaded-dev (que es el contiene el programa apxs2 que nos permite compilar mod_evasive20.c como módulo de apache2, OJO: En la documentación (readme de mod_evasive) pone que para instalarlo en apache el comando es apxs, sin embargo (y gracias a la tecla TAB) el prrgrama a ejecutar en debian es apxs2)

# apt-get install apache2-threaded-dev

Una vez instalado el paquete, compilamos:

# apxs2 -ic mod_evasive20.c

(o según el manual: apxs2 -ica mod_evasive20.c para cargarlo automáticamente sin tener que hacer el resto de pasos, pero prefiero tener el control de mis archivos de configuración TODOS a mano, luego uso la primera alternativa).

Bien, una vez hecho esto tenemos el mod_evasive compilado en: /usr/lib/apache2/modules/mod_evasive20.so, pero ahora deberemos cargarlo en nuestro apache2, para ello se requiere crear dos ficheros:

Primero:

# echo "LoadModule evasive20_module /usr/lib/apache2/modules/mod_evasive20.so" > /etc/apache2/mods-avaiable/evasive.load

Segundo:

Crear el archivo: /etc/apache2/mods-avaiable/evasive.conf

# touch /etc/apache2/mods-avaiable/evasive.conf

Y con nuestro editor preferido (en mi caso nano), introducir la siguiente información

<IfModule mod_evasive.c>
DOSHashTableSize 3097
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 900
</IfModule>

Explicación de cada cosa:

DOSHashTableSize: Tamaño de la tabla hash, supongo que será el máximo de IPs que almacenará por motivos de optimización

DOSPageCount: Número de páginas solicitadas a partir de las cuales si se cumplen el resto de condiciones, el módulo se activa.

DOSSiteCount: Número de solicitudes máximas a partir del cual el filtro se activa.

DOSPageInterval: Intervalo (en segundos) de tiempo entre las peticiones a las páginas

DOSSiteInterval: Intervalo (en segundos) de tiempo entre las peticiones

DOSBlockingPeriod: Tiempo que se bloqueará la web a esa IP

También puede ejecutarse un comando iptables para que en caso que nuestro módulo detecte un DOS, bloquee la IP para que no pueda acceder a nuestra máquina:

DOSSystemCommand "sudo -u root -c '/sbin/iptables -A INPUT -s %s -j DROP"

Aviso, tal cual está el comando, debe instalarse el paquete sudo y dar privilegios para usar iptables al usuario y grupo www-data (según creo), lo cual no me parece bien del todo, sin embargo hay soluciones alternativas como hacernos un programa con el bit SUID de modo que:
1) No use funciones inseguras (es decir: usar strncpy, strncmp, etc)
2) Sólo permita añadir reglas ejecutando él el iptables -A INPUT -s laIP -j DROP
3) Compruebe si hay caracteres tipo &&, -, etc y sólo permita números y puntos con un máximo de 15 caracteres (el estándar del IPv4: 0.0.0.0) pero cuidado si usas IPv6.

Otra opción es usar mi script banfromlog y hacer un comando que meta la IP en la base de datos y retocarlo para que cuando se ejecute, prohiba el acceso al puerto 22 y al 80

También se puede poner dentro de la configuración:

DOSEmailNotify root

Que enviaría un email al root de la máquina (que deberíais tener redirigido a otro usuario o a una cuenta de correo externa), lo cual siempre ayuda si vuestro operador de móvil os envía gratis un SMS cada vez que os envían un email (de este modo os enteráis justo en el momento que os están intentando hacer el ataque).

DOSWhitelist 127.0.0.1

Si queréis que determinadas IP’s (en este caso vuestro interfaz de loopback) no cuenten para el filtro (porque váis a hacer pruebas de carga, etc) podéis usar DOSWhiteList, que serán las ips a las que no se les aplicará el filtro aunque hagan un DOS al servidor.

Para evitar que una araña (por ejemplo la de google) pueda ser considerada un ataque (ya que hace muchas peticiones), se puede poner:

DOSWhitelist 66.249.65.*
DOSWhitelist 66.249.66.*

Como véis, la regla acepta caracteres comodines.

Evidentemente, una araña que haga tantas peticiones, está mal programada (suelen tener cuidado, salvo el bot de MSN, que no se porqué, pero si no le pongo algún tipo de filtro, es capaz de saturarme el servidor).

Evidentemente, os queda por averiguar rangos ips de los buscadores en los que queráis aparecer para aparecer en ellos de forma segura, un truco: Mirar los logs antiguos (el navegador, ya que suele decir si es un bot o no).

Siempre hay cosas más raras que se pueden hacer, sobre todo si tienes apache en un entorno chroot.

Ya sólo nos queda reiniciar apache2 para que se cargue correctamente el módulo:

# /etc/init.d/apache2 restart

En caso que queramos probar que realmente funciona el módulo, tenemos un pequeño programa a modo de test que se suministra con el propio fuente del mod_evasive, llamado test.pl, para ejecutarlo, nos situamos en el directorio del fuente (en nuestro caso /usr/src/mod_evasive) y ejecutamos: perl test.pl (si al principio devuelve códigos 200 de aceptado y después códigos 403 de prohibido, nuestro módulo está funcionando correctamente.

Hay más cosas que se pueden hacer para ayudar a luchar contra los ataques DOS, intentaré publicar otra otro día, por el momento unos links interesantes:

Web oficial del mod_evasive
http://www.nuclearelephant.com/projects/mod_evasive/ (no funcional)

Intentando detener un DOS:
http://foro.elhacker.net/index.php/topic,137442.0.html

Actualización: Otro manual de mod_evasive:

https://www.digitalocean.com/community/tutorials/how-to-protect-against-dos-and-ddos-with-mod_evasive-for-apache-on-centos-7