Limite las conexiones máximas por dirección IP y las nuevas conexiones por segundo con iptables

37

Tenemos un servidor Ubuntu 12.04 con httpd en el puerto 80 y queremos limitar:

  • las conexiones máximas por dirección IP a httpd a 10
  • el máximo de nuevas conexiones por segundo a httpd a 150

¿Cómo podemos hacer esto con iptables?

evachristina
fuente

Respuestas:

48
iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 32 -j REJECT --reject-with tcp-reset  

Esto rechazará las conexiones superiores a 15 desde una IP de origen.

iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 150/second --limit-burst 160 -j ACCEPT  

En este se permiten 160 nuevas conexiones (paquetes realmente) antes de que se aplique el límite de 150 NUEVAS conexiones (paquetes) por segundo.

totti
fuente
1
¿Se puede configurar lo anterior para que funcione en todos los puertos, no solo en el puerto 80?
EminezArtus
1
¿Estás seguro de que esto es por IP?
LatinSuD
2
Para establecer esta regla para todos los puertos, simplemente elimine el --dport 80.
Dan Pritts
55
La segunda regla NO funciona en "nuevas conexiones". Afecta explícitamente las conexiones existentes ("ESTABLECIDAS"). Para hacer nuevas conexiones, desearía --estar NUEVO. También puede considerar usar -m conntrack --ctstateen lugar de -m state --state. conntrack es nuevo y mejorado vs. estado.
Dan Pritts
2
el comentario anterior para agregar la segunda regla a las NEWconexiones, no lo hagas, ¡convierte efectivamente tu INPUTcadena en un valor predeterminado accept!
Stuart Cardall el
8

Desea que las siguientes reglas en sus iptables respondan ambos requisitos en su pregunta:

iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT

iptables -t filter -I INPUT -p tcp --dport 80 -m state \
  --state RELATED,ESTABLISHED -j ACCEPT

# Adjust "--connlimit-above NN" to limit the maximum connections per IP
#   that you need.
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
  --connlimit-above 10 --connlimit-mask 32 -j DROP

# Adjust "--connlimit-above NNN" to the maximum total connections you
#   want your web server to support
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
  --connlimit-above 150 -j DROP

Debido a que estamos usando -I (según la solicitud de OP) tenemos que hacerlos en orden inverso, así que 'léalos' de abajo hacia arriba.

También sugiero considerar: el cambio de NN de máscara de límite de 32 a 24. Esto limitará una red de clase C completa (máximo 256 direcciones IP en el mismo rango) a 10 conexiones. También puede usar cualquier otro número sin clase, como 22 o 30, dependiendo de cómo cree que podría usarse su servicio.

Además, dependiendo de cómo desee que se comporte el cliente, puede usar "-j REJECT --reject-with tcp-reset" en lugar de "-j DROP" en las dos reglas anteriores, o incluso solo en las 150 conexiones máximas regla.

Si RECHAZA la conexión, el navegador o el software que utiliza el puerto 80 mostrará un estado "no disponible" de inmediato, pero la opción DROP hará que el cliente espere y vuelva a intentarlo varias veces antes de informar que el sitio no está disponible. Tiendo a inclinarme por el DROP, ya que se comporta más como una mala conexión que como un servidor fuera de línea.

Además, si el límite de conexión vuelve a caer por debajo de 150 (o 10) mientras todavía está volviendo a intentarlo, entonces finalmente llegará a su servidor.

Sin embargo, la opción RECHAZAR causará una fracción menos de tráfico a su sitio, ya que DROP hará que envíe paquetes adicionales mientras vuelve a intentarlo. Probablemente no sea tan relevante.

Si, por otro lado, el tráfico de su puerto 80 es parte de un clúster, entonces RECHAZAR le indicará al controlador del clúster que está inactivo y que deje de enviarle tráfico mientras dure el tiempo de reintento.

La regla RELACIONADA, ESTABLECIDA está ahí bajo el supuesto de que su regla predeterminada es bloquear todo el tráfico (iptables -t filter -P INPUT DROP). Esto solo acepta otros paquetes pertenecientes a conexiones aceptadas.

También --syn le dice que preste atención (o cuente) a los paquetes que configuran una conexión TCP.

Ian Macintosh
fuente
Gracias por caminar a través de las minucias de estos comandos.
txyoji
¿Puedo obtener --connlimit-mask para bloquear solo esa dirección IP específica y no un rango completo?
Análogo
--Connlimit-mask 32 es un límite de dirección única. Es decir, es como una máscara de red / 32. Algo menos, como 24 es como una máscara de red / 24, ignorando los 8 bits inferiores.
Ian Macintosh
5

Necesitas usar el connlimit módulos que le permiten restringir la cantidad de conexiones TCP paralelas a un servidor por dirección IP de cliente (o bloque de direcciones).

/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
      --connlimit-above 10 -j DROP
Raman_Singh
fuente
Actualicé su respuesta, espero que todavía esté bien (¿por qué se necesita "--syn"?). + ¿Y qué hay de "La conexión máxima por segundo (puerto 80, tcp) a 150"? ¡Gracias!
evachristine
--syn significa que la regla solo mira los paquetes TCP con el indicador de sincronización, lo que significa nuevas conexiones. Podría hacer aproximadamente lo mismo con -m state --state NEW, pero esto es probablemente más rápido.
Dan Pritts