Cómo controlar la recepción de peticiones abusivas desde una misma IP

Hace unos meses escribí esta entrada sobre un guión en Python para la detección de peticiones abusivas hacia un servidor web Apache. Me faltó indicar cómo controlarlas y es muy sencillo:

iptables -I INPUT --dport 80  -p tcp --syn -m recent --name "CONTROL-WEB" --set
iptables -I INPUT -p tcp --dport 80 --syn -m recent --update --seconds 30 --hitcount 20 -j DROP

Estas líneas de iptables, que podemos añadir al principio de la lista de órdenes de nuestro filtro de acceso al servidor, se encargan de contar el número de peticiones de establecimiento de conexión por cada dirección IP en los últimos 30 segundos, descartando los que puedan llegar cuando la cuenta ha superado el valor de 20 e impidiendo, por tanto, la conexión desde esa IP. El guión de la entrada mencionada nos puede servir para hacernos una idea de qué es lo habitual en nuestro sistema y ajustar los segundos y número de conexiones en esos segundos que queremos admitir.

La primera orden crea una lista dinámica de nombre CONTROL-WEB en la que insertará la IP de origen del paquete. La segunda, comprueba si esa IP se ha añadido a la lista en los últimos 30″ y, en el caso de que se hayan contabilizado más de 20 peticiones, deniega la petición.

Podemos ser más específicos indicando que solo queremos contabilizar los inicio de conexión:

iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent -name "CONTROL-WEB" --set
iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 30 --hitcount 50 -j DROP

En el directorio /proc/net/xt_recent encontraremos un fichero de nombre CONTROL-WEB y cuyo contenido es la lista de IPs añadidas por las reglas anteriores.

Referencia

  1. man iptables