La correction est intégrée au TP (Voir les encadrés de couleur vert)
Ce que vous allez apprendre dans ce TP
- Lancer l'infrastructure multi-conteneurs
- Localiser et éditer le fichier principal
- Démarrer une instance HAProxy 3.4 avec une configuration de base
- Analyser les logs
- Comprendre les sections de configuration
- Comprendre l'importance de la modularité
- Apprendre à gérer l'inclusion de dossiers de configuration
- Comprendre l'importance de la différence entre reload et restart
- Configurer un frontend dédié à l'administration
- Tester l'accessibilité du tableau de bord de statistiques natif de HAProxy
- Configurer le frontend principal pour le trafic HTTP
- Configurer un backend par défaut
- Comprendre la répartition de charge : Round Robin, Least connection, ...
- Comprendre la notion de poids
- Comprendre la notion de X-FORWARD-FOR
- Comprendre la notion de HA
- Manipuler les ACL
- Configurer un check de niveau 7
- Configurer la recherche de pattern dans la sortie du check
- Limiter les connexions simultanées (Anti-DoS/DDoS)
- Se protéger contre les attaques lentes (Slowloris)
- Mettre en place un quota de requêtes (Rate Limiting)
- Identifier et filtrer les automates (Anti-bot/Scraping)
- Utiliser la terminaison silencieuse (Silent Drop) pour les flux interdits
Mise en place de l'infrastructure #
Ce que vous allez apprendre dans cette sectionDéploiement de 3 serveurs web, d'un serveur Nginx et d'un cluster HAProxy via Docker Compose.
- Lancer l'infrastructure multi-conteneurs
IMPORTANT : Vous devez lire cet article avant de commencer ce TP pour bien maîtriser les fondamentaux.
Nous vous recommandons aussi de suivre ces formations :. Mais cela n'est pas indispensable, car nous fournirons pour ce TP toutes les commandes pour ces produits.
- Docker : Pour mieux comprendre l'importance de la conteneurisation
- Prometheus : Pour mieux comprendre la notion de métriques et leurs gestions
- Opentelemetry : Pour mieux comprendre la notion de métriques et leurs gestions
- Grafana : Pour mieux comprendre la visualisation des données de télémétrie
Obtention des sources
Vous devez cloner les sources du projet depuis ce dépôt (repository)https://github.com/rousseltm/haproxy-formation.gitdans le dossier de votre choix.git clone https://github.com/rousseltm/haproxy-formation.gitMise en place de l'infrastructure
Pour tester nos configurations, on aura besoin d'une infrastructure minimale. Vous devez lancer les commandes suivantes pour la déployer sur Docker :cd haproxy-formation sudo docker compose -f compose-infra.yaml up -dAttention : Toutes les commandes
docker composedevront être lancées dans le dossierhaproxy-formation.
Prise en main de la configuration #
Ce que vous allez apprendre dans cette section
- Localiser et éditer le fichier principal
- Démarrer une instance HAProxy 3.4 avec une configuration de base
- Analyser les logs
- Comprendre les sections de configuration
- Comprendre l'importance de la modularité
- Apprendre à gérer l'inclusion de dossiers de configuration
- Comprendre l'importance de la différence entre reload et restart
Exploration de la structure de configuration et mise en place de la modularité.
Accéder au fichier de base haproxy.cfg
Le cœur de HAProxy réside dans son fichier de configuration principal : haproxy.cfg. Dans notre environnement Docker, ce fichier est monté en volume.Le fichier se situe dans
config/haproxy/haproxy.cfg. Vous pouvez l'ouvrir avec votre éditeur de texte habituel pour observer les sections déjà présentes.Démarrage de l'instance de base
Pour tester nos configurations, on aura besoin d'une infrastructure HAProxy 3.4 avec une configuration de base que l'on va modifier par la suite. Dans un premier temps, on va tester son fonctionnement avec la configuration de base avec la commande suivante :sudo docker compose up -dVérification du démarrage
L’objectif est d’apprendre à identifier les erreurs de configuration à travers les logs système et Docker et de vérifier l’absence d’erreurs dans les logs générés par HAProxy.Installation sur machine virtuelle ou machine physique : Les logs sont généralement disponibles dans
Avec la configuration fournie, vous pouvez rencontrer des erreurs comme :/var/log/haproxy.logou via la commande
Installation via Docker Compose (notre cas) : Utilisez la commande suivante pour consulter les logs de toutes les instances :journalctl -u haproxy
ou cette commande pour consulter ceux d'une instance en particulier (nom du conteneur 3 : haproxy-formation-haproxy-3)sudo docker compose logs -f haproxysudo docker logs <container_name>haproxy-1 | [ALERT] (1) : config : parsing [/usr/local/etc/haproxy/haproxy.cfg:71]: Missing LF on last line, file might have been truncated at position 32.
Vous devez comprendre le message et le corriger.L'erreur vous informe simplement qu'il manque un saut de ligne à la fin du fichier (LF).
BONNE PRATIQUE : Toujours tester vos configurations avant de relancer votre instance en production : option
-cL'importance de la modularité
À grande échelle, maintenir un fichier
haproxy.cfgmonolithique devient complexe et risqué. La modularité permet de séparer les responsabilités (ex. : un fichier par application, un pour le monitoring, un pour la sécurité, etc.), facilitant ainsi le déploiement continu, les revues de code et la limitation des erreurs humaines lors des mises à jour.
Par défaut, le service HAProxy est lancé avec l'option-f haproxy.cfg. Vous pouvez ajouter autant d'options-fque vous avez de fichiers, mais vous pouvez aussi utiliser la même option et passer un dossier en paramètre : HAProxy chargera tous les fichiers se terminant par.cfgdans ce dossier.
Attention à bien prendre en compte la dépendance entre les modules !
Dans notre cas, avec notre configuration Docker Compose, utilisez la commande suivante pour basculer vers l'utilisation du dossierconf.d(pensez à déplacer le fichier de conf dans ce dossier), qui se trouve au même niveau que le fichier haproxy.cfg. Les blocs de configuration des exercices suivants devront donc être placés dans un fichier.cfgde ce dossier, par exempleconfig/haproxy/conf.d/tp.cfg:sudo docker compose down; export HAPROXY_CONFIG=conf.d; sudo -E docker compose up -dRechargement de la configuration
Chaque modification du fichier nécessite une prise en compte par le moteur HAProxy.
Reload vs Restart : En production, n'utilisez jamais le restart car il coupe les connexions. Le Reload (signal HUP) permet de charger la nouvelle configuration sans aucune interruption de service.
Vous devez trouver la commande pour recharger votre serveur sans couper les connexions en cours via systemctl et via Docker.Pour recharger avec systemctl :
Pour recharger proprement avec Docker Compose (Reload) :sudo systemctl reload haproxy
Pour un redémarrage complet (Restart) :sudo docker compose kill -s HUP haproxysudo docker compose restart haproxyPour en savoir plus, consultez l'article sur les bonnes pratiques de configuration.
Gestion des Frontends #
Ce que vous allez apprendre dans cette section
- Configurer un frontend dédié à l'administration
- Tester l'accessibilité du tableau de bord de statistiques natif de HAProxy
- Configurer le frontend principal pour le trafic HTTP
Configuration des points d'entrée pour les statistiques et le trafic HTTP.
Point d'entrée pour l'administration
Créez un point d'entrée dédié au monitoring nommé 'admin'. Ce point d'entrée doit écouter sur le port 8404 (port par défaut). Vous devez activer l'interface de statistiques, définir la racine (/) comme URI d'accès et configurer un rafraîchissement automatique toutes les 5 secondes. Notez que vous pouvez réaliser cette configuration avec un blocfrontendou un bloclisten, le résultat sera identique.Comme nous avons basculé vers le chargement du dossier
conf.d, ajoutez cette configuration dans un fichier.cfgde ce dossier. Pour appliquer vos modifications, utilisez la commandeexport HAPROXY_CONFIG=conf.d; sudo -E docker compose restart haproxy(bien faire un reload en Production).Vous pouvez éditer le fichier de configuration HAProxy pour ajouter cette configuration :
Et ensuite, relancer le service.frontend admin bind :8404 stats enable stats uri / stats refresh 5sTest de l'accès aux statistiques
Après avoir configuré le frontend 'admin', vérifiez que l'interface de monitoring est bien opérationnelle. Vous pouvez utiliser votre navigateur ou une commande terminal pour tester l'accessibilité du service sur le port dédié.
Vérifiez l'accès en ouvrant l'URL suivante dans votre navigateur :
http://localhost:8404Vous pouvez également valider la connectivité avec
curl:curl http://localhost:8404Frontend HTTP
Configurez le frontend principal nommé 'http_in' pour recevoir le trafic web des utilisateurs. Il doit écouter sur le port 80 et rediriger par défaut toutes les requêtes vers le groupe de serveurs 'default' (qui sera créé par la suite).
frontend http_in bind :80 default_backend default
Gestion des Backends #
Ce que vous allez apprendre dans cette section
- Configurer un backend par défaut
- Comprendre la répartition de charge : Round Robin, Least connection, ...
- Comprendre la notion de poids
- Comprendre la notion de X-FORWARD-FOR
- Comprendre la notion de HA
Configuration des serveurs de destination pour traiter les requêtes.
Le Backend par défaut
Créez un groupe de serveurs nommé 'default'. Ce backend sera utilisé pour traiter les requêtes ne correspondant à aucune règle spécifique. Il doit fonctionner en mode HTTP, utiliser l'algorithme 'roundrobin' et pointer vers le serveur 'web1'. Configurez une règle pour que ce backend serve systématiquement le fichier 'default.html'.
backend default mode http balance roundrobin # Réécriture du chemin pour afficher la page de maintenance http-request set-path /default.html # Déclaration des nœuds applicatifs server web1 web1:80 checkReload à chaud via fichier de conf
Ouvrez votre interface de statistiques (port 8404). Vous devriez normalement voir 1 serveur actif dans le backend default.
L'objectif est d'ajouter le serveur web2 à ce pool à chaud, c'est-à-dire sans redémarrer le conteneur HAProxy, afin de préserver les connexions en cours. Les étapes :- Voir la date de création des conteneurs HAProxy : L'information est dans la colonne 'CREATED'
sudo docker compose ps haproxy - Vous devez éditer le fichier pour ajouter le second serveur et recharger le service :
sudo docker compose kill -s HUP haproxy - Vous devez vérifier dans l'interface que le nouveau serveur est bien présent et que la date de création du conteneur n'a pas changé
1. Ajoutez le serveur web2 dans le bloc
backend defaultde votre fichier de configuration chargé par HAProxy:server web2 web2:80 check2. Pour recharger la configuration sans redémarrer le conteneur, envoyez un signal de rechargement (SIGHUP) au processus HAProxy :
sudo docker compose kill -s HUP haproxyVérifiez sur le dashboard de statistiques : le backend default doit maintenant afficher 2 serveurs sans que l'Uptime du service n'ait été réinitialisé.
- Voir la date de création des conteneurs HAProxy : L'information est dans la colonne 'CREATED'
Reload à chaud via socat
HAProxy dispose d'une Runtime API accessible via une socket Unix. Elle permet de modifier l'état du load balancer (poids, état des serveurs, ajout dynamique) sans aucun rechargement.Pour inspecter l'état interne ou passer des commandes directement dans votre conteneur, connectez-vous au shell via :
sudo docker exec -it <nom_du_conteneur> sh
Pour utiliser l'API, vous devez avoir activé la socket dans la section global de la configuration chargée par HAProxy :stats socket /tmp/admin.sock mode 600 level adminRecommandation de lecture : Pour approfondir la gestion dynamique des backends et des serveurs via la Runtime API, consultez notre article dédié : HAProxy : Ajout et suppression dynamique de backends.
En ajoutant, vous devez voir le serveur apparaitre dans votre page de stats
Mais comme vous avez peu le constater la commande socat est une commande locale donc il faut la jouter sur l'ensemble des instances de votre cluster HAProxy. De plus, comme indiqué dans la documentation, ajouter un serveur ne suffit pas pour qu'il reçoive le trafic, il faut l'activer ...1. Connectez-vous au conteneur HAProxy :
docker exec -it <nom_du_conteneur> sh2. Utilisez socat pour envoyer la commande d'ajout au moteur :
echo "add server default/web3 web3:80 check" | socat stdio /tmp/admin.sock3. Par défaut, un serveur ajouté dynamiquement est en mode maintenance. Activez-le :
echo "enable server default/web3" | socat stdio /tmp/admin.sock4. Il faut aussi activer le healthcheck :
echo "enable health default/web3" | socat stdio /tmp/admin.sockVérifiez sur le dashboard : le serveur web3 apparaît instantanément. Mais attention à socat qui ne gère pas la persistence et a une exécution locale
Le Backend web_servers
Créez un groupe de serveurs nommé 'web_servers'. Ce backend doit fonctionner en mode HTTP et utiliser l'algorithme de répartition 'least connection' avec chaque backend qui a un poids qui correspond à son id de serveur. Vous devez également ajouter une règle pour transmettre l'adresse IP réelle du client au backend via l'en-tête 'X-Real-IP' et déclarer les 3 nœuds applicatifs (web1, web2, web3) sur le port 80 avec une vérification de santé (check). Enfin, mettez à jour le frontendhttp_inpour envoyer le trafic par défaut vers ce backend.
frontend http_in bind :80 default_backend web_servers backend web_servers mode http balance leastconn http-request set-header X-Real-IP %[src] # Déclaration des 3 nœuds applicatifs du cluster server web1 web1:80 weight 1 check server web2 web2:80 weight 2 check server web3 web3:80 weight 3 checkScaling de HAProxy
Le passage à l'échelle horizontal (scaling) consiste à multiplier les instances de HAProxy pour garantir la haute disponibilité (HA). Dans une architecture réelle, avoir une seule instance de load balancer crée un 'Single Point of Failure' (SPOF) : si HAProxy tombe, toute l'application est inaccessible, même si les serveurs web sont sains. En environnement Docker, le scaling permet de répartir la charge réseau et d'assurer une continuité de service lors des mises à jour (rolling updates). Vous devez lancer la commande Docker Compose avec le paramètre--scale haproxy=3pour faire passer le nombre d'instances HAProxy à 3.Note : Multiplier le nombre de nœuds HAProxy ne suffit pas à le mettre en haute disponibilité. Il faut qu'il dispose d'une VIP : dans notre cas, c'est Nginx qui fera le load balancing pour assurer une haute disponibilité complète.
Pour passer votre point d'entrée à l'échelle dans le monde Docker sans modifier votre fichier de configuration
compose.yml, nous utilisons le paramètre d'exécution--scale:Déploiement : Appliquez la nouvelle topologie :
sudo -E docker compose up -d --scale haproxy=3Pourquoi est-ce important ?
- Résilience : Si un conteneur HAProxy plante, les autres instances continuent de répondre.
- Maintenance à chaud : Vous pouvez redémarrer ou mettre à jour une instance sans interrompre le trafic global.
- Performance : En production, ces instances seraient réparties sur différents nœuds physiques (via Docker Swarm ou Kubernetes), ce qui permettrait d'absorber des débits réseau massifs.
Synchronisation des sessions avec le 'Peering'
Dans un cluster HAProxy haute disponibilité, un basculement entre deux nœuds peut provoquer la perte des informations de persistance si chaque instance conserve ses données localement. Pour éviter ce problème, HAProxy intègre un mécanisme natif appelé Peers qui permet de répliquer en temps réel le contenu des Stick Tables entre plusieurs serveurs HAProxy. Cette fonctionnalité garantit que les informations de session, les compteurs de limitation de débit (Rate Limiting), les détections d'abus ou encore les données d'affinité client restent cohérentes après un failover.IMPORTANT : Le peering ne synchronise pas les sessions applicatives (PHP, Java, .NET, etc.). Il réplique uniquement les données stockées dans les Stick Tables HAProxy. Pour partager les sessions applicatives, il est recommandé d'utiliser une solution externe comme Redis ou Memcached.
Que peut-on synchroniser avec les Peers ?
- Persistance de session : maintien de l'affinité entre un client et son serveur backend.
- Rate Limiting : partage des compteurs de requêtes entre les nœuds HAProxy.
- Protection contre les abus : détection distribuée des attaques ou comportements suspects.
- Tracking utilisateur : conservation d'informations liées aux clients même après un basculement.
Les Peers sont particulièrement utiles dans les architectures utilisant Keepalived ou VRRP où une adresse IP virtuelle peut migrer d'un HAProxy à un autre.
Bonnes pratiques :
Vous devez ajouter une section pour le partage des sessions nommée 'haproxy_cluster' et qui utilise les trois serveurs HAProxy haproxy-formation-haproxy-1/2/3 sur le port par défaut. Vous devez donc activer ce partage de session dans le backend 'web_servers' pour une taille de 100k pour une expiration après 30m et se basant sur l'IP source du visiteur.- Utilisez un réseau dédié ou isolé pour les échanges de peering afin d'éviter les interférences avec le trafic utilisateur.
- Vérifiez que les ports utilisés pour les Peers sont accessibles entre les nœuds du cluster.
- Conservez une définition identique de la section
peerssur l'ensemble des serveurs HAProxy. - Surveillez l'état de synchronisation via la Runtime API ou la page de statistiques HAProxy.
- Pour les applications stateful, privilégiez malgré tout une externalisation des sessions dans Redis afin d'éviter toute dépendance au load balancer.
Chaque membre du cluster doit déclarer la même section
peersavec la liste complète des nœuds participant à la réplication. Ensuite, les Stick Tables doivent être associées à ce groupe de Peers afin que leur contenu soit automatiquement synchronisé.peers haproxy_cluster peer haproxy1 haproxy-formation-haproxy-1:1024 peer haproxy2 haproxy-formation-haproxy-2:1024 peer haproxy3 haproxy-formation-haproxy-3:1024 backend web_servers # Table synchronisée entre tous les HAProxy stick-table type ip size 100k expire 30m peers haproxy_cluster # Affinité basée sur l'adresse IP source stick on src # L'ancienne configuration mode http balance leastconn http-request set-header X-Real-IP %[src] server web1 web1:80 weight 1 check server web2 web2:80 weight 2 check server web3 web3:80 weight 3 check
Routage avancé avec ACL #
Ce que vous allez apprendre dans cette section
- Manipuler les ACL
- Configurer un check de niveau 7
- Configurer la recherche de pattern dans la sortie du check
Rediriger les requêtes commençant par /api vers le serveur 2.
Modification ACL
Le routage intelligent permet de diriger le trafic vers différents backends selon des critères précis. Dans cet exercice, vous devez reconfigurer HAProxy pour qu'il identifie les requêtes destinées à l'API (commençant par le chemin/api) et les envoie exclusivement vers le backend secure_servers qui contient les serveurs du service web mais uniquement de la 2e à la 10e occurrence. Le trafic restant doit continuer à être distribué par le backend par défaut.Par défaut, HAProxy va faire des tests de niveau 4 (TCP - IP:PORT) mais vous devez modifier le backend pour faire un test de vie de niveau 7 (HTTP - page web) qui vérifie que la page 'secure.html' retourne bien la chaîne 'Service\ '

