Let's Encrypt : certificats TLS gratuits et renouvellement automatique
Cet article explique comment fonctionne Let's Encrypt, comment obtenir un certificat avec Certbot 2.x, et comment vérifier que le renouvellement se fait tout seul. Il s'adresse à quiconque administre un serveur web sous Linux et veut du HTTPS sans passer par une autorité commerciale.
Prérequis
- Un serveur Linux avec un accès root ou sudo.
- Un nom de domaine qui pointe vers l'adresse IP publique du serveur (enregistrement A ou AAAA).
- Le port 80 accessible depuis l'extérieur, même si tu veux seulement du HTTPS. La validation HTTP-01 passe par là.
- Une version récente de Certbot. La 2.x est la branche active ; la 1.x ne reçoit plus de mises à jour.
- Un serveur web : Nginx ou Apache. Les exemples ci-dessous utilisent Nginx.
Étape 1 — Installer Certbot
Certbot est le client officiel de l'EFF. Il gère l'émission, l'installation et le renouvellement.Sur Debian 12 ou Ubuntu 24.04, passe par le dépôt de ta distribution :
```bash sudo apt update sudo apt install certbot python3-certbot-nginx ```
Sur RHEL 9 ou Rocky Linux 9 :
```bash sudo dnf install certbot python3-certbot-nginx ```
Le paquet `python3-certbot-nginx` n'est utile que si tu utilises Nginx. Pour Apache, remplace-le par `python3-certbot-apache`. Si tu préfères gérer la configuration toi-même, installe Certbot seul et utilise le mode `--webroot`.
Étape 2 — Comprendre ce que Certbot va faire
Avant de lancer la commande, sache ce qui va se passer. Certbot va :1. Générer une paire de clés privée/publique sur ton serveur. La clé privée ne quitte jamais la machine. 2. Demander à Let's Encrypt un challenge pour prouver que tu contrôles le domaine. 3. Placer un fichier temporaire sous `/.well-known/acme-challenge/` que Let's Encrypt viendra lire via HTTP. 4. Recevoir le certificat signé, valable 90 jours. 5. Modifier ta configuration Nginx pour pointer vers le certificat et recharger le service.
La clé privée reste locale. Let's Encrypt ne la voit jamais. C'est le principe même d'ACME : l'autorité signe une clé publique, elle ne détient rien.
Étape 3 — Obtenir le premier certificat
La commande dépend de la façon dont ton serveur web est configuré.Si Nginx sert déjà ton domaine en HTTP avec un `server_name` correct :
```bash sudo certbot --nginx -d example.com -d www.example.com ```
Certbot détecte le bloc `server`, obtient le certificat, et réécrit la configuration pour rediriger HTTP vers HTTPS. Il te demande une adresse e-mail pour les notifications d'expiration et te propose de participer à la liste de diffusion de l'EFF. Tu peux refuser.
Si tu veux gérer la configuration Nginx toi-même, utilise le mode webroot :
```bash sudo certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com ```
Dans ce cas, tu ajoutes toi-même les directives `ssl_certificate` et `ssl_certificate_key` dans ton bloc serveur. Les fichiers se trouvent sous `/etc/letsencrypt/live/example.com/`.
Le mode `--nginx` est plus rapide. Le mode `--webroot` te laisse le contrôle. Choisis selon ce que tu préfères maintenir dans six mois.
Étape 4 — Vérifier la chaîne de certificats
Un certificat émis ne garantit pas que Nginx le sert correctement. Vérifie avec OpenSSL depuis une autre machine, pas depuis le serveur lui-même — sinon tu testes la boucle locale.```bash openssl s_client -connect example.com:443 -servername example.com /dev/null | openssl x509 -noout -subject -issuer -dates ```
Tu dois voir `issuer=... Let's Encrypt ...` et une date d'expiration à environ 90 jours. Si l'émetteur affiché est autre chose, ton serveur sert un ancien certificat ou un certificat auto-signé.
Étape 5 — Mettre en place le renouvellement automatique
Les certificats Let's Encrypt durent 90 jours. Cette durée est volontaire : elle limite la fenêtre d'exploitation si une clé fuite, et elle force l'automatisation. Un renouvellement manuel tous les trois mois est une source d'oubli garantie.Le paquet Certbot installe normalement un timer systemd ou une tâche cron. Vérifie lequel :
```bash systemctl list-timers | grep certbot ```
Sur les installations récentes, tu verras `certbot.timer`. S'il n'existe pas, crée-le :
```bash sudo systemctl enable --now certbot.timer ```
Si tu préfères cron, la ligne standard est :
```bash echo "0 3 * root certbot renew --quiet --deploy-hook 'systemctl reload nginx'" | sudo tee /etc/cron.d/certbot ```
Le `--deploy-hook` recharge Nginx uniquement quand un certificat a réellement été renouvelé. Sans lui, le serveur continue de servir l'ancien certificat en mémoire jusqu'au prochain redémarrage.
Étape 6 — Tester le renouvellement sans consommer de quota
Let's Encrypt impose des limites : 50 certificats par domaine enregistré et par semaine, 5 échecs de validation par compte et par heure. Un test mal placé peut te bloquer pour la journée.Certbot propose un mode simulation :
```bash sudo certbot renew --dry-run ```
Cette commande exécute tout le processus contre l'environnement de staging de Let's Encrypt. Aucun certificat réel n'est émis, aucun quota de production n'est touché. Si elle se termine sans erreur, ton renouvellement automatique fonctionnera.
Étape 7 — Configurer les enregistrements DNS pour le mode DNS-01
Le mode HTTP-01 échoue si ton serveur n'est pas joignable sur le port 80, ou si tu veux un certificat wildcard (`*.example.com`). Dans ces cas, passe au DNS-01.Tu déposes un enregistrement TXT `_acme-challenge.example.com` avec une valeur fournie par Certbot. Le plugin DNS de ton hébergeur automatise l'opération :
```bash sudo apt install python3-certbot-dns-cloudflare ```
Puis, avec un fichier d'identifiants correctement protégé :
```bash sudo certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \ -d example.com -d '*.example.com' ```
Le fichier d'identifiants doit être en `chmod 600` et appartenir à root. Un token DNS qui traîne en clair dans un dépôt Git, c'est un domaine qui change de propriétaire sans que tu t'en aperçoives.
Vérification
Deux contrôles suffisent.D'abord, la date d'expiration du certificat servi :
```bash echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate ```
Ensuite, la liste des certificats gérés par Certbot sur la machine :
```bash sudo certbot certificates ```
Tu dois y voir ton domaine, sa date d'expiration, et le chemin vers les fichiers. Si l'expiration est à plus de 60 jours, le renouvellement automatique n'a pas encore eu lieu — c'est normal. Le timer s'en occupe quand il reste 30 jours.
Problèmes fréquents
Le challenge HTTP-01 échoue avec « Connection refused » ou « Timeout » Le port 80 est fermé, ou un pare-feu bloque Let's Encrypt. Vérifie avec `sudo ss -tlnp | grep :80` que Nginx écoute bien. Si tu es derrière un CDN, la requête de validation doit atteindre ton origine — beaucoup de CDN proposent une option pour laisser passer `/.well-known/acme-challenge/`.Le navigateur affiche encore l'ancien certificat après renouvellement Nginx garde le certificat en mémoire au démarrage. Il faut le recharger. C'est exactement le rôle du `--deploy-hook` de l'étape 5. Sans lui, `certbot renew` réussit mais le serveur ne voit rien.
« too many failed authorizations recently » Tu as dépassé la limite de 5 échecs par heure. Attends une heure, puis corrige la cause avant de relancer. En attendant, teste avec `--dry-run` contre le staging : les quotas y sont bien plus larges.
Let's Encrypt a rendu le HTTPS par défaut au lieu d'être une option payante. Ce que ça t'a coûté : une dépendance à une autorité unique, financée par des dons, et un protocole — ACME — que tu dois comprendre au moins assez pour le déboguer quand il casse à trois heures du matin.