Outils pour utilisateurs

Outils du site


article:linux:certificat_let_s_encrypt_wildcard_avec_challenge_dns

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Prochaine révision
Révision précédente
article:linux:certificat_let_s_encrypt_wildcard_avec_challenge_dns [2026/04/25 00:02] – créée Garyarticle:linux:certificat_let_s_encrypt_wildcard_avec_challenge_dns [2026/04/26 01:02] (Version actuelle) Gary
Ligne 4: Ligne 4:
   * Indépendant d'un serveur web (nginx, apache, ...): Afin de pouvoir réutiliser les certificats librement et sur plusieurs services   * Indépendant d'un serveur web (nginx, apache, ...): Afin de pouvoir réutiliser les certificats librement et sur plusieurs services
   * Wildcard (*.mondomain.tld) et domaine de base: Ainsi pas besoin de rejouer la certification à chaque nouveau service   * Wildcard (*.mondomain.tld) et domaine de base: Ainsi pas besoin de rejouer la certification à chaque nouveau service
-  * Challenge par DNS intermédiaire supportant API: Pour 2 raisons :+  * Challenge via un service DNS intermédiaire disposant d'une API: Pour 2 raisons :
     * Que notre serveur de base fournisse une API ou pas, on ne s'en préoccupe pas     * Que notre serveur de base fournisse une API ou pas, on ne s'en préoccupe pas
-    * La clé API utilisé sur notre DNS intermédiaire ne couvre QUE le l'entrée DNS de certification. En cas de fuite c'est limité à celui-ci+    * La clé API utilisée sur notre DNS intermédiaire ne couvre QUE le projet chez Hetzner, donc l'entrée DNS de certification. En cas de fuite c'est limité à celui-ci
  
 Le programme fournira en sortie les certificats *.mondomain.tld et mondomain.tld. On pourra faire pointer nos services directement dessus ou les fournir aux différents serveurs. Le programme fournira en sortie les certificats *.mondomain.tld et mondomain.tld. On pourra faire pointer nos services directement dessus ou les fournir aux différents serveurs.
  
