Estuvimos hablando en el anterior post sobre cómo proteger nuestra infraestructura mediante la limitación de peticiones por segundo que podía realizar una misma IP gracias a Haproxy.
En esta segunda parte configuraremos Haproxy para que registre mediante una sticky-table tanto la IP del visitante como la URL que visita. De esta forma, vamos a poder controlar las peticiones repetitivas de bots y webcrawlers.
De igual forma, vamos a proteger un path sensible de nuestra aplicación.
Configuración Haproxy contra bot y webcrawlers
En la siguiente configuración, vamos a tratar de evitar que los bots, webcrawlers y scrappers nos visiten masivamente. Para ello crearemos dos backends nuevos:
El primero registrará durante 24 horas tanto URL como IP del visitante:
backend per_ip_and_url_rates stick-table type binary len 8 size 1m expire 24h store http_req_rate(24h)
El segundo registrará también durante 24 horas los ratios de visitas de cada IP:
backend per_ip_rates stick-table type ip size 1m expire 24h store gpc0,gpc0_rate(30s)
Una vez creados los backends, modificaremos la definición de nuestro frontal de la siguiente forma:
frontend my_web_app bind :80 http-request track-sc0 src table per_ip_rates http-request track-sc1 url32+src table per_ip_and_url_rates unless { path_end .css .js .png .jpeg .gif } acl exceeds_limit sc_gpc0_rate(0) gt 15 http-request sc-inc-gpc0(0) if { sc_http_req_rate(1) eq 1 } !exceeds_limit http-request deny if exceeds_limit default_backend web_backend
La línea http-request track-sc0 src table per_ip_rates nos permitirá registrar la IP de cada uno de los visitantes. La línea http-request track-sc1 url32+src table per_ip_and_url_rates unless { path_end .css .js .png .jpeg .gif } registrará la IP y la URL visitada exceptuando las visitas generadas a los assets de nuestro sitio web. Y por último, con la línea http-request deny if exceeds_limit mandamos un código 403 Forbidden, si el usuario visita un máximo de 15 páginas distintas en el tiempo fijado por la sticky-table definida en el backend: per_ip_rates.
Configuración Haproxy contra brute-force attacks
Imaginemos ahora que queremos proteger, por ejemplo, el acceso a la parte de login de nuestra página web basada en WordPress.
Crearemos un nuevo backend para alojar las peticiones masivas a nuestro wp-login.php.
backend per_ip_and_url_bruteforce stick-table type binary len 8 size 1m expire 10m store http_req_rate(3m)
Modificaremos ahora nuestra definición de frontend para guardar en el sticky-table las peticiones que van a nuestro path de acceso wp-login.php que se hagan mediante POST.
Posteriormente denegaremos el acceso mediante un 403 Forbidden a los que excedan el ratio deseado.
frontend my_web_app http-request track-sc2 base32+src table per_ip_and_url_bruteforce if METH_POST { path /wp-login.php } http-request deny if { sc_http_req_rate(2) gt 10 }
Configuración Haproxy contra escáneres de vulnerabilidades
Por último, un problema muy común en ciertas instalaciones son los escáneres de vulnerabilidades que se dedican a probar infinidad de combinaciones de URL’s en busca de problemas o posibles agujeros de seguridad.
Habitualmente, y especialmente si nuestro sitio está configurado correctamente, estos servicios generan un flujo de peticiones bastante alto y la mayoría de las veces con códigos de error 4xx que podemos rastrear gracias a Haproxy para evitar que puedan afectar al rendimiento de nuestro sitio.
Modificaremos la definición de nuestro backend para agregar al sticky-table la variable http_err_rate(5m).
backend per_ip_rates stick-table type ip size 1m expire 24h store gpc0,gpc0_rate(30s),http_err_rate(5m)
Y en la definición de nuestro frontend denegaremos la petición si el ratio de peticiones que han devuelto es superior al valor especificado.
http-request deny if { sc_http_err_rate(0) gt 10 }
De esta manera, si nuestra aplicación está siendo escaneada por uno de estos sistemas de detección de vulnerabilidades, podemos evitar que se vea sobrecargada si el ratio de peticiones con error sube de un margen establecido.
Otra acción que podríamos tomar sería la de dirigir las peticiones con este alto volumen de error a un backend específico, por ejemplo, uno que sirviese la aplicación de forma estática o cacheada, evitando así la sobrecarga de la parte dinámica de nuestro sitio web.
Con esta pequeña introducción a la infinidad de posibilidades de configuración, protección y servicio de nuestro software de proxy y balanceo, terminamos la serie de posts relacionados con Haproxy.