SSD Nodes Learn
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-07-19

Certbot Ubuntu 24.04 : Apache + Let's Encrypt

Obtenez un certificat Let's Encrypt pour Apache sur Ubuntu 24.04 avec Certbot : snap ou apt, ServerName, renouvellement auto et les erreurs d'émission.

Ce que vous construisez

Un site Apache sur Ubuntu 24.04 qui répond en HTTPS avec un certificat Let's Encrypt gratuit et reconnu par les navigateurs, émis par Certbot et renouvelé automatiquement par un timer systemd auquel vous ne penserez plus jamais. La commande qui fait le travail tient sur une seule ligne. Tout ce qui échoue échoue avant cette ligne : un vhost sans ServerName, le port 80 fermé sur le pare-feu du fournisseur, le DNS qui pointe encore vers l'ancien serveur. Ce guide passe donc l'essentiel de son temps sur les conditions préalables, et nomme la chaîne d'erreur exacte qu'affiche chaque erreur.

Deux précisions de périmètre. Si votre serveur web est nginx, le déroulement a la même forme mais le plugin et les configurations diffèrent : utilisez plutôt la version nginx de ce guide. Et si ce que vous sécurisez est purement interne, un panneau d'administration sur une adresse privée, une machine de préproduction que personne d'autre ne visite, vous n'avez pas besoin d'autorité de certification du tout ; un certificat auto-signé demande moins de machinerie et fonctionne hors ligne.

Prérequis, et les trois façons dont cela échoue avant même que Certbot démarre

  • Apache dessert déjà votre site en HTTP simple. Le plugin Apache de Certbot modifie un site existant ; il n'en crée pas. Si vous partez d'un VPS vierge, construisez d'abord la pile LAMP sur Ubuntu 24.04 et revenez : ce guide en est le chapitre TLS manquant.
  • Un domaine public avec un enregistrement A pointant vers l'adresse de votre VPS. Le défi HTTP-01 de Let's Encrypt signifie que leurs serveurs de validation se connectent à votre machine depuis Internet : pas de homelab derrière un NAT sans redirection de port, pas de noms .local, pas d'adresses IP nues. dig +short example.com doit renvoyer l'adresse de votre VPS, et si vous avez changé le DNS dans la dernière heure, attendez l'expiration du TTL de l'ancien enregistrement avant d'émettre.
  • Si un enregistrement AAAA existe, il doit être correct. Let's Encrypt préfère l'IPv6 quand un enregistrement AAAA est publié, donc un AAAA périmé échoue à la validation même si curl depuis votre ordinateur portable, probablement en IPv4, fonctionne parfaitement. Publiez un AAAA correct ou aucun.

Les ports 80 et 443 doivent être ouverts dans ufw et dans le pare-feu réseau de votre fournisseur : la plupart des panneaux d'hébergement ont un second pare-feu que le système d'exploitation ne voit jamais. HTTP-01 valide spécifiquement sur le port 80 ; vous ne pouvez pas faire cela en 443 uniquement.

sudo ufw allow "Apache Full"
sudo ufw status

Une fois cela en place, tout le travail prend quinze minutes, dont dix de lecture.

Certbot snap ou apt ? Sur 24.04, apt convient enfin

Certbot est passé à la distribution snap il y a des années pour une bonne raison : les paquets des distributions se fossilisaient. Ubuntu 20.04 livrait Certbot 0.40 et n'a jamais bougé, et le projet s'est lassé de déboguer des bugs vieux de cinq ans. Sur 24.04 cette raison a disparu : l'archive livre Certbot 2.9.0, une version de génération actuelle, et unattended-upgrades la maintient à jour. Ma recommandation pour ce système d'exploitation : utilisez apt. Vous évitez le démon snapd, le plugin Apache s'installe dans la même transaction, et le timer de renouvellement s'intègre à systemd de la manière Debian ordinaire.

sudo apt update
sudo apt install -y certbot python3-certbot-apache
certbot --version

Résultat correct : certbot 2.9.0. Le paquet python3-certbot-apache est le plugin qui lit et modifie vos configurations Apache : sans lui, certbot --apache échoue avec The requested apache plugin does not appear to be installed.