-Note: Un certificat Let's Encrypt a une durée de vie de 90 jours. Il est généralement renouvellé 30 jours avant son expiration. Dans mon cas mes services redémarrent au moins une fois par semaine, je ne me préoccupe donc pas de redémarrer les services au moment du changement de certificat, ceux-ci chargerons les nouveaux certificats de manière asynchrone au moment du redémarrage.+Note: Un certificat Let's Encrypt a une durée de vie de 90 jours (64 jours à partir de 2027 puis 45 jours en 2028). Il est généralement renouvelé à 1/3 (ici 30 joursavant son expiration. Dans mon cas mes services redémarrent au moins une fois par semaine, je ne me préoccupe donc pas de redémarrer les services au moment du changement de certificat, ceux-ci chargeront les nouveaux certificats de manière asynchrone au moment du redémarrage.
  
 ===== Préparation du système ===== ===== Préparation du système =====
  
 <code bash> <code bash>
-apt install python3 python3-venv+apt install python3 python3-venv curl dnsutils ca-certificates
 </code> </code>
  
Ligne 25: Ligne 25:
 </code> </code>
  
-''--system'' : Compte système, possède un UID/GID bas, afin de séparer des utilisateurs interactif \\+''--system'' : Compte système, possède un UID/GID bas, afin de séparer des utilisateurs interactifs \\
 ''--group'' : Crée un groupe éponyme \\ ''--group'' : Crée un groupe éponyme \\
 ''--no-create-home'' : N'aura pas de home directory, inutile ici \\ ''--no-create-home'' : N'aura pas de home directory, inutile ici \\
-''--shell /usr/sbin/nologin'' : Le binaire nologin empêche d'ouvrir un shell si on s'connect+''--shell /usr/sbin/nologin'' : Le binaire nologin empêche d'ouvrir un shell si on s'connecte
  
 L'utilisateur n'aura pas de mot de passe non plus, car inaccessible. L'utilisateur n'aura pas de mot de passe non plus, car inaccessible.
Ligne 34: Ligne 34:
 Le groupe ''certssl-user'' permettra d'autoriser qui peut consulter les certificats Le groupe ''certssl-user'' permettra d'autoriser qui peut consulter les certificats
  
-Le dossier de travail sera ''/opt/certbot'', on va créer le nécessaire à cet endroit. En l'occurence un environnement virtuel python avec le package certbot installé+Le dossier de travail sera ''/opt/certbot'', on va créer le nécessaire à cet endroit. En l'occurrence un environnement virtuel python avec le package certbot installé
  
 <code bash> <code bash>
Ligne 58: Ligne 58:
   * Dans la partie DNS du projet, vous ajoutez votre nom de domaine   * Dans la partie DNS du projet, vous ajoutez votre nom de domaine
     * **Note**: Il indiquera "It looks like your domain is pointing to different nameservers.", ceci est normal et nous lui déléguerons uniquement le sous-domaine _acme-challenge utile à Let's Encrypt     * **Note**: Il indiquera "It looks like your domain is pointing to different nameservers.", ceci est normal et nous lui déléguerons uniquement le sous-domaine _acme-challenge utile à Let's Encrypt
-  * Créer une zone type *TXT* nommé "_acme-challenge", avec une valeur libre et un TTL de 60 secondes+  * Créer un enregistrement de type **TXT** nommé "_acme-challenge", avec une valeur libre et un TTL de 60 secondes
   * Dans la partie Security > API tokens, vous aurez besoin d'une clé API avec accès en écriture (Read/Write)   * Dans la partie Security > API tokens, vous aurez besoin d'une clé API avec accès en écriture (Read/Write)
  
 ==== Fichier de configuration ==== ==== Fichier de configuration ====
  
-On va réunir la configuration utilisé dans les scripts dans un fichier **.env**+On va réunir la configuration utilisée dans les scripts dans un fichier **.env**
  
 <code bash .env> <code bash .env>
 +# Domaine à certifier
 DOMAIN="mondomain.tld" DOMAIN="mondomain.tld"
 +# Token généré chez Hetzner
 TOKEN="MON-TOKEN-A-REMPLACER" TOKEN="MON-TOKEN-A-REMPLACER"
 +# Adresse de contact pour Let's Encrypt en cas de besoin
 +EMAIL="MON-EMAIL@mondomain.tld"
 </code> </code>
  
Ligne 76: Ligne 80:
 <code bash /opt/certbot/hook-hetzner.sh> <code bash /opt/certbot/hook-hetzner.sh>
 #!/usr/bin/env bash #!/usr/bin/env bash
 +set -euo pipefail
 +
 +set -a
 +source .env
 +set +a
  
-curl "https://api.hetzner.cloud/v1/zones/${DOMAIN}/rrsets/_acme-challenge/TXT/actions/add_records" \+curl -sS --fail-with-body "https://api.hetzner.cloud/v1/zones/${DOMAIN}/rrsets/_acme-challenge/TXT/actions/add_records" \
   --request POST \   --request POST \
   --header "Content-Type: application/json" \   --header "Content-Type: application/json" \
Ligne 96: Ligne 105:
 On n'oublie pas de le rendre exécutable On n'oublie pas de le rendre exécutable
 <code bash> <code bash>
-chmod +x hook-duckdns.sh+chmod +x hook-hetzner.sh
 </code> </code>
  
-noter que la variable ''CERTBOT_VALIDATION'' sera une variable d'environnement passé par certbot.+À noter que la variable ''CERTBOT_VALIDATION'' sera une variable d'environnement passée par certbot.
  
 Pour valider le bon fonctionnement : Pour valider le bon fonctionnement :
Ligne 135: Ligne 144:
 Il est recommandé (mais pas obligatoire) de nettoyer l'enregistrement DNS après validation par Let's Encrypt. Tout comme pour le script précédent, Certbot propose d'appeler un script pour le nettoyage, que voici : Il est recommandé (mais pas obligatoire) de nettoyer l'enregistrement DNS après validation par Let's Encrypt. Tout comme pour le script précédent, Certbot propose d'appeler un script pour le nettoyage, que voici :
  
-<code bash hook-hetzner.cleanup.sh>+<code bash hook-hetzner-cleanup.sh>
 #!/usr/bin/env bash #!/usr/bin/env bash
 +set -euo pipefail
  
-curl "https://api.hetzner.cloud/v1/zones/${DOMAIN}/rrsets/_acme-challenge/TXT"+set -a 
-  --request DELETE +source .env 
-  --header "Authorization: Bearer ${TOKEN}"+set +a 
 + 
 +curl -sS --fail-with-body "https://api.hetzner.cloud/v1/zones/${DOMAIN}/rrsets/_acme-challenge/TXT/actions/remove_records" \ 
 +  --request POST \ 
 +  --header "Content-Type: application/json" 
 +  --header "Authorization: Bearer ${TOKEN}" \ 
 +  --data "{ 
 +    \"records\":
 +      { 
 +        \"value\": \"\\\"${CERTBOT_VALIDATION}\\\"\" 
 +      } 
 +    ] 
 +  }"
 </code> </code>
  
 ==== Configuration du domaine principal ==== ==== Configuration du domaine principal ====
  
