RousselTMLEARNING

Proxy & networking

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

Learn how to automate the generation and renewal of your SSL/TLS certificates with Let's Encrypt. Discover the ACME protocol and its integration with Traefik, HAProxy and Nginx.

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

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.

Related articles

Traefik: securing and transforming requests with middlewares (BasicAuth, ForwardAuth…)

Traefik middlewares modify requests and responses between the router and the service: BasicAuth and ForwardAu…

Traefik: providers (Docker, Kubernetes, Nomad, Consul, files, key-value stores)

Providers feed Traefik's dynamic configuration: service discovery for Docker, Swarm, Kubernetes, Nomad and Co…

Traefik as an Ingress Controller for Kubernetes (Helm, IngressRoute, Gateway API)

Install Traefik in Kubernetes with Helm and publish applications with Ingress, the IngressRoute and Middlewar…

Keep learning

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!