HAProxy reverse proxy : terminaison TLS, rate limiting et supervision Prometheus

Configurer HAProxy en frontal d’une boutique PrestaShop : terminaison TLS stable, rate limiting fin via stick‑tables et métriques Prometheus pour une supervision actionnable.

Interface de gestion réseau avec HAProxy et divers graphiques.

Table des matières :

  1. HAProxy reverse proxy en frontal d’une boutique : périmètre clair, limites assumées
  2. Terminaison TLS avec HAProxy 3.2 : SNI, chaînes, ALPN et propagation du schéma
  3. Choix crypto et performance : TLS 1.3, resumption, et compatibilités e‑commerce
  4. Rate limiting L4/L7 avec stick‑tables : protéger PrestaShop sans casser les vrais clients
  5. Exposer des métriques Prometheus depuis HAProxy : endpoint /metrics et hygiène de labels
  6. Supervision actionnable : erreurs TLS, 502/504, saturation, et corrélation avec le TTFB
  7. Exploitation en production : reload sans coupure, sockets d’admin, tests et garde‑fous

Dans la plupart des stacks e‑commerce auto‑hébergées (PrestaShop 8.x/9.x + PHP‑FPM 8.2/8.3 + MariaDB/MySQL + éventuellement Varnish/Redis), le point d’étranglement le plus fréquent n’est pas « Apache vs Nginx », mais la couche d’entrée : TLS, files d’attente, timeouts, protection anti‑abus et observabilité. C’est précisément le terrain d’un reverse proxy HAProxy correctement configuré.

Un point souvent sous‑estimé sur les boutiques B2C (France/UE notamment) : une part significative du trafic « légitime » arrive derrière des IP partagées (réseaux mobiles, entreprises, Wi‑Fi publics). Ça change la manière dont vous devez penser le rate limiting et la détection d’abus : on protège la boutique sans pénaliser un segment complet d’utilisateurs.

HAProxy reverse proxy en frontal d’une boutique : périmètre clair, limites assumées

Un reverse proxy est un composant placé côté serveur, qui termine les connexions clientes (TCP/TLS/HTTP) et relaie les requêtes vers un ou plusieurs backends (Nginx, Apache, PHP‑FPM via un webserver, microservices, etc.). Dans un contexte PrestaShop, ça sert à normaliser l’entrée (TLS, HTTP/2, headers), à répartir la charge, à appliquer des règles L7 (ACL) et à sortir des métriques exploitables.