-Le domaine principal doit pouvoir déléguer ''_acme-challenger.mondomain.tld'' vers Hetzner, ce qui est le rôle des enregistrement de type **NS**.+Le domaine principal doit pouvoir déléguer ''_acme-challenge.mondomain.tld'' vers Hetzner, ce qui est le rôle des enregistrements de type **NS**.
  
-Sur votre console Hetner, dans la partie DNS > mondomain.tld > Name servers, Hetner indique les serveurs DNS qui contient notre enregistrement, dans mon cas : ''hydrogen.ns.hetzner.com.'', ''helium.ns.hetzner.de.'', ''oxygen.ns.hetzner.com.'' (Potentiellement différent chez vous)+Sur votre console Hetzner, dans la partie DNS > mondomain.tld > Name servers, Hetzner indique les serveurs DNS qui contiennent notre enregistrement, dans mon cas : ''hydrogen.ns.hetzner.com.'', ''helium.ns.hetzner.de.'', ''oxygen.ns.hetzner.com.'' (Potentiellement différent chez vous)
  
-Chez votre registrar, vous devrez ajouter ces serveurs comme record de type **NS** pour le sous-domaine _acme-challenge :+Chez votre registrar, vous devrez ajouter ces serveurs comme enregistrement de type **NS** pour le sous-domaine _acme-challenge :
  
 <code> <code>
Ligne 167: Ligne 189:
 ===== Automatisation de Certbot ===== ===== Automatisation de Certbot =====
  
-Tout est en place pour que Certbot puisse travailler. Le certificat n'étant valable que 90 jours, il est obligatoire d'automatiser son renouvellement. On créer un script également pour ceci :+Tout est en place pour que Certbot puisse travailler. Le certificat ayant une durée de vie courte, il est obligatoire d'automatiser son renouvellement. On crée un script également pour ceci :
  
 <code bash certbot-renew.sh> <code bash certbot-renew.sh>
Ligne 193: Ligne 215:
 echo \> Renew \[*.\]${DOMAIN} echo \> Renew \[*.\]${DOMAIN}
 bin/certbot --config-dir "${CONF_DIR}" --work-dir "${WORK_DIR}" --logs-dir "${LOGS_DIR}" \ bin/certbot --config-dir "${CONF_DIR}" --work-dir "${WORK_DIR}" --logs-dir "${LOGS_DIR}" \