Le snap reste le bon choix dans deux cas : vous voulez le Certbot le plus récent le jour de sa sortie, ou vous avez besoin d'un plugin DNS distribué uniquement en snap (c'est le cas de plusieurs plugins de fournisseurs certbot-dns-*). Si vous partez dans cette direction :

sudo apt remove -y certbot python3-certbot-apache
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Quel que soit votre choix, n'utilisez jamais les deux. Deux installations signifient deux planificateurs de renouvellement qui se disputent /etc/letsencrypt, et le certbot que votre shell trouve dans le PATH peut ne pas être celui qui possède vos certificats. La ligne apt remove ci-dessus n'est pas une décoration facultative.

Le vhost que Certbot modifie doit déjà exister : ServerName est tout l'enjeu

certbot --apache fonctionne en trouvant l'hôte virtuel sur le port 80 dont le ServerName ou le ServerAlias correspond à chaque domaine -d que vous passez, en prouvant le contrôle du domaine à travers lui, puis en écrivant un jumeau SSL de ce vhost. Pas de ServerName correspondant, pas de correspondance ; et le 000-default.conf par défaut d'Ubuntu est livré avec ServerName en commentaire. Cette seule ligne commentée est la raison la plus fréquente pour laquelle la grande commande de ce guide échoue.

Donc avant de toucher à Certbot, donnez au site un vhost basé sur le nom, en bonne et due forme. Créez /etc/apache2/sites-available/example.com.conf :

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com
    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>

Activez-le et confirmez qu'Apache l'analyse bien et route le nom vers lui :

sudo a2ensite example.com.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
sudo apache2ctl -S

configtest doit afficher Syntax OK. S'il affiche aussi AH00558: apache2: Could not reliably determine the server's fully qualified domain name, c'est un avertissement sur le ServerName global, pas sur votre vhost : sans conséquence ici, et réduit au silence par echo "ServerName $(hostname -f)" | sudo tee /etc/apache2/conf-available/servername.conf && sudo a2enconf servername && sudo systemctl reload apache2.

La sortie de -S est la vérification qui compte. Vous voulez une ligne comme port 80 namevhost example.com (/etc/apache2/sites-enabled/example.com.conf:1) avec alias www.example.com en dessous : Apache indique le lien symbolique sites-enabled qu'il a réellement lu, pas le fichier que vous avez modifié dans sites-available. Si example.com n'est pas listé face au port 80, Certbot ne le trouvera pas non plus.

Émettre le certificat : certbot --apache

sudo certbot --apache -d example.com -d www.example.com

