Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente | |||
si:infra:acme-dns [2025/04/24 21:34] – supprimée - modification externe (Unknown date) 127.0.0.1 | si:infra:acme-dns [2025/04/24 21:34] (Version actuelle) – ↷ Page déplacée de si:acme-dns à si:infra:acme-dns vcalame | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ====== Certificats Letsencrypt via DNS ====== | ||
+ | |||
+ | La création de certificats Letsencrypt se fait traditionnellement par authentification HTTP en utilisant le client [[https:// | ||
+ | Mais il est également possible de créer des certificats Letsencrypt par authentification DNS pour des cas d' | ||
+ | |||
+ | Pour les besoins du service XMPP c'est un certificat Wildcard qui a été créé en utilisant le client [[https:// | ||
+ | |||
+ | Ici j' | ||
+ | |||
+ | ===== Principe de fonctionnement ===== | ||
+ | |||
+ | Le principe du fonctionnement de la validation est similaire que l’on passe par validation DNS-01 ou validation HTTP-01 : | ||
+ | |||
+ | * votre client ACME (certbot, dehydrated, autre) contacte le serveur CA ACME | ||
+ | * le serveur ACME lui retourne une chaine de caractères générée pour l’occasion | ||
+ | * le client ACME rend alors cette chaine de caractères publique : | ||
+ | * soit à une URL http:// | ||
+ | * soit dans un enregistrement DNS de type TXT *_acme-challenge.ledomaine.net* dans le cas d’une validation par DNS-01 | ||
+ | * le client ACME prévient le serveur ACME que ça a été publié | ||
+ | * le serveur ACME est désormais sûr qu’il avait affaire à quelqu’un de légitime valide alors le requête, génère le certificat demandé initialement et le transmet au client ACME | ||
+ | |||
+ | Il faut donc pouvoir publier un enregistrement DNS de type TXT sur nos serveurs Bind (en fait sur un seul ça suffit). | ||
+ | |||
+ | ===== Configurer Bind pour les mises à jour dynamiques ===== | ||
+ | |||
+ | Techniquement il est possible de configurer directement la zone parinux.org pour accepter les changements dynamiques, avec la commande // | ||
+ | |||
+ | > Zones that are under dynamic control via nsupdate or a DHCP server should not be edited by hand. Manual edits could conflict with dynamic updates and cause data to be lost. | ||
+ | |||
+ | Donc le plus simple c'est créer une délégation DNS uniquement pour // | ||
+ | |||
+ | Donc pour cela dans le fichier de zone de // | ||
+ | |||
+ | < | ||
+ | _acme-challenge NS ns1.parinux.org. | ||
+ | </ | ||
+ | |||
+ | Créer une clef secrète qui ne sera partagée qu' | ||
+ | |||
+ | < | ||
+ | cd /tmp | ||
+ | dnssec-keygen -r / | ||
+ | </ | ||
+ | |||
+ | La clef secrète se trouve dans un fichier nommé /// | ||
+ | Ensuite, créer un fichier /// | ||
+ | |||
+ | <file / | ||
+ | key " | ||
+ | algorithm hmac-sha512; | ||
+ | secret " | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | Dans le fichier /// | ||
+ | |||
+ | <file / | ||
+ | include "/ | ||
+ | zone " | ||
+ | file "/ | ||
+ | type master; | ||
+ | masterfile-format text; | ||
+ | allow-update { key " | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | Il faut maintenant peupler un minimum cette zone dynamique (un SOA et un NS). Créer le fichier /// | ||
+ | |||
+ | <file / | ||
+ | _acme-challenge.parinux.org. IN SOA troll4.parinux.org. admin.parinux.org. ( | ||
+ | | ||
+ | 86400 | ||
+ | 300 | ||
+ | | ||
+ | 86400 | ||
+ | ) | ||
+ | NS | ||
+ | </ | ||
+ | |||
+ | Permettre à Bind de modifier ce fichier : | ||
+ | |||
+ | < | ||
+ | sudo chown bind: / | ||
+ | </ | ||
+ | |||
+ | Puis '' | ||
+ | |||
+ | Maintenant on peut tester la publication dynamique. On peut déjà vérifier qu'on peut manuellement ajouter/ | ||
+ | |||
+ | < | ||
+ | sudo nsupdate -k / | ||
+ | server 127.0.0.1 | ||
+ | update delete _acme-challenge.parinux.org | ||
+ | update add _acme-challenge.parinux.org 8000 IN TXT " | ||
+ | send | ||
+ | EOF | ||
+ | </ | ||
+ | |||
+ | Puis | ||
+ | |||
+ | < | ||
+ | dig +short _acme-challenge.parinux.org | ||
+ | </ | ||
+ | Voilà. Ça, c'est fait. | ||
+ | |||
+ | ===== Certificat Wildcard avec dehydrated ===== | ||
+ | |||
+ | Sur la machine ayant besoin d'un certificat Wildcard (ici la machine xmpp-1 hébergeant ejabberd) créer le fichier /// | ||
+ | |||
+ | <file etc/ | ||
+ | key " | ||
+ | algorithm hmac-sha512; | ||
+ | secret " | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | |||
+ | Temporairement, | ||
+ | |||
+ | < | ||
+ | |||
+ | On configure dehydrated pour faire de la validation DNS-01 dans le fichier /// | ||
+ | |||
+ | <file / | ||
+ | CHALLENGETYPE=" | ||
+ | HOOK=/ | ||
+ | </ | ||
+ | |||
+ | On créé le script hook /// | ||
+ | |||
+ | < | ||
+ | # | ||
+ | |||
+ | set | ||
+ | set -u | ||
+ | set -o pipefail | ||
+ | |||
+ | NSUPDATE=" | ||
+ | DNSSERVER=" | ||
+ | TTL=300 | ||
+ | |||
+ | case " | ||
+ | " | ||
+ | printf " | ||
+ | ;; | ||
+ | " | ||
+ | printf " | ||
+ | ;; | ||
+ | " | ||
+ | # on concatène le certificat et la clef pour ejabberd. C'est pas obligatoire mais c'est plus simple. | ||
+ | cat / | ||
+ | sudo -u ejabberd ejabberdctl reload_config | ||
+ | |||
+ | ;; | ||
+ | " | ||
+ | # do nothing for now | ||
+ | ;; | ||
+ | " | ||
+ | # do nothing for now | ||
+ | ;; | ||
+ | " | ||
+ | # do nothing for now | ||
+ | ;; | ||
+ | esac | ||
+ | |||
+ | exit 0 | ||
+ | </ | ||
+ | |||
+ | Il faut rendre ce script exécutable : | ||
+ | |||
+ | < | ||
+ | |||
+ | On indique le ou les domaines qu’on souhaite dans /// | ||
+ | |||
+ | <file / | ||
+ | parinux.org *.parinux.org | ||
+ | </ | ||
+ | |||
+ | La première fois : | ||
+ | |||
+ | <code bash> | ||
+ | |||
+ | Puis on génère ou régénère les certificats : | ||
+ | |||
+ | <code bash> | ||
+ | |||
+ | Si tout s'est bien passé, alors pour peut générer un vrai certificat cette fois en supprimant le fichier /// | ||
+ | |||
+ | < | ||
+ | rm / | ||
+ | dehydrated --register --accept-terms | ||
+ | dehydrated -c --force # --force pour écraser le précédent certificat staging | ||
+ | </ | ||
+ | |||
+ | Il faut maintenant créer une tâche cron pour renouveler le certificat automatiquement. | ||
+ | On créé le fichier /// | ||
+ | |||
+ | <file / | ||
+ | #! /bin/bash | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | Et on le rend exécutable : | ||
+ | |||
+ | < | ||
+ | |||
+ | ===== Créer le certificat avec Certbot ===== | ||
+ | |||
+ | Cette méthode nécessite le plugin [[https:// | ||
+ | |||
+ | Installer les paquets nécessaires : | ||
+ | |||
+ | < | ||
+ | sudo apt install certbot python3-certbot-dns-rfc2136 | ||
+ | </ | ||
+ | |||
+ | Définir les variables qui seront utilisées par la suite : | ||
+ | |||
+ | < | ||
+ | export DOMAIN=mondomaine.net | ||
+ | export DNSSERVER=x.x.x.x | ||
+ | </ | ||
+ | |||
+ | Créer le fichier /// | ||
+ | |||
+ | < | ||
+ | cat << EOF | sudo tee / | ||
+ | dns_rfc2136_server = ${DNSSERVER} | ||
+ | dns_rfc2136_port = 53 | ||
+ | dns_rfc2136_name = rndc-acme-challenge.${DOMAIN}-key | ||
+ | dns_rfc2136_secret = xxxxxxxxxxxxxxxx | ||
+ | dns_rfc2136_algorithm = HMAC-SHA256 | ||
+ | EOF | ||
+ | </ | ||
+ | |||
+ | Avec des permissions restreintes : | ||
+ | |||
+ | < | ||
+ | |||
+ | Créer le script hook a exécuter après chaque renouvellement de certificat : | ||
+ | |||
+ | < | ||
+ | cat << EOF | sudo tee / | ||
+ | #! /bin/sh | ||
+ | systemctl reload nginx | ||
+ | EOF | ||
+ | </ | ||
+ | |||
+ | Et le rendre exécutable : | ||
+ | |||
+ | < | ||
+ | |||
+ | Puis lancer certbot certonly : | ||
+ | |||
+ | < | ||
+ | certbot certonly \ | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | -d " | ||
+ | | ||
+ | </ | ||