RousselTMLEARNING

Article · HAProxy: from discovery to expertise

Certificates with Let's Encrypt

1. Understanding the ACME protocol #

The ACME (Automated Certificate Management Environment) protocol is the standard that automates interactions between a certificate authority (CA) such as Let's Encrypt and web servers to obtain SSL/TLS certificates.

How does it work? The 'challenges' #

To obtain a certificate, a server must prove that it really controls the requested domain. ACME uses 'challenges' for this verification:

  • HTTP-01: the ACME client (e.g. Certbot) places a file containing a unique token at a specific URL on the web server (http://<YOUR_DOMAIN>/.well-known/acme-challenge/<TOKEN>). The certificate authority then checks that the file is present. It is the most common method.
  • DNS-01: the ACME client creates a TXT DNS record with a specific value. The certificate authority checks this record. This method is more complex but lets you obtain wildcard certificates (*.yourdomain.com).

The benefits of automation #

  • Free: Let's Encrypt democratized HTTPS by offering free certificates through ACME.
  • Security: certificates have a short lifespan (90 days), which limits the risks if the private key is compromised.
  • Reliability: automating renewal eliminates the risk of forgetting, a frequent cause of website outages.

2. Hands-on: integration with modern proxies #

Each reverse proxy has its own philosophy for integrating the ACME protocol. Here is how the most popular ones do it.

Traefik: native integration #

Traefik is designed for dynamic environments (containers, microservices) and includes a native ACME client. There is no external tool to install. Configuration is done directly in Traefik's static file or through Docker labels.

To learn more, see our Traefik course.

Configuration example (docker-compose.yml):
version: '3.7'

services:
  traefik:
    image: traefik:v2.10
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.email=votre.email@domaine.com"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./letsencrypt:/letsencrypt"

  whoami:
    image: traefik/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.votre-domaine.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=myresolver"

HAProxy: native ACME client (3.2 and later) or external client #

Since version 3.2, HAProxy includes a native ACME client (an acme section associated with certificates, automatic renewal), first offered as an experimental feature limited to the HTTP-01 challenge. An external client (Certbot, acme.sh) remains the most proven option for earlier versions, the DNS-01 challenge or advanced needs: check the documentation for your HAProxy version. With an external client such as Certbot or acme.sh, the most robust approach in production is to use Certbot's webroot mode, which requires no service interruption.

Deepen your knowledge with our HAProxy course.

1. HAProxy configuration (haproxy.cfg)

The trick is to configure HAProxy to serve the challenge files created by Certbot itself, without disturbing normal traffic. To do this, you create a backend pointing to a local directory.

frontend http-in
    bind *:80

    # ACL pour intercepter les requêtes du challenge ACME
    acl is_acme path_beg /.well-known/acme-challenge/

    # Si la requête est pour ACME, on la sert via le backend dédié
    use_backend acme_backend if is_acme

    # Pour tout le reste du trafic, on redirige vers HTTPS
    default_backend web_servers
    redirect scheme https if !{ ssl_fc }

# Ce backend ne proxy rien, il sert des fichiers depuis un dossier local
backend acme_backend
    # On utilise un préfixe pour construire le chemin du fichier sur le disque
    http-request set-var(req.path) path
    http-request use-service lua.acme-http01

# Le frontend principal pour le trafic sécurisé
frontend https-in
    bind *:443 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1
    default_backend web_servers

Note: the use-service lua.acme-http01 directive is a modern, efficient method. An older alternative is to use a backend with a lightweight web server (such as a mini Nginx) that serves the content of the challenge directory.

2. Running Certbot in webroot mode

With this configuration, you can run Certbot in webroot mode. It simply creates a file in the /var/www/letsencrypt directory, and HAProxy serves it to the certificate authority.

# Assurez-vous que le répertoire existe et que l'utilisateur HAProxy peut y écrire
sudo mkdir -p /var/www/letsencrypt
sudo chown haproxy:haproxy /var/www/letsencrypt

# Lancez Certbot en spécifiant le webroot
sudo certbot certonly --webroot -w /var/www/letsencrypt -d votre-domaine.com
3. Automating renewal

HAProxy needs the certificate and private key in a single .pem file. You therefore use a script (--deploy-hook) that Certbot runs after each successful renewal to prepare the file and reload HAProxy.

Example renewal script (/etc/letsencrypt/renewal-hooks/deploy/haproxy-renew.sh):
#!/bin/bash

DOMAIN_PATH="/etc/letsencrypt/live/votre-domaine.com"
HAPROXY_CERT_PATH="/etc/haproxy/certs/votre-domaine.com.pem"

# Concaténer le certificat et la clé dans un seul fichier
cat "$DOMAIN_PATH/fullchain.pem" "$DOMAIN_PATH/privkey.pem" > "$HAPROXY_CERT_PATH"

# Recharger HAProxy pour qu'il prenne en compte le nouveau certificat
sudo systemctl reload haproxy

Don't forget to make this script executable: sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/haproxy-renew.sh. Certbot takes care of the rest through its system cron job, ensuring fully automated renewal without interruption.

Nginx: simplicity with the Certbot plugin #

Nginx is the most common use case for Certbot, which has a dedicated plugin (--nginx). This plugin can read your Nginx configuration, modify it to add the SSL blocks and handle the challenge transparently.

Become an Nginx expert with our dedicated course.

Setup example:

1. Install Certbot and its Nginx plugin:

sudo apt update
sudo apt install certbot python3-certbot-nginx

2. Run the magic command. Certbot takes care of everything:

sudo certbot --nginx -d votre-domaine.com -d www.votre-domaine.com

Certbot will automatically:

  • Detect the matching server blocks in your configuration.
  • Add the ssl_certificate and ssl_certificate_key directives.
  • Configure the HTTP-to-HTTPS redirect.
  • Install a cron job or a systemd timer for automatic renewal.

Conclusion #

Automating SSL/TLS certificate management is now an essential standard for any secure, reliable web infrastructure.

Which tool to choose? #

The choice depends on your architecture:

  • Traefik is the king of containerized, dynamic environments thanks to its native integration.
  • Nginx + Certbot is the simplest and most widespread solution for more traditional web servers (VMs, dedicated servers).
  • HAProxy + Certbot is a robust solution for high-performance infrastructures that need HAProxy's advanced features.

In every case, adopting the ACME protocol frees you from the mental load of manual renewal and ensures a safer web for everyone.

📄 Managing SSL/TLS certificates with Let's Encrypt and ACME →

My progress

  • ⏱ Estimated time : ≈ 13 min

Sign in to track your progress and take notes. Sign in

💬 Questions about this lesson

No questions yet: be the first to ask for help or share your configuration.

Ask a question about this lesson →

Recommended Articles

The ACME protocol: ACME server, http-01 and dns-01 challenges, TLS automation

Understand the ACME protocol: the role of the ACME server (Let's Encrypt, ZeroSSL, step-ca), the ...

HAProxy and SSL: TLS termination, SSL passthrough and hardening

HAProxy and SSL/TLS: SSL termination, SSL passthrough in TCP mode with SNI routing, re-encryption...

HAProxy as a Kubernetes Ingress Controller: the production guide

Learn how to use HAProxy as an Ingress Controller in Kubernetes: direct-to-pod architecture, TLS ...

Mastering ACLs in HAProxy: the complete guide

A complete guide to HAProxy ACLs: learn how to configure smart routing, IP-based access control, ...

Mastering ACLs in HAProxy

A complete guide to HAProxy ACLs: learn how to configure smart routing, IP-based access control, ...

HAProxy best practices: optimization, security and high availability

Discover the best practices for configuring HAProxy to ensure the performance, security and resil...

HAProxy in Kubernetes: the high-performance Ingress Controller

Discover in depth how HAProxy integrates with Kubernetes: direct-to-pod architecture, hot update ...

Advanced Elasticsearch security: TLS, certificates, API keys, FLS, DLS and audit

Secure Elasticsearch in depth: transport and HTTP TLS, certificate management with elasticsearch-...

Traefik best practices: security, high availability and observability

Traefik best practices: securing the dashboard and the Docker socket, modern TLS, middlewares, ra...

Support us

♥ SUPPORT US

Support RousselTM Learning

Courses, articles, labs and certificates stay free with no intrusive ads. A voluntary contribution, of any amount you choose, pays for hosting, lab environments and new content.

Contribute with PayPal Any amount · card or PayPal accountLearn more
QR code PayPal
Or scan this QR code with your phone

Thank you, every contribution counts!