guest@6admin.io:~$

Haproxy : le reverse proxy qui a pris la suite de Pound

Le blog parlait de Pound en 2008 : un reverse proxy très light, qui dépose le TLS et balance vers un pool. Pound fait ce travail avec l’élégance du minimal, mais dès qu’il faut router sur le contenu (un Host vers un cluster, une URL vers un backend spécifique, une session collante), on fait un pas au-dessus: haproxy 1.3, de Willy Tarreau, en cours de stabilisation vers la 1.4.

Le bloc qui dit tout

frontend web
    bind *:80
    mode http
    acl is_app    hdr(host) -i app.domain.tld
    acl is_static path_beg /static/
    use_backend app      if is_app
    use_backend statics  if is_static
    default_backend app

backend app
    mode http
    balance roundrobin
    option httpchk HEAD /health
    server web1 192.168.10.11:8080 check inter 5s fall 2 rise 2
    server web2 192.168.10.12:8080 check inter 5s fall 2 rise 2

backend statics
    mode http
    balance source
    server s1 192.168.10.21:80

Le mode tcp et le mode http: en TCP, haproxy est un répartiteur bête et méchant (TLS pass-through, n’importe quel protocole); en HTTP, il parse la requête et routera sur ce qu’elle contient. Les ACL font le reste: hdr(host), path_beg et une grammaire d’opérateurs qui rend la conf lisible, ce que Pound ne proposait pas.

Ce qu’il fait que Pound ne fait pas

  • Les health checks par backend (option httpchk): un serveur qui ne répond plus est sorti du pool en deux probes, pas à la première timeout client;
  • Les sessions collantes (balance source ou les cookies en mode http), ce que le générique “roundrobin à l’aveugle” de Pound rendait pénible avec les apps non stateless;
  • La page de stats (stats enable): un backend qui prend 40% du traffic se voit immédiatement;
  • La granularité L7: router sur l’URL, le Host, un cookie, un User-Agent: en 2009 c’est ce qui sépare un proxy d’un répartiteur.

Les réflexes d’époque

  • balance roundrobin par défaut, mais leastconn pour les backends inhomogènes;
  • le pair keepalived/VRRP pour la redondance du haproxy lui-même (le SPOF se déplace, il ne disparaît pas);
  • les timeouts réglés explicitement (timeout connect 5s, timeout server 30s), les défauts généreux de haproxy étant fait pour les connexions longues;
  • et la conf testée avec haproxy -c avant chaque déploiement: la commande qui a sauvé plus de soirées que tous les backups de la maison, parce qu’une typo dans un frontend coupe tout le site et qu’on le découvre toujours pendant le dîner.

[edit: 2026] La pérennité, seule vraie surprise

Pound a fini aux oubliettes; haproxy, lui, a traversé tout: la même grammaire de conf est encore en prod aujourd’hui (HAProxy 3.x), avec les mêmes frontends/backends/ACL, agglomérés à quinze ans de features (HTTP/2, gRPC, TLS 1.3, maps, découvertes DNS). C’est la rareté dans l’outillage réseau: un outil dont la conf de 2009 charge encore telle quelle dans la version courante. Le reverse proxy de l’époque est devenu l’edge par défaut et la conf lisible n’y est pour rien moins que tout.

[edit: 2026] L’implémentation Ansible de tout ceci: le rôle haproxy .