Protéger HAProxy consiste à décrire en ACL ce qu'il faut refuser, à compter
les requêtes de chaque client dans une stick-table pour limiter les abus, et à
ajouter des en-têtes de sécurité ; l'observer consiste à produire des journaux
structurés et à exposer ses métriques à Prometheus sur une interface qui n'est
pas publique. Cette leçon est la suite de la publication en HTTPS avec
HAProxy : elle reprend les gestes de protection et d'observation de la
formation, dans la syntaxe de HAProxy. Les exemples valent pour HAProxy
3.4.7, installé depuis haproxy.debian.net sur Debian 13.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »La leçon va de la règle qui refuse à la métrique qui mesure.
- Écrire une ACL et l'appliquer à une règle.
- Exiger une authentification sur une route et refuser des méthodes.
- Limiter le débit par client avec une stick-table.
- Ajouter des en-têtes de sécurité aux réponses.
- Exposer l'exporteur Prometheus sur une interface restreinte.
- Situer l'API d'exécution et ses risques.
Prérequis
Section intitulée « Prérequis »Cette leçon suppose que vous publiez déjà un service avec HAProxy.
- La publication en HTTPS et le rechargement sans coupure : Publier en HTTPS avec HAProxy.
- Les concepts de base de HAProxy : HAProxy.
- Le trajet d'une requête et la confiance accordée aux en-têtes : Publier un service web.
Comment refuser une requête avec une ACL ?
Section intitulée « Comment refuser une requête avec une ACL ? »Une ACL nomme une condition, et une règle http-request l'utilise pour
agir. Une ACL teste un élément de la requête : un chemin, une méthode, une
adresse source, un en-tête. La règle associée refuse, redirige ou modifie quand
la condition est vraie.
frontend https_in acl chemin_admin path_beg /admin acl reseau_interne src 10.0.0.0/8 http-request deny deny_status 403 if chemin_admin !reseau_interneCette règle répond 403 à tout accès à /admin qui ne vient pas du réseau
interne. Les ACL se lisent comme des phrases : nommez-les pour ce qu'elles
testent, et gardez en tête qu'une adresse source n'est fiable que si HAProxy est
le premier relais ; derrière un autre proxy, c'est l'adresse du relais que vous
verrez.
Comment exiger un mot de passe et refuser des méthodes ?
Section intitulée « Comment exiger un mot de passe et refuser des méthodes ? »Une route sensible s'authentifie avec une userlist et http-request auth,
et une méthode inutile se refuse par une ACL sur method. La userlist
déclare les comptes avec un mot de passe haché, jamais en clair. La règle
auth répond 401 tant que la condition http_auth n'est pas satisfaite.
userlist admins user ops password $5$Xk3pQ9aB$dCdsGkSjDndrErPudW5LAbbgWQkf5eMHpYsiK0QLek9
frontend https_in acl chemin_admin path_beg /admin http-request auth realm Administration if chemin_admin !{ http_auth(admins) } acl methode_ecriture method PUT DELETE http-request deny deny_status 405 if methode_ecritureLe hachage de l'exemple vient de openssl passwd -5 et correspond au mot de
passe Exemple-Ops-2026 : générez le vôtre. Un refus ne se prouve qu'en montrant
ce qui passe encore : curl -i sans identifiants sur /admin doit rendre
401, la même requête avec --user doit atteindre le backend, un
DELETE doit rendre 405 et un GET doit toujours aboutir. Une
configuration qui refuserait tout satisferait les trois premiers contrôles en
ayant simplement supprimé le service.
Comment limiter le débit avec une stick-table ?
Section intitulée « Comment limiter le débit avec une stick-table ? »Une stick-table garde en mémoire un compteur par clé, par exemple par adresse
source, et une règle refuse les clés qui dépassent un seuil. Il faut trois
éléments : déclarer la table et ce qu'elle compte, suivre chaque requête avec
track-sc, puis refuser quand le compteur dépasse la limite.
frontend https_in stick-table type ip size 100k expire 30s store http_req_rate(10s) http-request track-sc0 src http-request deny deny_status 429 if { sc_http_req_rate(0) gt 50 }La table compte ici le nombre de requêtes par adresse sur une fenêtre de dix
secondes, et la règle répond 429 au-delà de cinquante. Le seuil et la fenêtre
sont à choisir selon l'application : trop bas, ils bloquent des utilisateurs
légitimes ; trop haut, ils ne protègent de rien. Comme pour toute limitation par
adresse, ce que vous comptez doit correspondre au client réel.
http_req_rate(10s) est une moyenne glissante, pas un compteur qui repart de
zéro à intervalle fixe. Le manuel 3.4 écrit qu'elle rapporte « the average
HTTP request rate over that period ». Après une rafale, la cadence redescend
progressivement, et le client n'est servi à nouveau qu'une fois repassée sous
le seuil. Cette décroissance est lente : sur une fenêtre de dix secondes et un
seuil de 20, une rafale de 25 requêtes laissait encore une requête de contrôle
sur deux refusée treize secondes après la dernière. Une bonne limite
relâche donc d'elle-même, sans bannir, mais plus tard qu'on ne le croit. Enfin, la clé ne doit pas être une valeur que le client envoie :
un compteur clavé sur un en-tête est remis à zéro par celui qu'il devait limiter,
d'où le choix de src.
Quels en-têtes de sécurité ajouter ?
Section intitulée « Quels en-têtes de sécurité ajouter ? »Ajoutez des en-têtes de réponse qui réduisent la surface d'attaque côté
navigateur, avec http-response set-header. Ils disent au navigateur de ne
pas deviner le type d'un contenu, de ne pas laisser afficher la page dans un
cadre, de ne pas transmettre l'adresse d'origine et de n'utiliser que HTTPS.
http-response set-header X-Content-Type-Options nosniffhttp-response set-header X-Frame-Options DENYhttp-response set-header Referrer-Policy no-referrerhttp-response set-header Content-Security-Policy "default-src 'self'; frame-ancestors 'none'"http-response set-header Strict-Transport-Security "max-age=31536000"Vérifiez avec curl -I les en-têtes réellement reçus, pas ceux que vous
croyez avoir configurés : une règle placée dans le mauvais bloc, ou une réponse
d'erreur produite par HAProxy lui-même, peut ne pas les porter. Le contrôle
fiable porte sur une réponse venue du backend, pas sur une page d'erreur.
Comment produire des journaux exploitables ?
Section intitulée « Comment produire des journaux exploitables ? »HAProxy peut formater ses journaux en JSON, à condition que le frontend ait une
destination de journaux. Un format structuré se filtre et s'agrège sans
analyse de texte. Sans directive log sur le frontend ou héritée de la
section global, haproxy -c signale que le format est ignoré : c'est le
premier réflexe de diagnostic si les lignes n'apparaissent pas.
defaults mode http log global log-format "%{+json}o %(client_ip)ci %(status)ST %(bytes)B %(duration)Ta %(backend)b %(server)s"Chaque champ porte son nom, ce qui permet à un outil comme Loki ou Elasticsearch de les indexer sans règle d'extraction.
Comment exposer les métriques à Prometheus ?
Section intitulée « Comment exposer les métriques à Prometheus ? »HAProxy sert lui-même ses métriques au format Prometheus : l'exportateur est
compilé d'office dans le paquet 3.4.7 de haproxy.debian.net, donc il n'y a ni
compilation à faire ni exportateur séparé à installer. Il s'active par un
service interne, use-service prometheus-exporter, sur un frontend dédié qu'il
faut restreindre. Les métriques révèlent la topologie des backends et leur
état : elles n'ont pas à être joignables depuis Internet.
frontend metriques bind 127.0.0.1:8404 http-request use-service prometheus-exporter if { path /metrics } no logLiez ce frontend à l'adresse que Prometheus atteint réellement, jamais à
toutes les interfaces. N'y activez pas stats enable : cela publierait la page
de statistiques sans authentification, et cette page ne montre plus la
version depuis la 3.4 (stats show-version est désactivé par défaut) : lisez la
version avec haproxy -v.
Vérifiez d'abord le point de métriques avec
curl http://127.0.0.1:8404/metrics. La sortie doit contenir
haproxy_frontend_status et haproxy_server_status, ce dernier portant
la santé de chaque serveur de backend. Côté Prometheus, un scrape réussi se voit par une cible à l'état
up (page des cibles, ou l'API /api/v1/targets).
À quoi sert l'API d'exécution ?
Section intitulée « À quoi sert l'API d'exécution ? »L'API d'exécution est une socket de commande qui permet de lire l'état de
HAProxy et de le modifier à chaud, sans rechargement. On y interroge l'état des
serveurs, on désactive un serveur pour une maintenance, on consulte le contenu
d'une stick-table. Elle ne se publie jamais en réseau : une socket Unix aux
droits restreints, ou une écoute locale, suffit, parce que quiconque l'atteint
peut changer le comportement du proxy. Le paquet Debian en pose une,
/run/haproxy/admin.sock, en mode 660 et de niveau admin.
Le niveau du socket décide de ce qu'on peut défaire. Un socket de niveau
operator exécute déjà set table et clear table : il peut donc effacer
un blocage posé par une stick-table, par exemple avec
echo "clear table https_in key 192.0.2.10" | socat stdio /run/haproxy/admin.sock.
Réservez ces niveaux aux comptes qui doivent lever un blocage, et traitez
l'accès à la socket comme un droit d'administration.
Mettre en pratique : protéger puis observer avec HAProxy
Section intitulée « Mettre en pratique : protéger puis observer avec HAProxy »Deux labs se jouent dans l'ordre : le premier protège le frontend, le second observe avec Prometheus. Chacun se valide par un contrôle automatisé.
Le premier lab part d'un service publié par HAProxy dont la route /admin est servie à qui la demande, qui accepte un nombre illimité de requêtes par client, qui transmet DELETE et PUT au backend et dont les réponses ne portent aucun en-tête de sécurité. Il vous demande d'ajouter les en-têtes de sécurité, d'exiger des identifiants sur /admin, de refuser en 429 plus de 20 requêtes par tranche de 10 secondes et par adresse source, et de refuser DELETE et PUT. La validation joue dans les deux sens : chaque refus est vérifié avec la requête qui doit encore passer, et le service doit redevenir disponible une fois la fenêtre écoulée.
Le second lab part d'un service déjà publié par HAProxy, avec une instance Prometheus
prête à le surveiller. Le point de métriques ne renvoie aucune métrique, et
les deux interfaces de supervision, ce point de métriques et l'interface de
Prometheus, sont joignables depuis d'autres machines. Il vous demande de
configurer l'exporteur Prometheus, de limiter les deux interfaces à l'hôte et de
faire remonter à Prometheus une cible up ainsi que les métriques de santé du
backend, sans interrompre le service public.
À retenir
Section intitulée « À retenir »Protéger HAProxy, c'est refuser par ACL et limiter par stick-table ; l'observer, c'est des journaux structurés et des métriques sur une interface fermée.
- Une ACL nomme une condition,
http-request denyagit. userlistethttp-request authexigent des identifiants.- Une stick-table compte par clé,
track-scsuit, un seuil refuse ; le débit est une moyenne glissante qui redescend. http-response set-headerajoute les en-têtes de sécurité.- Le journal JSON exige une destination de journaux.
- Les métriques et l'API d'exécution restent sur l'hôte.
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Continuer le cours : Limiter les abus avec des stick-tables
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications