Etiquetas

,

Hace un tiempo escribí un pequeño apunte para detectar bots agresivos. Pero con la cantidad de bots que hay por el Menéame, y la cantidad de gente que «juega» haciendo varias decenas de conexiones por segundo, ese script era ya prácticamente inservible. En este tiempo estuve probando varios módulos del Apache. El mod_evasive del Apache –el más usado, no entiendo por qué– no sirve para nada ya que sólo controla las conexiones para un sólo proceso –en el Menéame estamos en unos 150-200 procesos concurrente en cada uno de los dos servidores–.

Al final, probando varias opciones de las iptables, la que más me gustó es la del módulo «recent». Funciona muy bien, no consume casi nada y tampoco requiere el módulo conntrack –de nuevo, es muy «caro» en el Menéame por la cantidad de conexiones–

Esto es lo que tengo en reglas de las iptables en Menéame:


#Connection throttling
IF=eth_la_que_corresponda
...
iptables -i $IF -I INPUT -p tcp --syn -m recent --set
iptables -i $IF -I INPUT -p tcp --syn -m recent --update --seconds 10 --hitcount 30 -j DROP

Lo que hace es contar el número de paquetes SYN (inicio de conexión TCP) para cada dirección IP en los últimos 10 segundos. Si llega a 30 descarta ese paquete por lo que no se establecerá la conexión (el TCP volverá a intentar varias veces, cuando baje del límite podrá establecerse). El valor de 30 es un valor que encontré iba muy bien para el Menéame. Podéis comenzar con eso y luego ajustarla.

Para poder mirar el número de conexiones simultáneas de cada IP hice un pequeño script en Python que las muestra ordenadas:


#! /usr/bin/env python
import re

ips = {}
r = re.compile(r’src=([\d\.]+).+ oldest_pkt: (\d)’)
f = open(«/proc/net/ipt_recent/DEFAULT»)
for line in f.readlines():
  g = r.match(line).groups()
  if  int(g[1]) > 4:
    # Store only in it has more than 4 conns.
    ips[g[0]] = int(g[1])

tuples = ips.items()
tuples.sort(lambda (k1,v1),(k2,v2):cmp(v2,v1))
for ip, counter in tuples:
  print ‘%-16s  %-8d’ % (ip, counter)

En cada servidor del Menéame los máximos que suelo observar no superan las 8 ó 9 conexiones. Por ejemplo:


$ recent-ip.py
83.41.13.38       9
88.22.14.52       9
84.78.63.183      9
85.219.45.29      9
83.33.104.1       9
62.43.161.95      8
62.43.51.161      8
85.57.206.54      7
213.60.230.179    7
88.14.107.53      7
85.60.43.31       7
85.85.25.68       7
88.11.242.144     7
84.126.172.191    7
84.127.93.44      6
83.138.223.248    6
212.225.182.55    6
217.127.202.163   6
84.123.119.212    5