HAProxy est souvent choisi parce qu’il est extrêmement efficace sur les workloads HTTP à fort débit et qu’il embarque des primitives de contrôle de trafic très concrètes (ACL, stick‑tables, health checks, retries, timeouts). La page officielle résume bien l’outil : « HAProxy is a free, very fast and reliable solution offering high availability, load balancing, and proxying for TCP and HTTP‑based applications » (HAProxy Technologies, documentation officielle : https://www.haproxy.org/).

  • Entrée HTTPS propre : politique TLS homogène, SNI multi‑domaines, HTTP/2, redirections.
  • Protection « avant backend » : limitation de débit, blocage ciblé, tarpit (ralentissement) sur patterns abusifs, garde‑fous sur timeouts.
  • Routage et isolation : séparer /api, backoffice, endpoints sensibles, voire multi‑boutiques par Host.
  • Observabilité pragmatique : logs structurés et métriques (Prometheus) orientées saturation/erreurs/latence.

Les limites sont à poser dès le départ : HAProxy n’est pas un CDN, et ce n’est pas un cache HTTP « drop‑in ». Vous ne remplacerez pas Varnish pour du cache agressif/ESI (cf. https://www.expertise-prestashop.fr/2026/05/22/varnish-cache-configuration-esi-pour-optimiser-le-cache-par-fragments/ et https://www.expertise-prestashop.fr/2026/06/24/cache-prestashop-varnish-redis-memcached-et-opcache-cote-serveur/). En revanche, HAProxy est un excellent « garde‑barrière » : terminaison TLS propre, rate limiting, routage fin, et observabilité (Prometheus) à faible friction.

Enfin, ne confondez pas « reverse proxy » et « WAF » : HAProxy peut filtrer, mais si votre besoin est une protection applicative complète (règles OWASP, signatures), cela peut impliquer une brique dédiée. L’objectif ici reste d’augmenter la résilience et la lisibilité du trafic entrant.

Terminaison TLS avec HAProxy 3.2 : SNI, chaînes, ALPN et propagation du schéma

La terminaison TLS consiste à déchiffrer HTTPS au niveau du reverse proxy, puis à relayer en HTTP vers les backends (sur réseau privé) ou en HTTPS interne si vous avez besoin de chiffrement de bout en bout. Le gain est double : (1) centraliser les certificats et la politique crypto, (2) éviter de multiplier les handshakes TLS côté backends (utile quand vous scalez horizontalement).

Sur HAProxy 3.2 (exemples valables sur Ubuntu 22.04/24.04, Debian 12, etc.), la terminaison se fait généralement via bind :443 ssl crt ... avec support SNI. Un point qui casse souvent en prod : la chaîne (fullchain) et la gestion multi‑domaines. En pratique, préférez un répertoire de certificats (un PEM par domaine, incluant cert + chaîne + clé), ou un bundle unique si votre CA le permet.

Deux détails opérationnels qui évitent des incidents récurrents :

  • Renouvellement/rotation : si vous utilisez Let’s Encrypt, standardisez un chemin de sortie stable (ex. /etc/haproxy/certs/shop.example.com.pem) et automatisez la concaténation fullchain + privkey dans un seul fichier PEM attendu par HAProxy, puis reload contrôlé.
  • SNI et « fallback » : si vous hébergez plusieurs domaines, prévoyez un certificat par défaut (un crt générique) pour éviter des erreurs de handshake si le SNI est absent (rare, mais ça arrive sur certains clients/robots).

Exemple minimaliste (à adapter) :

global
  log /dev/log local0
  maxconn 50000
  tune.ssl.default-dh-param 2048

defaults
  log global
  mode http
  option httplog
  timeout connect 5s
  timeout client  30s
  timeout server  30s

frontend fe_https
  bind :443 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  http-request set-header X-Forwarded-For %[src]
  http-request set-header X-Forwarded-Port 443

  # Exemple : routage PrestaShop + API
  use_backend be_prestashop if { hdr(host) -i shop.example.com }
  default_backend be_prestashop

backend be_prestashop
  balance roundrobin
  option httpchk GET /index.php
  http-check expect status 200
  server web1 10.0.10.11:8080 check
  server web2 10.0.10.12:8080 check

À ce stade, ajoutez généralement un frontal HTTP/80 minimal pour forcer HTTPS (et éviter les comportements divergents entre modules/robots) :

  • redirection 301 vers HTTPS ;
  • exception éventuelle pour /.well-known/acme-challenge/ si vous terminez l’ACME à cet endroit (sinon, ne l’ouvrez pas).

Ne négligez pas la propagation du schéma : PrestaShop (et beaucoup de modules) se base encore sur X-Forwarded-Proto pour générer des URLs, gérer les cookies Secure, et forcer certaines redirections. Si vous terminez TLS sur HAProxy, mais que le backend « croit » recevoir du HTTP, vous allez déclencher des boucles de redirection et/ou du mixed‑content. C’est le même sujet que les hardenings côté appli : HSTS, CSP, etc. (voir https://www.expertise-prestashop.fr/2026/07/08/http-security-headers-en-php-guide-csp-hsts-x-frame-options/).

Enfin, si vous avez des backends qui journalisent l’IP client, le sujet de l’IP réelle est central : derrière un reverse proxy, l’application ne voit plus src mais l’IP du proxy. Selon votre architecture, vous passerez soit par X-Forwarded-For, soit par le PROXY protocol (plutôt côté TCP). La bonne méthode dépend du backend et du niveau de confiance (ex. si vous êtes derrière un CDN, l’en‑tête X-Forwarded-For doit être accepté uniquement si la requête provient d’IP du CDN, sinon vous ouvrez la porte au spoofing).

Choix crypto et performance : TLS 1.3, resumption, et compatibilités e‑commerce

La politique TLS doit être explicite. Sur Internet en 2026, TLS 1.2 + TLS 1.3 sont la base raisonnable. L’objectif n’est pas de « cocher TLS 1.3 », mais de réduire les surfaces d’attaque et de stabiliser les performances sous charge (handshakes coûteux, CPU spikes, queueing). TLS 1.3 a aussi un intérêt très concret côté performance : le protocole réduit les allers‑retours nécessaires au handshake et simplifie la négociation.

Côté HAProxy, vous pouvez fixer les minimums et quelques options de sécurité :

global
  ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
  ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384
  ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
  tune.ssl.cachesize 200000

Quelques points concrets (et souvent contre‑intuitifs) :

  • Session resumption (tickets / cache) peut réduire la latence, mais les tickets peuvent compliquer certains modèles de rotation de clés. Si vous avez une exigence de PFS stricte ou des contraintes de conformité, documentez votre choix (no-tls-tickets vs tickets activés).
  • Certificats ECDSA vs RSA : un certificat ECDSA peut réduire le coût CPU du handshake côté serveur, mais il faut s’assurer que votre audience/compatibilité est acceptable (certains environnements anciens peuvent être plus sensibles). Dans l’e‑commerce, la compatibilité prime : on choisit des profils connus et on observe les erreurs réelles.
  • HTTP/2 via alpn h2,http/1.1 améliore le multiplexing côté navigateur, mais n’efface pas les problèmes de backend (verrous PHP, I/O DB). Si vos TTFB explosent, c’est rarement la faute d’HTTP/2 (voir https://www.expertise-prestashop.fr/2026/06/03/ttfb-prestashop-reduire-le-time-to-first-byte-sous-200-ms/).
  • Le goulot est souvent CPU au handshake (certificats RSA trop lourds, courbes, manque d’accélération), ou file descriptors/maxconn mal dimensionnés (cf. https://www.expertise-prestashop.fr/2026/07/02/prestashop-9-corriger-lerreur-too-many-open-files/). Dans ce cas, la supervision (Prometheus) vous dira rapidement si vous êtes en saturation côté front proxy plutôt que côté PHP.

Pour ancrer le sujet, gardez en tête la recommandation de l’IETF sur l’état de l’art TLS : « TLS 1.3 is the most recent version of the Transport Layer Security protocol » (RFC 8446, https://www.rfc-editor.org/rfc/rfc8446). Vous ne « sécurisez » pas une boutique en empilant des options ésotériques : vous sécurisez en restant compatible, en désactivant ce qui est obsolète, et en observant les erreurs réelles (handshake failures, unsupported ciphers) au lieu de spéculer.

Si vous cherchez un point de départ pragmatique (sans réinventer une politique crypto), l’outil de Mozilla est utile pour générer des profils cohérents et maintenus : https://ssl-config.mozilla.org/ (à adapter ensuite à vos contraintes réelles et à vos tests).

Rate limiting L4/L7 avec stick‑tables : protéger PrestaShop sans casser les vrais clients

Le rate limiting dans HAProxy repose en pratique sur les stick‑tables : des tables en mémoire qui associent une clé (souvent IP, ou IP+Host, ou IP+URL) à des compteurs/échantillons (taux de requêtes, connexions, erreurs, etc.). C’est très efficace pour traiter les attaques « basiques » (scraping, bots, bruteforce, attaques de cart) et pour limiter les endpoints qui déclenchent des requêtes SQL coûteuses.

Cas classique PrestaShop : la navigation à facettes et certains endpoints Ajax peuvent générer des rafales de requêtes et des patterns très stables (mêmes URLs, mêmes paramètres). PrestaShop n’embarque pas un mécanisme natif de throttling HTTP fin : vous finissez avec MySQL en sueur, du PHP‑FPM saturé, et des 504. Vous pouvez compléter avec fail2ban côté logs applicatifs (voir https://www.expertise-prestashop.fr/2026/07/08/prestashop-securite-bloquer-la-navigation-a-facettes-via-fail2ban/), mais HAProxy permet d’agir avant d’envoyer la requête au backend.

Exemple de limitation par IP (à adapter à votre trafic réel, et à tester en staging) :

frontend fe_https
  # ... bind TLS etc.

  # Table : taux de requêtes HTTP par IP sur 10s
  stick-table type ip size 200k expire 10m store http_req_rate(10s),conn_rate(10s),gpc0

  # Track IP
  http-request track-sc0 src

  # Endpoints sensibles (exemples)
  acl is_search  path_beg -i /recherche /search
  acl is_login   path_beg -i /connexion /login
  acl is_facets  url_reg  -i /.*(q=|/filter|/facettes|layered).*

  # Seuils : à calibrer avec des métriques (sinon vous rate-limit vos clients NAT)
  acl abuse_req_rate  sc_http_req_rate(0) gt 30
  acl abuse_conn_rate sc_conn_rate(0) gt 10

  # Réponse 429 sur abus ; vous pouvez différencier selon endpoint
  http-request deny deny_status 429 if abuse_req_rate is_facets
  http-request deny deny_status 429 if abuse_conn_rate is_login

Pour rendre ce mécanisme « business‑safe » (conversion), ajoutez une logique progressive plutôt qu’un blocage brutal partout :

  • Soft limit sur les endpoints non critiques : injecter un délai (tarpit) sur des patterns de scraping, au lieu de bannir immédiatement.
  • Hard limit uniquement sur des endpoints à fort coût (facettes, recherche) ou à risque (login), avec un 429 clair.
  • Exemptions ciblées : ne rate‑limitez pas agressivement les étapes de checkout si vos clients déclenchent plusieurs appels XHR légitimes (sinon vous fabriquez des paniers abandonnés).

Mini‑grille de calibration (exemple de départ, à mesurer et ajuster) :

Endpoint (ACL) Risque principal Limite indicative Action
is_facets DoS « lent » via URLs/paramètres 20–30 req / 10s / IP 429 ou tarpit
is_search charge DB + indexation 10–20 req / 10s / IP 429
is_login bruteforce / credential stuffing 5–10 connexions / 10s / IP 429 + hausse gpc0

Pièges habituels (et ils coûtent cher en conversion) :

1) NAT / mobile carriers / entreprises : beaucoup d’utilisateurs légitimes partagent une IP. Un rate limit « global par IP » peut pénaliser un réseau entier. Si vous êtes derrière un CDN/WAF, utilisez l’IP réelle (X‑Forwarded‑For) mais seulement si vous pouvez faire confiance à la source (liste d’IP du CDN + règle de réécriture).

2) Cardinalité : si vous commenez à « keyer » sur src+path+query, vous allez exploser la mémoire et rendre l’observabilité illisible. Restez sur des clés simples (IP, IP+Host) et isolez les endpoints via ACL.

3) Couplage au produit : ne faites pas porter à HAProxy la dette d’architecture applicative. Si vos endpoints déclenchent des requêtes SQL pathologiques, corrigez aussi l’amont (slow query log, index, caching). Sur PrestaShop, activez et exploitez le slow query log (voir https://www.expertise-prestashop.fr/2026/07/13/requetes-mysql-lentes-prestashop-activer-slow-query-log/) et dimensionnez le cache multi‑niveaux (voir https://www.expertise-prestashop.fr/2026/07/13/prestashop-soldes-optimiser-le-cache-multi-niveaux-et-ccc/).

Un scénario typique en production : pendant une campagne Ads, vous observez une hausse des requêtes sur /recherche et des URLs de filtres. HAProxy vous permet de contenir l’emballement (429 ciblés, tarpit) pendant que vous confirmez la cause réelle (requêtes lentes, index manquant, cache absent) — sans attendre que PHP‑FPM et MySQL s’effondrent.

Exposer des métriques Prometheus depuis HAProxy : endpoint /metrics et hygiène de labels

Prometheus fonctionne sur un modèle simple : des endpoints HTTP exposent des métriques au format texte, et Prometheus scrape périodiquement ces endpoints. Le point important côté design (et coût) est le modèle multidimensionnel : chaque combinaison de labels crée une série temporelle. Si vous laissez filer des labels dynamiques (URLs complètes, user‑agents, IDs), vous créez une explosion de cardinalité et vous perdez l’intérêt du monitoring.

HAProxy fournit un export Prometheus via un service interne prometheus-exporter. Vous créez un frontend dédié (souvent en local ou sur un réseau d’admin), et vous servez /metrics :

frontend fe_metrics
  bind 127.0.0.1:8404
  mode http
  http-request use-service prometheus-exporter if { path /metrics }

  # Optionnel : protéger l’endpoint
  acl allowed src 127.0.0.1 10.0.0.0/8
  http-request deny if !allowed

Sur un cluster Kubernetes ou une infra avec Prometheus centralisé, vous pouvez soit (a) scraper en local via un agent (node exporter + scrape config), soit (b) exposer 8404 sur un VLAN d’admin et restreindre par firewall. Si vous déployez déjà kube-prometheus-stack, l’approche est cohérente avec ce qui est décrit dans https://www.expertise-prestashop.fr/2026/07/08/prometheus-sur-kubernetes-ovhcloud-deployer-kube-prometheus-stack-avec-helm/.

Côté métriques utiles, vous voulez au minimum :

  • saturation : connexions actives, maxconn, files d’attente backend ;
  • qualité : taux de 4xx/5xx, retries, srv_abrt, hrsp_5xx ;
  • latence : temps de réponse backend, distribution si vous la calculez via histogrammes côté app.

Deux pratiques qui rendent les métriques HAProxy réellement exploitables :

  • Nommer vos frontends/backends avec une convention stable (ex. fe_https, be_prestashop, be_api, be_backoffice). Si les noms changent à chaque refactor, vos dashboards/alertes deviennent du bruit.
  • Éviter les backends « fourre‑tout » : si /api et la boutique partagent le même backend, vous perdez la capacité à isoler une saturation API d’un pic de navigation.

Évitez d’exporter des labels basés sur des URLs complètes ou des User‑Agents (cardinalité incontrôlable). Si vous avez besoin d’une vue par route, faites‑le au niveau applicatif (Symfony/PrestaShop) ou via un API gateway spécialisé (cf. https://www.expertise-prestashop.fr/2026/07/07/api-gateway-authentification-rate-limiting-et-routage-des-microservices/).

Supervision actionnable : erreurs TLS, 502/504, saturation, et corrélation avec le TTFB

Une supervision utile n’est pas « un dashboard de plus », c’est une capacité à répondre en 10 minutes à : est‑ce HAProxy, le backend web, PHP‑FPM, ou MySQL ? Sur PrestaShop, l’erreur la plus courante pendant les pics (soldes, campagnes ads) est un mélange de timeouts et de saturation backend. Le reverse proxy doit vous permettre d’isoler le symptôme et de déclencher un runbook.

Sur HAProxy, surveillez au minimum :

  • Handshake / TLS errors : hausse des SSL handshake failure dans les logs, corrélée à une rotation de certs ou à une politique crypto trop stricte.
  • HTTP 5xx côté proxy : 502 (backend reset), 503 (pas de serveur dispo), 504 (timeout). En e‑commerce, une hausse de 504 sur /order ou /payment est un incident, pas une métrique.
  • Queues : si qcur/qmax augmente sur vos backends, vous êtes en contention backend, même si HAProxy est « OK ».

Pour rendre ça actionnable, ajoutez des seuils simples et reliés à une décision d’exploitation. Exemples de questions à trancher rapidement :

  • Les 504 augmentent, mais les queues backend aussi → vous manquez de capacité backend (PHP‑FPM saturé, DB lente), ou vos timeouts sont trop agressifs.
  • Les 5xx montent sans queue → resets réseau, health checks instables, mauvais keep‑alive, crash backend.
  • Les connexions actives HAProxy touchent maxconn → HAProxy devient le goulot (FD, CPU handshake, tuning kernel), ou votre limite est volontaire et trop basse.

La corrélation la plus rentable est avec vos objectifs de performance (TTFB/LCP). Un HAProxy reverse proxy bien instrumenté vous montre si le délai vient (a) du client, (b) du proxy (saturation), (c) du backend. Ensuite seulement vous allez optimiser PHP‑FPM/OPcache/MySQL (voir https://www.expertise-prestashop.fr/2026/06/29/performance-prestashop-benchmarks-et-optimisation-php-fpm-opcache-mysql/ et https://www.expertise-prestashop.fr/2026/07/08/surveillance-prestashop-tableau-de-bord-seuils-et-reduction-des-fausses-alertes/).

Pour Grafana, partez d’un dashboard orienté exploitation (pas esthétique) : erreurs par code, latence par backend, saturation, health checks, et un panneau « top N hosts » si vous avez du multi‑tenant. Si vous n’avez pas de base Grafana standard, référez‑vous à https://www.expertise-prestashop.fr/2026/07/03/grafana-sur-ubuntu-installation-apt-et-configuration-initiale/.

Enfin, n’oubliez pas la couche logs : un format de log HAProxy incluant status, Tq/Tw/Tc/Tr/Tt (temps de queue/connexion/réponse/total) et le backend choisi est souvent la manière la plus rapide d’expliquer un incident à froid, et de relier un spike de 504 à une congestion backend plutôt qu’à « le réseau ».

Exploitation en production : reload sans coupure, sockets d’admin, tests et garde‑fous

En production, le risque n°1 n’est pas « une mauvaise option TLS », c’est un reload qui coupe des connexions ou une config qui ne démarre pas. Sur HAProxy 3.2, vous devez systématiquement valider la config avant reload : haproxy -c -f /etc/haproxy/haproxy.cfg. Si vous avez besoin d’une base sur le déploiement systemd, la structuration frontend/backend/ACL et les patterns propres à 3.2, vous avez déjà un socle ici : https://www.expertise-prestashop.fr/2026/06/22/haproxy-3-2-deploiement-systemd-configuration-frontend-backend-acl/.

Le reload « sans coupure » (graceful) repose sur le fait de démarrer un nouveau processus HAProxy qui reprend les sockets d’écoute, pendant que l’ancien termine les connexions existantes. Ça fonctionne bien si vos timeouts sont cohérents et si vous ne tuez pas brutalement le processus. Dans systemd, vérifiez ExecReload et la gestion du PID. Pour les infrastructures à fort trafic, documentez un runbook : fenêtre de reload, validation de conf, puis systemctl reload haproxy, puis contrôle des métriques (pas seulement systemctl status).

Pour piloter finement (sans ouvrir une interface web de stats publiquement), l’usage d’un socket d’admin est une bonne pratique : il permet de lire l’état, de mettre un serveur en maintenance, de vider une stick‑table, etc., tout en restant sur un canal local et auditable. L’idée n’est pas d’automatiser « à l’aveugle », mais d’avoir des leviers sûrs lors d’un incident (ex. isoler web2 si ses health checks flappent).

Enfin, testez vos hypothèses. Exemple concret : vous ajoutez du rate limiting pour réduire la charge pendant des pics, mais vous devez vérifier que (a) vous ne pénalisez pas des utilisateurs légitimes, (b) vous n’explosez pas la cardinalité métrique, (c) vous ne masquez pas un vrai problème backend (requêtes lentes, cache absent). C’est la même discipline que pour tout plan de charge e‑commerce : tests, seuils, et procédures (voir https://www.expertise-prestashop.fr/2026/06/18/prestashop-performance-monitoring-tests-de-charge-et-runbooks-soldes/ et https://www.expertise-prestashop.fr/2026/07/10/prestashop-pics-de-trafic-architecture-cloud-scalable-et-haute-disponibilite/).

Checklist courte avant mise en prod (ou avant une période type soldes) :

  • [ ] Politique TLS testée (navigateurs + robots), certificats/chaînes OK, SNI multi‑domaines validé
  • [ ] X‑Forwarded‑Proto et IP client (XFF/PROXY) cohérents côté backend
  • [ ] Timeouts alignés entre HAProxy, webserver et PHP‑FPM (sinon 504 « fantômes »)
  • [ ] Rate limiting limité aux endpoints coûteux, avec seuils mesurés (pas « au doigt mouillé »)
  • [ ] /metrics restreint (loopback/VLAN admin) et dashboards orientés incidents (queues/5xx/latence)

Si vous cherchez une règle simple : terminez TLS de façon stable, limitez les endpoints qui coûtent cher, et mesurez tout (erreurs, latence, saturation). Le reste (cache, DB, PHP) ne devient optimisable que lorsque votre HAProxy reverse proxy vous donne un signal fiable plutôt qu’un brouillard d’incidents.


À lire aussi