La première exécution demande trois choses : une adresse e-mail (utilisée pour votre compte ACME et les avis urgents de l'autorité de certification ; Let's Encrypt n'envoie plus d'avertissements d'expiration, donc la surveillance des renouvellements vous incombe), l'acceptation des conditions de Let's Encrypt, et si vous voulez partager votre e-mail avec l'EFF. Il n'y a plus de question sur la redirection : depuis Certbot 2.0, l'installateur Apache redirige HTTP vers HTTPS par défaut, ce qui est ce que vous voulez. Passez --no-redirect si vous avez réellement besoin que le HTTP simple continue à servir du contenu.

Le succès ressemble à ceci, et vous devriez le lire plutôt que le survoler :

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2026-10-14.

Deploying certificate
Successfully deployed certificate for example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Successfully deployed certificate for www.example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://example.com and https://www.example.com

Derrière ce message, Certbot a fait quatre choses : activé le module ssl d'Apache s'il ne l'était pas déjà, écrit example.com-le-ssl.conf (une copie de votre vhost sur *:443 avec SSLEngine on et les chemins du certificat), activé ce fichier, et ajouté un bloc RewriteRule au vhost d'origine sur le port 80 qui redirige tout en 301 vers HTTPS. Votre fichier vhost d'origine est modifié, pas remplacé, et le jumeau SSL se trouve à côté, où vous pouvez lire chaque ligne qu'il a ajoutée.

Où réside réellement le certificat, et pourquoi vous ne le copiez jamais

Tout arrive sous /etc/letsencrypt/live/example.com/ : fullchain.pem (le certificat plus la chaîne intermédiaire, ce vers quoi les serveurs doivent pointer), privkey.pem (la clé privée, lisible par root uniquement), plus cert.pem et chain.pem pour les logiciels qui veulent les morceaux séparément. Ce sont des liens symboliques vers /etc/letsencrypt/archive/, et cette indirection est le mécanisme de renouvellement : le renouvellement écrit de nouveaux fichiers dans archive/ et repointe les liens symboliques. Pointez n'importe quel autre logiciel vers les chemins live/ et il récupère les renouvellements gratuitement ; copiez les fichiers ailleurs et vous vous êtes construit une panne dans 90 jours.

L'autre fichier à connaître est /etc/letsencrypt/renewal/example.com.conf, qui enregistre comment ce certificat a été émis (authenticator = apache, installer = apache, les domaines) afin que le renouvellement puisse répéter le processus sans surveillance, y compris le rechargement d'Apache ensuite.

Le renouvellement est déjà planifié : vérifiez-le, ne le construisez pas

Les certificats Let's Encrypt durent 90 jours par conception, et le paquet apt a déjà installé la machinerie : un timer systemd qui exécute Certbot deux fois par jour à des heures aléatoires, renouvelant tout certificat à moins de 30 jours de l'expiration. N'ajoutez pas de tâche cron par-dessus ; un second planificateur n'apporte que du bruit dans les journaux et une exposition aux limites de débit.

systemctl list-timers certbot.timer
sudo certbot renew --dry-run

La première commande montre le timer actif, avec une heure NEXT quelque part dans les 24 heures à venir : la planification est deux fois par jour avec un délai aléatoire, donc l'heure exacte est délibérément imprévisible (sur l'installation snap, le timer est plutôt snap.certbot.renew.timer). Le test à blanc effectue une répétition complète de renouvellement contre l'environnement de préproduction de Let's Encrypt : défi réel, aucun certificat émis, aucun coût en limite de débit. Le résultat correct se termine par :

Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)

Si le test à blanc échoue, le vrai renouvellement dans environ 60 jours échouera de la même manière : corrigez-le maintenant, pendant que le certificat actuel a encore toute sa vie devant lui. Le coupable habituel est une règle de pare-feu ajoutée après l'émission qui a refermé le port 80.

Vérifier avec curl, et ce que le cadenas doit indiquer

curl -sI http://example.com | head -n 3
curl -I https://example.com
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -issuer -dates

La première doit renvoyer HTTP/1.1 301 Moved Permanently avec un en-tête Location: https://example.com/ : c'est la redirection installée par Certbot. La deuxième doit renvoyer HTTP/1.1 200 OK sans plainte TLS de la part de curl. La troisième affiche l'émetteur (une ligne O = Let's Encrypt avec un CN court comme R12 ou E7) et un notAfter à environ 90 jours. Dans un navigateur, vous obtenez le cadenas, et un clic dessus montre le même émetteur. Si curl fonctionne et que le navigateur avertit, vous regardez presque certainement une page en cache ou le mauvais nom d'hôte, pas un problème de certificat.

Plusieurs sites : un certificat SAN ou un certificat par site

Les deux fonctionnent ; ils se renouvellent de la même façon. Pour des sites sans rapport sur la même machine, exécutez la commande d'émission une fois par site : chacun obtient son propre répertoire sous live/ et sa propre configuration de renouvellement, et un problème sur un domaine ne bloque jamais le renouvellement des autres. C'est mon choix par défaut.

Pour un seul site avec plusieurs noms, mettez-les sur un seul certificat SAN : un seul certificat peut porter jusqu'à 100 noms. Vous l'avez déjà fait ci-dessus avec example.com et www.example.com. Pour ajouter un nom à un certificat existant plus tard, réémettez en nommant le certificat et la liste complète des nouveaux noms :

sudo certbot --apache --cert-name example.com -d example.com -d www.example.com -d blog.example.com

