Limitación de velocidad usando haproxy por url por ip

Limitación de velocidad usando haproxy por url por ip

Alguien ataca nuestros servidores constantemente. No es DDOS. Sólo una IP llega a una URL más de 200 veces por segundo. Actualmente estoy bloqueando al usuario por tablas de ip. Estamos utilizando HAproxy para equilibrar la carga. ¿Hay alguna manera de limitar a un usuario según su IP y la URL a la que accede?

No quiero bloquear solo según la IP, ya que los usuarios con NAT podrían verse afectados. Digamos que quiero mostrar la página de error 503 si una IP en particular accede a la misma URL como www.example.com/somepage.php?some=option&other=option2 más de 3000 veces en 5 minutos. Esto significa que la misma IP puede acceder a otras URL como www.example.com/somepage.php?another=someotheroption.

Respuesta1

Esta solución requiere al menos haproxy 1.6.

Primero, agregue lo siguiente a la interfaz:

http-request set-header X-DOS-Protect %[src];%[req.fhdr(host)]%[capture.req.uri]

Luego, agregue lo siguiente al backend:

stick-table type integer size 1m expire 5m store http_req_rate(5m)
tcp-request inspect-delay 5s
tcp-request content track-sc0 req.fhdr(X-DOS-Protect),crc32(1) if HTTP
http-request tarpit if { sc0_http_req_rate gt 3000 }

No pude encontrar una manera de hacer el seguimiento en la interfaz porque no encontré una manera de aplicar un convertidor en esa cadena concatenada que conforma el encabezado X-DOS-Protect.

Estoy aplicando la función hash para asegurarme de que no almacene una cadena enorme en la tabla de palos, ya que podría conducir fácilmente a una denegación de servicio. Si cree que esta función hash no es adecuada para usted debido a demasiadas colisiones posibles, también puede hacerla más grande aplicando crc32 a cada uno de los componentes concatenados (y, por supuesto, eliminándolo al almacenar los datos y cambiando a un almacenamiento de mesa más grande), como este:

http-request set-header X-DOS-Protect %[src,crc32(1)];%[req.fhdr(host),crc32(1)]%[capture.req.uri,crc32(1)]

stick-table type string len 30 size 1m expire 5m store http_req_rate(5m)
tcp-request inspect-delay 5s
tcp-request content track-sc0 req.fhdr(X-DOS-Protect) if HTTP
http-request tarpit if { sc0_http_req_rate gt 3000 }

Tenga en cuenta que esta última solución utilizará más de 7 veces más memoria que la primera, para cada entrada en la tabla de dispositivos. Por supuesto, el riesgo de colisión también sería mucho menor.

información relacionada