-           certonly --verbose --non-interactive --agree-tos --manual \+           certonly --verbose --non-interactive --agree-tos --manual --email "${EMAIL}" \
            --preferred-challenges dns --domains "${DOMAIN}" --domains "*.${DOMAIN}" \            --preferred-challenges dns --domains "${DOMAIN}" --domains "*.${DOMAIN}" \
            --manual-auth-hook ./hook-hetzner.sh \            --manual-auth-hook ./hook-hetzner.sh \
Ligne 203: Ligne 225:
 fi fi
  
-cp -rfL "${CONF_DIR}/live/${DOMAIN}/*.pem"cert/${DOMAIN}/" +cp -rfL "${CONF_DIR}/live/${DOMAIN}/"*.pem "cert/${DOMAIN}/" 
-chmod 0640 "cert/${DOMAIN}/*"+chmod 0640 "cert/${DOMAIN}/"*
 </code> </code>
  
Ligne 216: Ligne 238:
 ==== Sécurisation du répertoire ==== ==== Sécurisation du répertoire ====
  
-Mes tests ont été fait avec un utilisateur interactif par facilité. Mettons en place la sécurité nécessaire+Mes tests ont été faits avec un utilisateur interactif par facilité. Mettons en place la sécurité nécessaire
  
 <code bash> <code bash>
Ligne 227: Ligne 249:
 find . -type f -exec chmod 640 {} \; find . -type f -exec chmod 640 {} \;
 chmod 700 *.sh chmod 700 *.sh
 +chmod 700 bin/certbot
 chmod 600 .env chmod 600 .env
  
Ligne 236: Ligne 259:
 ==== Crontab ==== ==== Crontab ====
  
-Je trouve qu'une fois semaine est un bon compromis. Dès qu'il restera 30 jours au certificat, il sera au maximum dans les 7 prochains jours.+Je trouve qu'une fois par semaine est un bon compromis. Dès qu'il restera 30 jours au certificat, il sera au maximum dans les 7 prochains jours.
  
 Certbot ne tentera rien si le certificat est trop récent. Certbot ne tentera rien si le certificat est trop récent.
Ligne 245: Ligne 268:
 # Renouvellement certificat Let's Encrypt # Renouvellement certificat Let's Encrypt
 # Chaque dimanche à 2h14 # Chaque dimanche à 2h14
-14 2 * * 0 /opt/certbot/certbot-renew.sh > /opt/certbot/cron.log+14 2 * * 0 /opt/certbot/certbot-renew.sh > /opt/certbot/cron.log 2>&1
 </code> </code>
  
Ligne 252: Ligne 275:
 ===== Conclusion ===== ===== Conclusion =====
  
-Le script n'est pas parfait, n'est pas hyper sécurisé et il y a forcément moyen de faire mieux/optimisé...+Le script n'est pas parfait, n'est pas hyper sécurisé et il y a forcément moyen de faire mieux/optimiser...
  
 MAIS, je l'utilise depuis maintenant des années (un peu amélioré pour l'article et initialement avec DuckDNS), et il ne m'a jamais fait défaut. MAIS, je l'utilise depuis maintenant des années (un peu amélioré pour l'article et initialement avec DuckDNS), et il ne m'a jamais fait défaut.
  
 CEPENDANT ! Il ne dispense pas d'un monitoring de l'état du certificat SSL sur le site web où il sera utilisé avec une alerte s'il expire prochainement (- de 15 jours), signe d'un problème. CEPENDANT ! Il ne dispense pas d'un monitoring de l'état du certificat SSL sur le site web où il sera utilisé avec une alerte s'il expire prochainement (- de 15 jours), signe d'un problème.
article/linux/certificat_let_s_encrypt_wildcard_avec_challenge_dns.1777068153.txt.gz · Dernière modification : de Gary

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki

GH3.BE WIKI 2026