Certbot remarque le jeu de domaines modifié, vous demande de confirmer l'extension, et remplace le certificat sur place : même chemin live/, donc rien d'autre n'a besoin d'être touché. Notez que la liste est un remplacement, pas un ajout : omettez www de cette commande et le nouveau certificat l'abandonne silencieusement.

Les certificats génériques exigent DNS-01, et en général vous n'en avez pas besoin

HTTP-01 ne peut pas émettre *.example.com : placer un fichier sur un serveur web prouve le contrôle d'un seul nom d'hôte, pas de tout un espace de noms. Les certificats génériques exigent le défi DNS-01 : Certbot pose un enregistrement TXT sur _acme-challenge.example.com, ce qui en pratique signifie un plugin certbot-dns-* avec des identifiants d'API pour votre fournisseur DNS, ou l'édition manuelle des enregistrements TXT à chaque renouvellement avec --manual (pénible : ne bâtissez pas votre plan autour). Le tutoriel complet, de la mécanique de l'enregistrement TXT à un plugin qui se renouvelle sans surveillance, se trouve dans les certificats génériques avec Certbot via DNS-01. Conseil honnête : si vous avez quatre sous-domaines connus, un certificat SAN qui les liste tous les quatre est plus simple qu'un certificat générique et ne nécessite aucune clé d'API DNS posée sur le serveur.

Modes d'échec, avec les chaînes que vous verrez

Certbot refuse de démarrer parce que la configuration d'Apache est cassée.

The apache plugin is not working; there may be problems with your existing configuration.
The error was: MisconfigurationError('Error while running apache2ctl configtest.\n\nAction \'configtest\' failed.\nThe Apache error log may have more information.\n\nAH00526: Syntax error on line 12 of /etc/apache2/sites-enabled/example.com.conf')

Le plugin exécute configtest avant de toucher à quoi que ce soit et abandonne si Apache lui-même n'est pas content : les \n sont littéraux parce que Certbot affiche le repr de l'exception. Exécutez sudo apache2ctl configtest vous-même : il nomme le fichier et la ligne, typiquement une faute de frappe due à une édition manuelle, un SSLCertificateFile pointant vers un chemin qui n'existe plus, ou un module référencé mais non activé. Corrigez jusqu'à ce qu'il affiche Syntax OK, puis relancez Certbot.

Aucun vhost ne correspond au domaine.

Unable to find a virtual host listening on port 80 which is currently the only challenge port.

C'est l'échec du ServerName manquant vu plus haut, attrapé au moment de l'émission. Certbot a cherché dans chaque vhost activé sur le port 80 un ServerName/ServerAlias correspondant à votre -d et n'a rien trouvé. sudo apache2ctl -S montre ce qu'Apache route réellement ; ajoutez la ligne ServerName au bon vhost, rechargez, réessayez. Un cousin proche est la validation qui atteint le mauvais vhost : la réponse au défi revient en Invalid response ... 404 parce qu'un autre site a intercepté la requête. Même diagnostic, même outil : apache2ctl -S.

La validation expire.

Certbot failed to authenticate some domains (authenticator: apache).
...
Detail: ...: Timeout during connect (likely firewall problem)

Let's Encrypt n'a pas pu ouvrir de connexion TCP vers le port 80 à l'adresse que votre DNS annonce. Par ordre de probabilité : le pare-feu réseau de votre fournisseur (distinct de ufw, configuré dans le panneau d'hébergement), un jeu de règles ufw n'autorisant que le 443 ou que le SSH, le DNS pointant encore vers un serveur précédent, ou le problème de l'AAAA périmé, leurs serveurs ont essayé l'IPv6 et le vôtre ne répond qu'en IPv4. Testez depuis l'extérieur du VPS : curl -I http://example.com depuis votre ordinateur portable reproduit ce que voit leur validateur.

Vous avez atteint une limite de débit à force de réessayer.

Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/

Let's Encrypt autorise 5 validations échouées par nom d'hôte, par compte et par heure ; depuis la refonte des limites de débit de 2025, c'est un seau qui se remplit, regagnant environ un essai toutes les 12 minutes, et marteler les réessais contre un pare-feu cassé l'épuise vite. Attendre fonctionne, mais le vrai correctif est comportemental : après tout échec, déboguez avec l'environnement de préproduction jusqu'à ce que ça réussisse.