Voici un exemple de configuration (il est conseillé de le dispatcher en plusieurs fichiers) avec un bloc pour le frontend, la résolution des services docker et un pour le backend
frontend http_in bind *:80 # On définit une ACL qui vérifie si le chemin commence par /api acl is_api path_beg /api # On demande à HAProxy d'utiliser un backend spécifique si l'ACL est vraie use_backend secure_servers if is_api default_backend web_servers resolvers docker # DNS interne Docker (permet resolution des noms de containers) nameserver dns 127.0.0.11:53 # Nombre de tentatives en cas d'echec DNS resolve_retries 3 # Timeout global pour une requete DNS timeout resolve 1s # Temps d'attente entre deux tentatives de resolution timeout retry 1s # Duree pendant laquelle une resolution est consideree valide # Important pour eviter les re-resolutions trop frequentes hold valid 10s backend secure_servers # Healthcheck HTTP personnalise option httpchk GET /secure.html # Verifie que la reponse contient bien 'Service' http-check expect string Service\ # Pool dynamique securise server-template web 2-10 web:80 check resolvers docker init-addr libc,noneWhitelisting des IP
Le filtrage par adresse IP est un pilier de la sécurité. Vous devez maintenant restreindre l'accès au dashboard de statistiques (port 8404) pour n'autoriser que les sources internes qui ont besoin : dans notre cas le serveur prometheus (dns prometheus dans docker) et les administrateurs.Whitelisting vs Blacklisting :
HAProxy est compatible avec les deux approches via ses règles d'ACL.
- Whitelisting (liste blanche) : Stratégie 'Default Deny'. On bloque tout par défaut et on n'autorise que les sources connues. C'est l'approche la plus robuste pour la sécurité.
Cas d'usage : accès à une console d'administration, API interne réservée à des partenaires, restriction d'accès aux IP d'un VPN d'entreprise. - Blacklisting (liste noire) : Stratégie 'Default Allow'. On laisse passer tout le trafic sauf les IP identifiées comme malveillantes.
Cas d'usage : blocage de bots connus (scrapers), protection temporaire contre une IP réalisant une attaque par force brute, ou Geo-blocking (blocage de régions entières).
En environnement réel, n'oubliez pas d'ajouter les IP de vos passerelles VPN ou de vos bureaux. Dans notre infrastructure de TP, les services internes Docker utilisent le sous-réseau du projet ; on l'autorise donc pour conserver l'accès depuis Prometheus et Nginx d'administration. Voici comment appliquer ce filtrage sur le frontend des statistiques :
frontend admin bind :8404 # Définition de l'ACL basée sur l'IP source (src) acl allowed_monitors src nginx-admin prometheus # On refuse l'accès si l'IP n'est pas autorisée http-request deny if !network_allowed stats enable stats uri / stats refresh 5sAstuce de factorisation : Si vous avez une liste d'IP que vous souhaitez réutiliser dans plusieurs frontends, évitez de les copier-coller. Utilisez un fichier externe (ex. :
/etc/haproxy/whitelist.lst) contenant une IP ou un CIDR par ligne. Votre ACL devient alors simple et centralisée :acl network_allowed src -f /etc/haproxy/whitelist.lst- Whitelisting (liste blanche) : Stratégie 'Default Deny'. On bloque tout par défaut et on n'autorise que les sources connues. C'est l'approche la plus robuste pour la sécurité.
Sécurité et Durcissement #
Ce que vous allez apprendre dans cette section
- Limiter les connexions simultanées (Anti-DoS/DDoS)
- Se protéger contre les attaques lentes (Slowloris)
- Mettre en place un quota de requêtes (Rate Limiting)
- Identifier et filtrer les automates (Anti-bot/Scraping)
- Utiliser la terminaison silencieuse (Silent Drop) pour les flux interdits
Protection du cluster contre les abus et les attaques réseau.
Protection contre le DoS et le DDoS
Configurez le frontendhttp_inpour limiter chaque IP source à un maximum de 15 connexions TCP simultanées (couche 4). Une fois la configuration appliquée, tentez d'ouvrir plusieurs connexions en parallèle pour vérifier que HAProxy rejette les suivantes.Vérification : Simulez une charge avec une boucle shell pour ouvrir de nombreuses connexions en arrière-plan :
Regardez vos logs HAProxy ou le dashboard : les connexions au-delà de 15 doivent être rejetées immédiatement.for i in $(seq 1 20); do curl -s http://localhost & doneDoS vs DDoS : quelle différence ?
- DoS (Denial of Service) : l'attaque provient d'une seule machine. HAProxy peut facilement la bloquer en limitant les connexions par IP.
- DDoS (Distributed DoS) : l'attaque provient de milliers de sources (botnet). Bloquer une IP ne suffit plus, car le trafic est distribué.
- Défense en profondeur : pour les attaques volumétriques massives (couches 3 et 4), utilisez des services de protection Cloud (Cloudflare, AWS Shield) en amont.
- Filtrage couche 7 : utilisez HAProxy pour identifier des signatures d'attaque spécifiques dans les en-têtes ou les URL via les ACL.
- Stick Tables : elles restent essentielles pour limiter l'impact de chaque nœud du botnet sur vos ressources applicatives.
Mode opératoire :
- Modifiez le frontend
http_inexistant pour intégrer le suivi des connexions :
frontend http_in bind :80 # Création de la table de suivi stick-table type ip size 100k expire 30s store conn_cur # Suivi de l'IP source tcp-request connection track-sc0 src # Rejet au-delà de 15 connexions tcp-request connection reject if { sc0_conn_cur gt 15 } default_backend web_servers2. Rechargez HAProxy.
Protection contre le Slowloris
L'attaque Slowloris sature le serveur en envoyant des en-têtes HTTP très lentement. Implémentez une protection en limitant le temps de réception des en-têtes à 5 secondes.Simulation d'attaque : Lancez cette commande avant la configuration (la connexion restera bloquée), puis après (HAProxy coupera la connexion après 5 s) :
Explication des paramètres :curl -X GET "http://localhost:80/" \ -H "X-Slow: $(head -c 5000 < /dev/zero | tr '\0' 'A')" \ --limit-rate 1 \ --verbose-H "X-Slow: ...": génère un en-tête massif de 5000 octets (viaheadettr) pour forcer un envoi long.--limit-rate 1: bride l'envoi à 1 octet/s. Sans protection, la connexion resterait ouverte plus d'une heure.--verbose: permet d'observer en direct le moment exact où HAProxy interrompt la session.
Recommandations de HAProxy (Lire l'article officiel) : Pour une protection optimale, HAProxy préconise de combiner plusieurs réglages :
timeout http-request 5s: limite le temps d'attente des en-têtes (défense principale).timeout http-keep-alive 1s: libère rapidement les slots de connexion inactifs.maxconn: limite le nombre global de connexions pour protéger les descripteurs de fichiers du système contre l'épuisement.
Mode opératoire :
- Dans la section
defaults(ou le frontend), ajoutez la directive de timeout :
defaults # Coupe la connexion si les en-têtes mettent plus de 5 s à arriver timeout http-request 5s # timeout http-keep-alive 1s # maxconn 100002. Rechargez HAProxy et relancez la commande de simulation. Vous devriez voir un message
Empty reply from serverou une fermeture de socket après environ 5 secondes.Limiter les requêtes (Rate Limiting)
Mettez en place un quota de 50 requêtes maximum toutes les 10 secondes par IP. Testez le dépassement du seuil et vérifiez que HAProxy retourne bien un code d'erreur HTTP 429.Vérification : Exécutez une rafale de requêtes curl pour saturer le quota :
Vous devez observer des réponsesfor i in $(seq 1 60); do curl -I http://localhost; doneHTTP/1.1 429 Too Many Requestsaprès la 50e requête.Mode opératoire :
- Mettez à jour la stick-table du frontend
http_inpour suivre à la fois les connexions en cours et le débit de requêtes (http_req_rate) :
frontend http_in bind :80 # On conserve conn_cur et on ajoute le stockage du débit sur 10s stick-table type ip size 100k expire 30s store conn_cur,http_req_rate(10s) tcp-request connection track-sc0 src tcp-request connection reject if { sc0_conn_cur gt 15 } # Suivi au niveau HTTP (sc1) http-request track-sc1 src # Blocage avec code 429 (Too Many Requests) http-request deny deny_status 429 if { sc1_http_req_rate gt 50 } default_backend web_servers2. Rechargez la configuration.
- Mettez à jour la stick-table du frontend
Modules Anti-bot et Détection du scraping
Bloquez les aspirateurs de données (scrapers) et les bots malveillants en identifiant leurs signatures User-Agent suspectes.Simulation de bot : Tentez d'accéder au site en simulant un bot connu via curl :
curl -I -H "User-Agent: Googlebot-Scraper" http://localhost/Mode opératoire :
- Ajoutez ces ACL et cette règle dans le frontend
http_inexistant, en conservant les protections déjà configurées :
# Détection de mots-clés dans le User-Agent (insensible à la casse) acl is_bot hdr_sub(user-agent) -i bot crawler scraper spider # Rejet des requêtes identifiées comme bots http-request deny deny_status 403 if is_bot2. Rechargez HAProxy et vérifiez que votre requête curl avec l'en-tête suspect est désormais rejetée par un code 403.
- Ajoutez ces ACL et cette règle dans le frontend
Terminaison silencieuse de requête
Le 'Silent Drop' est une technique de défense avancée : au lieu d'envoyer un code d'erreur (403/429) qui confirme au pirate l'existence d'une protection, HAProxy ignore simplement la requête. L'attaquant gaspille ses ressources à attendre une réponse qui ne viendra jamais.Vérification : Testez l'accès à un chemin interdit et constatez que curl reste en attente (hang) jusqu'au timeout :
curl -v http://localhost/admin/configMode opératoire :
- Ajoutez l'action
silent-dropdans le frontendhttp_inexistant pour les chemins ou flux interdits :
acl is_forbidden path_beg /admin # Fermeture de la connexion sans envoyer le moindre bit de réponse http-request silent-drop if is_forbidden2. Rechargez la configuration. Le client ne recevra aucune donnée (pas même un TCP RST), ce qui est particulièrement efficace contre les scanners automatiques.
- Ajoutez l'action
Observabilité #
Mise en place du monitoring, de l'exposition des métriques et de la télémétrie.
Stats Dashboard
Vérifiez que le point d'entrée d'administration configuré plus tôt expose toujours le dashboard de statistiques sur la racine du port 8404.
frontend admin bind :8404 stats enable stats uri / stats refresh 5sPrometheus : Exposition des métriques
Configurez HAProxy pour exposer les métriques de performance au format Prometheus sur l'URI/metrics. Cela permet à un serveur Prometheus de scraper l'état du load balancer.Vérification : Testez la récupération des métriques via curl :
Vous devriez voir défiler les métriques au format texte brut (HELP et TYPE).curl http://localhost:8404/metricsMode opératoire :
- Dans votre bloc
frontend admin, utilisez la directivehttp-request use-service:
frontend admin bind :8404 stats enable stats uri / stats refresh 5s # Exposition des métriques pour Prometheus # Cette règle intercepte les requêtes sur l'URI '/metrics' et renvoie le format Prometheus http-request use-service prometheus-exporter if { path /metrics }2. Rechargez la configuration. HAProxy sert désormais les métriques sur le même port que le dashboard.
- Dans votre bloc
Prise en charge d'OpenTelemetry (OTel)
Configurez l'exportation native de données de télémétrie vers un collecteur OpenTelemetry.Note : La prise en charge native d'OpenTelemetry est disponible à partir de la version 3.4 de HAProxy.
Mode opératoire :
- Déclarez l'exportateur OTel dans la section
global:
global otel-exporter my-collector endpoint otel-collector:43172. Activez l'envoi des traces dans votre frontend pour propager le contexte :
frontend http_in http-request otel-send-trace- Déclarez l'exportateur OTel dans la section
Niveau de difficulté : ●●●○○ (3/5)
Glossaire de la formation
ACL (Access Control List)
Liste de contrôle d'accès définissant les permissions accordées sur des ressources. Dans HAProxy, les ACL sont des conditions flexibles permettant de ...
Backend
Section de la configuration HAProxy définissant un pool de serveurs cibles vers lesquels le trafic est redirigé. C'est ici que l'on configure l'algori...
Frontend
Section de la configuration HAProxy qui définit comment les requêtes sont reçues du côté client (adresse IP, port, certificats SSL) avant d'être envoy...
GSLB (Global Server Load Balancing)
Technique de répartition de charge à l'échelle mondiale, utilisant généralement le DNS pour diriger les utilisateurs vers le datacenter le plus proche...
HAProxy
Logiciel de load balancing et de proxying haute performance pour TCP et HTTP. HAProxy est le standard de l'industrie pour la gestion de trafic à très ...
Health Check
Mécanisme automatisé permettant au load balancer de tester périodiquement la disponibilité des serveurs afin d'exclure temporairement ceux qui sont en...
Load Balancing
Dispositif qui distribue le trafic applicatif sur un ensemble de serveurs afin d'optimiser l'usage des ressources, de minimiser les temps de réponse e...
SSL Offloading
Processus consistant à déléguer le déchiffrement du trafic HTTPS au load balancer pour libérer de la puissance CPU sur les serveurs d'application.
Stickiness
Mécanisme garantissant qu'un utilisateur est systématiquement redirigé vers le même serveur backend durant toute sa session, indispensable pour les ap...
Slowloris
Type d'attaque par déni de service (DoS) qui consiste à ouvrir de nombreuses connexions HTTP et à les maintenir ouvertes le plus longtemps possible en...
DoS / DDoS
Attaque visant à rendre un service indisponible en submergeant le serveur ou le réseau de trafic. On parle de DDoS (Distributed Denial of Service) lor...
SSL / TLS
Protocoles de sécurisation des échanges sur internet. TLS (Transport Layer Security) est le successeur moderne de SSL (Secure Sockets Layer). Ils perm...
Articles recommandés
Visualiser votre infrastructure avec HAProxy Topology Visualizer
Apprenez à utiliser HAProxy Topology Visualizer pour transformer vos fichiers haproxy.cfg complex...
HAProxy dans Kubernetes : L'Ingress Controller Haute Performance
Découvrez en profondeur l'intégration de HAProxy dans Kubernetes. Architecture Direct-to-Pod, opt...
Gestion des certificats SSL/TLS avec Let's Encrypt et ACME
Apprenez à automatiser la génération et le renouvellement de vos certificats SSL/TLS avec Let's E...
Maîtriser les ACLs dans HAProxy : Le Guide Complet
Guide complet sur les ACLs HAProxy : apprenez à configurer le routage intelligent, le contrôle d'...
HAProxy comme Ingress Controller Kubernetes : Le Guide de Production
Découvrez comment utiliser HAProxy comme Ingress Controller dans Kubernetes. Architecture Direct-...
Nouveautés HAProxy : OpenTelemetry, JWT Natif, et Optimisations de Performance
Explorez les dernières innovations de HAProxy : prise en charge native d'OpenTelemetry pour l'obs...
Le Load Balancing : Principes, Algorithmes et Cas d'usage
Découvrez le fonctionnement de la répartition de charge (Load Balancing), son rôle dans la haute ...
Anatomie de la configuration HAProxy, Clustering et Haute Disponibilité
Comprendre la structure d'un fichier haproxy.cfg : sections Global, Defaults, Frontend, Backend e...
Maîtriser les ACLs dans HAProxy
Guide complet sur les ACLs HAProxy : apprenez à configurer le routage intelligent, le contrôle d'...
Sécurité et SSL avec HAProxy
Guide complet sur la terminaison SSL, le chiffrement des flux et la sécurisation du serveur HAProxy.
Monitoring et Statistiques dans HAProxy
Comment activer le tableau de bord de statistiques natif et exposer des métriques pour Prometheus.
Persistance de session (Stickiness)
Comprendre comment garantir qu'un utilisateur reste sur le même serveur backend durant toute sa s...
Health Checks et Haute Disponibilité
Comment HAProxy détecte les pannes et gère le basculement automatique vers les serveurs sains.
Installation de HAProxy
Guide complet pour installer HAProxy sur les serveurs Linux (Debian, RedHat) et via des environne...
L'écosystème HAProxy : De l'Open Source à HAProxy One
Comprendre les différences, avantages et interconnexions entre HAProxy OSS, Enterprise, Fusion, E...
Bonnes Pratiques HAProxy : Optimisation, Sécurité et Haute Disponibilité
Découvrez les meilleures pratiques pour configurer HAProxy afin d'assurer performance, sécurité e...
Aide-mémoire HAProxy : Les commandes essentielles
Un guide pratique regroupant toutes les commandes indispensables pour installer, gérer, tester et...
HAProxy : Ajout et suppression dynamique de backends
Découvrez comment utiliser la Runtime API de HAProxy pour créer, configurer et supprimer des back...
ACME : Le guide du déploiement SSL/TLS automatisé
Comprendre le protocole ACME, ses avantages et comment configurer le renouvellement automatique d...
HAProxy : Guide détaillé des directives de configuration
Une exploration complète des directives essentielles de HAProxy : de bind à http-check, apprenez ...