Haproxy es un paquete de software que no deja de sorprendernos conforme vamos adoptándolo y utilizándolo en distintos proyectos de nuestro día a día en Grupo Trevenque. Como sabréis, Haproxy es un proxy TCP y HTTP de muy bajo consumo y altas prestaciones. Permite su uso (y casi es un estándar de facto) como balanceador de carga y a parte es… Open Source.
Entre sus innumerables bondades está la de ser un genial balanceador de carga tanto en capa L4 como en capa L7, que también nos permite proteger nuestra infraestructura mediante políticas de limitación de concurrencias o rate-limit. Esta funcionalidad, en conjunción con las sticky-tables y detección de códigos de error, nos permite salvaguardar nuestros servicios de Bots, Crawlers, Web Scrappers y todo tipo de actores no deseados que pueden hacer presencia de modo insospechado y pernicioso en el buen desempeño de nuestra infraestructura.
Instalación y configuración de Haproxy 2.0 (LTS)
Comenzaremos con la instalación de Haproxy que podemos realizar desde sus repositorios oficiales. En este caso, para Debian, bastará con agregar el repositorio e instalar el paquete de la siguiente forma:
# Para versiones de Debian 9 # https://haproxy.debian.net/#?distribution=Debian&release=stretch&version=2.0 # Instalación de la llave pública del repositorio curl https://haproxy.debian.net/bernat.debian.org.gpg | apt-key add - # Configuración del haproxy.list echo deb http://haproxy.debian.net stretch-backports-2.0 main | tee /etc/apt/sources.list.d/haproxy.list # Actualización del conjunto de repositorios apt-get update # Instalación apt-get install haproxy=2.0.\*
Una vez instalado, tendremos nuestro fichero de configuración en la ruta /etc/haproxy/haproxy.cfg .
Aunque no es el scope de este post hablar de toda la configuración que podemos hacer con Haproxy, en este caso vamos a mostrar como proteger una instalación de un cluster web de varios servidores.
Para ello, activaremos como primer paso el socket de estadísticas de Haproxy dentro de la sección global de su fichero de configuración:
global stats socket /var/run/admin/haproxy.sock mode 660 level admin
Una vez hecho esto, tendremos que recargar la configuración de Haproxy mediante systemctl reload haproxy . Es recomendable, previo a esta operación, testear que la configuración de Haproxy tiene una sintaxis válida mediante el comando haproxy -c -V -f /etc/haproxy/haproxy.cfg .
Con una configuración válida en ejecución definiremos por ejemplo un conjunto de servidores web backend que admiten un máximo de 500 conexiones por servidor. Una vez sobrepasado dicho límite, Haproxy se encargará de encolar durante un tiempo definido las siguientes conexiones hasta que los servidores sean capaces de procesarlas.
De esta forma, nos aseguramos de que el número de conexiones que recibe nuestro conjunto de servidores dentro del backend no excede su capacidad planificada.
Lo realizaremos de la siguiente forma:
backend web_backend timeout queue 30s server web_backend_srv_1 10.200.100.101 check maxconn 500 server web_backend_srv_2 10.200.100.102 check maxconn 500
Con esta protección, nuestra instalación de Haproxy retendrá durante un máximo de 30 segundos las peticiones que excedan la capacidad de nuestros servidores web y devolverá un error 503 pasado ese tiempo si persiste la carga.
Ahora que hemos protegido nuestros servidores backend, vamos a limitar el número de conexiones que un cliente puede realizar durante un tiempo dado. Esto nos permitirá rastrear, en un principio, a quienes abusan de nuestro servicio, así como limitar el número de peticiones que pueden lanzar.
frontend my_web_app bind :80 stick-table type ip size 100k expire 60s store http_req_rate(10s) http-request track-sc0 src http-request deny deny_status 429 if { sc_http_req_rate(0) gt 20 } default_backend web_backend
Con esta configuración definimos una sticky table de tipo IP (almacenará IPs de acceso) con un tamaño de 100k que va a guardar el ratio de conexiones que realiza cada visitante de nuestro servicio. Esta tabla contiene la ip de los visitantes y fija un máximo de 20 conexiones durante 10 segundos. Una vez sobrepasado dicho límite, devolveremos un mensaje de error 429 o too many requests al cliente, limitando así su capacidad de sobrecargar de peticiones nuestra aplicación. Dejaremos de registrar la ip pasados 60 segundos, así que podrá volver a intentarlo una vez pasado ese tiempo.
En el siguiente post, continuaremos mitigando el impacto de detectores de vulnerabilidades, web crawlers y bots gracias a Haproxy.
Una pregunta, como puedo usar ese limite de conexiones por servidor para que cuando sobrepase ese limite se pueda redirigir la carga a otros servidores de backup
Gracias