sudo certbot certonly --apache --dry-run -d example.com -d www.example.com

Notez le certonly : --dry-run n'est accepté que par les sous-commandes certonly et renew, et la forme nue certbot --apache --dry-run refuse carrément de s'exécuter, en vous disant --dry-run currently only works with the 'certonly' or 'renew' subcommands. Le test à blanc valide contre la préproduction, qui a ses propres limites généreuses et n'émet aucun certificat réel, donc vous pouvez y échouer tout l'après-midi. Ne relancez la vraie commande qu'une fois la préproduction réussie. Les autres limites, 50 certificats par domaine enregistré et par semaine, 5 doublons du même jeu de noms par semaine, vous ne les atteindrez que si un script réémet en boucle.

Une fois le HTTPS en place, souvenez-vous que le certificat sécurise le transport, pas le serveur : le port 22 encaisse toujours des tentatives de mot de passe toute la journée. Associer cela à Fail2ban sur Ubuntu 24.04 est la suite naturelle des trente prochaines minutes.

FAQ

Faut-il installer Certbot avec snap ou apt pour Apache sur Ubuntu 24.04 ?

Utilisez apt. Ubuntu 24.04 livre Certbot 2.9.0, assez récent pour tout ce que couvre ce guide, reçoit les correctifs de sécurité via unattended-upgrades, et ne nécessite pas snapd. Choisissez le snap uniquement si vous avez besoin de la version la plus récente immédiatement ou d'un plugin DNS distribué exclusivement en snap ; et si vous changez, faites d'abord apt remove certbot python3-certbot-apache pour que deux planificateurs de renouvellement ne coexistent jamais.

Pourquoi Certbot affiche-t-il « Unable to find a virtual host listening on port 80 » ?

Parce qu'aucun vhost activé sur le port 80 n'a de ServerName ou de ServerAlias correspondant au domaine que vous avez passé avec -d : le vhost par défaut d'Ubuntu est livré avec ServerName en commentaire. Exécutez sudo apache2ctl -S, trouvez (ou créez) le vhost qui devrait posséder le nom, ajoutez ServerName example.com, rechargez Apache, et relancez Certbot.

Comment corriger « Timeout during connect (likely firewall problem) » ?

Let's Encrypt n'a pas pu atteindre le port 80 à l'adresse que votre DNS publie. Vérifiez le pare-feu réseau au niveau du panneau de votre fournisseur ainsi que ufw, confirmez que dig +short example.com renvoie ce VPS, et supprimez ou corrigez tout enregistrement AAAA périmé : la validation préfère l'IPv6 quand il en existe un. Confirmez la correction depuis l'extérieur du serveur avec curl -I http://example.com, puis répétez avec sudo certbot certonly --apache --dry-run -d example.com avant l'émission réelle.

Certbot renouvelle-t-il les certificats automatiquement sur Ubuntu 24.04 ?

Oui. Le paquet apt installe certbot.timer, un timer systemd qui s'exécute deux fois par jour et renouvelle tout certificat à moins de 30 jours de l'expiration, en rechargeant Apache ensuite ; le snap utilise snap.certbot.renew.timer pour la même tâche. Vérifiez avec systemctl list-timers certbot.timer et répétez avec sudo certbot renew --dry-run : n'ajoutez pas votre propre tâche cron par-dessus.

Comment obtenir un certificat générique avec Certbot et Apache ?

Les certificats génériques exigent le défi DNS-01 : Certbot doit placer un enregistrement TXT sur _acme-challenge.example.com, ce qui implique un plugin certbot-dns-* avec des identifiants d'API pour votre fournisseur DNS (l'alternative --manual nécessite des enregistrements TXT édités à la main à chaque renouvellement). Si vous n'avez qu'une poignée de sous-domaines connus, un certificat SAN qui les liste explicitement est plus simple et garde les clés d'API DNS hors du serveur.