El tipo más común de ataque a un servidor o VPS es el DDos. La forma de operar de estos ataques es, lanzar repetidas solicitudes contra un servidor desde varios sistemas a la vez. Si son excesivas, la maquina receptora se queda sin ciclos de procesamiento, memoria o ancho de banda de red y, el sistema se bloquea de manera irreversible hasta que no pueda levantarse por si sola.
Es evidente que contra ataques de millones de clientes, no existe forma de pararlo, también te digo que esto no es común. Lo normal es que se lancen unos cientos, tal vez unos pocos miles. Para esto tenemos una solución, tenemos el módulo de Apache «mod_evasive».La utilidad mod_evasive supervisa las solicitudes entrantes del servidor, incluyendo las que son sospechosas. Por ejemplo.
- Detecta el exceso de solicitudes a una página en concreto por segundo.
- Más de 50 solicitudes simultáneas por segundo las considera sospechosas.
- Esta pendiente de la repetición de solicitudes desde una ip que ya está en la lista negra.
Al detectar un ataque, el módulo de apache envía un error 403 a la máquina cliente. Al proteger un servidor de manera predeterminada, bloquea las ip afectadas durante 10 segundos, pero este valor es modificable.
En este tutorial veremos como instalar y configurar mod_evasive, en nuestro servidor con CentOS o Debian / Ubuntu y derivados. Proteger un servidor contra DDos.
Prerequisitos
Se tiene que deshabilitar el firewall y cargar iptables (si es que no esta habilitado ya)
En CentOS
systemctl stop firewalld
systemctl disable firewalld
yum update && yum install iptables-services
systemctl enable iptables
systemctl start iptables
systemctl status iptables
En Ubuntu
systemctl stop ufw
systemctl disable ufw
sudo apt-get update
sudo apt-get install iptables
Instalación mod_evasive
En CentOS
En Ubuntu
sudo apt-get install apache2-utils sudo
apt-get install libapache2-mod-evasive
Cuando acaba la instalación se crean los archivos de configurcion
ls -l /etc/httpd/conf.d
-rw-r–r– 1 root root 3475 jun 16 2015 mod_evasive.conf
Validar que las siguiente entrada se encuentre cargada como primer linea.(sino agregarla)
LoadModule evasive20_module modules/mod_evasive24.so
En CentOS
sudo nano /etc/httpd/conf.d/mod_evasive.conf
En Ubuntu
sudo nano /etc/apache2/mods-enabled/evasive.conf
LoadModule evasive20_module modules/mod_evasive24.so
DOSHashTableSize 3097
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
DOSEmailNotify usuario@mimail.com DOSLogDir “/var/log/apache2/”
Puedes configurar los valores según tus necesidades, pero ten en cuenta que para máquinas con un tráfico normal, los valores por defecto son aceptables. Vemos el detalle explicativo.
DOSHashTableSize: Este valor asigna espacio para ejecutar las operaciones de búsqueda. Al aumentar el tamaño, mejora la velocidad a costa de un mayor consumo de memoria.
DOSPageCount: Número de solicitudes a una página concreta para ingresar una ip a la lista negra.
DOSSiteCount: Número de solicitudes al sitio para ingresar una ip a la lista negra.
DOSPageInterval: Número de segundos que calcula el umbral de accesos a una página en particular de una ip.
DOSSiteInterval: Número de segundos que calcula el umbral de accesos a un sitio de una ip.
DOSBlockingPeriod: Tiempo en segundos que una ip permanece en la lista negra.
DOSEmailNotify: Puedes des comentar la línea e introducir tu email. El módulo te avisará en cada bloqueo.
DOSSystemCommand: Por si quieres ejecutar un comando específico al detectar un ataque.
DOSLogDir: Por si quieres modificar la ruta donde se guardan los logs.
DOSWhitelist: Lista blanca de ip’s.
Ejemplo de archivo de configuración
# mod_evasive configuration
LoadModule evasive20_module modules/mod_evasive24.so
<IfModule mod_evasive24.c>
# The hash table size defines the number of top-level nodes for each
# child’s hash table. Increasing this number will provide faster
# performance by decreasing the number of iterations required to get to the
# record, but consume more memory for table space. You should increase
# this if you have a busy web server. The value you specify will
# automatically be tiered up to the next prime number in the primes list
# (see mod_evasive.c for a list of primes used).
DOSHashTableSize 3097
# This is the threshhold for the number of requests for the same page (or
# URI) per page interval. Once the threshhold for that interval has been
# exceeded, the IP address of the client will be added to the blocking
# list.
DOSPageCount 5
# This is the threshhold for the total number of requests for any object by
# the same client on the same listener per site interval. Once the
# threshhold for that interval has been exceeded, the IP address of the
# client will be added to the blocking list.
DOSSiteCount 50
# The interval for the page count threshhold; defaults to 1 second
# intervals.
DOSPageInterval 1
# The interval for the site count threshhold; defaults to 1 second
# intervals.
DOSSiteInterval 1
# The blocking period is the amount of time (in seconds) that a client will
# be blocked for if they are added to the blocking list. During this time,
# all subsequent requests from the client will result in a 403 (Forbidden)
# and the timer being reset (e.g. another 10 seconds). Since the timer is
# reset for every subsequent request, it is not necessary to have a long
# blocking period; in the event of a DoS attack, this timer will keep
# getting reset.
DOSBlockingPeriod 10
# If this value is set, an email will be sent to the address specified
# whenever an IP address becomes blacklisted. A locking mechanism using
# /tmp prevents continuous emails from being sent.
#
# NOTE: Requires /bin/mail (provided by mailx)
DOSEmailNotify user@domain.com.mx
# If this value is set, the system command specified will be executed
# whenever an IP address becomes blacklisted. This is designed to enable
# system calls to ip filter or other tools. A locking mechanism using /tmp
# prevents continuous system calls. Use %s to denote the IP address of the
# blacklisted IP.
#DOSSystemCommand “su – someuser -c ‘/sbin/… %s …'”
DOSSystemCommand “sudo /usr/local/bin/scripts-tecmint/ban_ip.sh %s”
# Choose an alternative temp directory By default “/tmp” will be used for
# locking mechanism, which opens some security issues if your system is
# open to shell users.
#
# http://security.lss.hr/index.php?page=details&ID=LSS-2005-01-01
#
# In the event you have nonprivileged shell users, you’ll want to create a
# directory writable only to the user Apache is running as (usually root),
# then set this in your httpd.conf.
DOSLogDir “/var/log/mod_evasive”
# You can use whitelists to disable the module for certain ranges of
# IPs. Wildcards can be used on up to the last 3 octets if necessary.
# Multiple DOSWhitelist commands may be used in the configuration.
DOSWhitelist 187.188.55.133
#DOSWhitelist 192.168.0.*
</IfModule>
Es importante hacer tunning del sitio y ver que el uso normal no vaya a generar un bloqueo de la ip del cliente o se correara el peligro de bloquear a usuarios normales
Este script (sudo /usr/local/bin/scripts-tecmint/ban_ip.sh %s) se usa para que permanentemente se bloque la ip ofensora usando iptables
A continuación se muestra el contenido del script.
sudo nano /usr/local/bin/scripts-tecmint/ban_ip.sh
!/bin/sh
# IP that will be blocked, as detected by mod_evasive
IP=$1
# Full path to iptables
IPTABLES="/sbin/iptables"
# mod_evasive lock directory
MOD_EVASIVE_LOGDIR=/var/log/mod_evasive
# Add the following firewall rule (block all traffic coming from $IP)
$IPTABLES -I INPUT -s $IP -j DROP
# Remove lock file for future checks
rm -f "$MOD_EVASIVE_LOGDIR"/dos-"$IP"sudo nano /usr/local/bin/scripts-tecmint/ban_ip.sh
Este script bloqueara permanentemente la ip, aun cuando el mod_envasive se haya configurado con 10 segundos de baneo, por lo que si se requiere desbloquear, se tiene que borrar manualmene la entrada en el iptables.
Aqui se muestra otro ejemplo mas completo de script
#!/bin/bash
#set -x
[ -z $1 ] && (echo "Usage: $0 <sourceip>"; exit 1)
[ -x /usr/bin/at ] || (echo "Please, install 'at'"; exit 1)
#############
## OPTIONS
#
SOURCEIP="$1"
HOSTNAME=$(/bin/hostname -f)
BODYMAIL="/tmp/bodymailddos"
MODEVASIVE_DOSLogDir="/tmp"
FROM="Anti DDOS System <ddos@yourfromdomain.foo>"
# Multiple accounts separated by commas
TO="admin@yourfromdomain.foo user@yourfromdomain.foo"
# Time-units can be minutes, hours, days, or weeks
BANNEDTIME="1 minute"
#
##
############
# Custom mail message
{
echo "Massive connections has been detected from this source IP: $SOURCEIP
The system has blocked the IP in the firewall for $BANNEDTIME. If the problem persist you should block that IP permanently.
- Anti DDOS System -"
} > $BODYMAIL
sudo /sbin/iptables -I INPUT -s $SOURCEIP -j DROP
echo "sudo /sbin/iptables -D INPUT -s $SOURCEIP -j DROP" | sudo at now + $BANNEDTIME
cat $BODYMAIL | /usr/bin/mail -r "$FROM" -s "DDOS Attack Detected - $HOSTNAME" $TO
rm -f "$MODEVASIVE_DOSLogDir/dos-$SOURCEIP"
Para que apache pueda ejecutar ese comando hay que agregar al archivo de sudoers las siguientes lineas
nano /etc/sudoers
apache ALL=NOPASSWD: /usr/local/bin/scripts-tecmint/ban_ip.sh *, /sbin/iptables *, /usr/bin/at *
Defaults:apache !requiretty
Una vez que tengamos configurado el archivo, lo guardas. Para proteger un servidor de ataques DDos, tan solo nos falta recargar los módulos de Apache, o reiniciar el mismo.
En CentOS
sudo systemctl restart httpd.service
En Ubuntu
sudo systemctl reload apache2
Validar que los modulos esten en el path adecuado
cd /etc/httpd/modules
ls -l | grep -Ei ‘(evasive)’
Validar que se hayan cargado los modulos
httpd -M | grep -Ei ‘(evasive)’
Probar el modulo mod_evasive
Para asegurarnos que el modulo esta jalando, se utiliza el script test.pl que viene con la instalación
En CentOS
nano /usr/share/doc/mod_evasive-1.10.1/test.pl
En Ubuntu
nano /usr/share/doc/libapache2-mod-evasive/examples/test.pl
Modificar el script de acuerdo a los siguientes parametros
#!/usr/bin/perl
# test.pl: small script to test mod_dosevasive's effectiveness
use IO::Socket;
use strict;
for(0..200) {
my($response);
my($SOCKET) = new IO::Socket::INET( Proto => "tcp",
PeerAddr=> "xxx.xxx.xxx.xx:80");
if (! defined $SOCKET) { die $!; }
print $SOCKET "GET /?$_ HTTP/1.0\n\n";
$response = <$SOCKET>;
print $response;
close($SOCKET);
}`
En CentOS
sudo perl /usr/share/doc/mod_evasive-1.10.1/test.pl
En Ubuntu
sudo perl /usr/share/doc/libapache2-mod-evasive/examples/test.pl
Se debe tener una salida de este tipo
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
En los logs del sistema /var/log/messages o /var/log/syslog podria aparecer entradas de este tipo.
Oct 26 15:36:42 CentOS-7 mod_evasive[2732]: Blacklisting address 192.168.1.42: possible DoS attack.