Rôle dans l'architecture
Les certificats TLS sécurisent tous les services exposés du homelab. Le renouvellement est entièrement automatisé par le défi DNS-01 : le client ACME prouve la propriété du domaine en créant un enregistrement TXT dans la zone, que l'autorité vient vérifier.
Flux de renouvellement
sequenceDiagram
actor Admin
participant Certbot as Client ACME
participant BIND9 as Resolveur DNS
participant LE as Autorite de certification
participant HAP as Terminaison TLS
Admin->>Certbot: demande de certificat
activate Certbot
Certbot->>BIND9: nsupdate signe TSIG
Note over BIND9: cree l enregistrement de defi
Certbot->>LE: demande de validation
activate LE
LE->>BIND9: interrogation TXT du defi
BIND9-->>LE: reponse
LE-->>Certbot: certificat delivre
deactivate LE
Certbot->>BIND9: nsupdate supprime le defi
Certbot->>HAP: depot du fichier PEM
deactivate Certbot
Pourquoi DNS-01 plutôt que HTTP-01
Le défi HTTP-01 exige que le serveur web soit joignable depuis Internet sur le port 80. Dans une architecture à plusieurs couches — terminaison TLS, routage applicatif, pare-feu applicatif, backend — il faudrait ouvrir un chemin ACME à travers chacune d'elles, et le maintenir ouvert.
Le défi DNS-01 déplace le problème là où il est déjà résolu : seul le serveur DNS doit être joignable depuis l'extérieur, ce qui est le cas par construction. Aucune couche HTTP n'a besoin de connaître ACME.
Une politique de mise à jour restreinte au défi
La zone publique n'autorise les mises à jour dynamiques que sur les enregistrements de défi, et pour aucun autre nom :
zone "jbsky.fr" {
type master;
file "/etc/bind/db.jbsky.fr";
update-policy {
grant tsig-key name _acme-challenge.jbsky.fr. TXT;
grant tsig-key name _acme-challenge.www.jbsky.fr. TXT;
grant tsig-key name _acme-challenge.mail.jbsky.fr. TXT;
grant tsig-key name _acme-challenge.home.jbsky.fr. TXT;
};
};
C'est le point qui limite les dégâts en cas de fuite de la clé : elle ne permet d'écrire que des enregistrements de défi, pas de détourner un nom de service.
L'interaction avec les vues, qui n'est pas évidente
Le résolveur est en split-horizon : il sert une vue différente selon le sous-réseau du client. Une mise à jour signée arrivant du réseau interne tomberait donc dans une vue qui n'a pas la politique de mise à jour, et se verait refusée.
La parade tient dans la sélection des clients : les vues par sous-réseau excluent explicitement les requêtes signées, ce qui fait tomber toute mise à jour signée dans la vue publique — la seule qui sait quoi en faire. L'architecture de vues est détaillée dans le DNS split-horizon.
Une clé de signature éphémère
flowchart LR
gen["Generation<br/>cle aleatoire"] --> val["Validation<br/>configuration et zones"]
val --> dep["Deploiement<br/>cote resolveur"]
dep --> inj["Injection<br/>cote client ACME"]
style gen fill:#4a9,color:#fff
style inj fill:#e74,color:#fff
La clé de signature est régénérée à chaque exécution du pipeline et n'est jamais stockée dans le dépôt. Elle est déposée en même temps des deux côtés — le résolveur qui l'accepte, le client qui l'utilise.
La conséquence opérationnelle vaut d'être dite : en cas de suspicion de compromission, il n'y a pas de procédure de rotation à écrire, un simple déclenchement du pipeline remplace la clé. La rotation n'est pas une opération exceptionnelle, c'est le fonctionnement normal.
Le fichier journal des mises à jour dynamiques
Une zone qui reçoit des mises à jour dynamiques s'accompagne d'un fichier journal posé à côté d'elle. Il fait partie de l'état de la zone, pas des artefacts temporaires.
Le synchroniser en même temps que la zone est donc obligatoire : l'exclure laisse le résolveur avec une zone et un journal qui décrivent deux instants différents, et la mise à jour suivante échoue.
L'ordre d'ajout d'un domaine n'est pas commutatif
C'est le piège qui coûte le plus cher, parce qu'il ne casse pas le nouveau domaine — il casse tous les autres.
La terminaison TLS refuse catégoriquement de démarrer si un fichier PEM référencé dans sa liste de certificats n'existe pas. Ajouter la référence avant d'avoir produit le certificat met donc l'ensemble des sites hors ligne, pas seulement celui qu'on ajoutait.
flowchart TB
A["DNS : enregistrement et autorisation de defi"] --> B["Declarer le domaine cote client ACME"]
B --> C["Deployer la configuration"]
C --> D["Generer le certificat"]
D --> E{"Le PEM existe-t-il vraiment ?"}
E -->|"Non"| D
E -->|"Oui"| F["Seulement alors : referencer dans la terminaison TLS"]
F --> G["Deployer"]
style E fill:#f90,color:#fff
style F fill:#4a9,color:#fff
La vérification du losange n'est pas une précaution de style : c'est la seule étape qui empêche une panne globale à partir d'un ajout anodin.
Certificats gérés
| Certificat | Domaines | Renouvellement |
|---|---|---|
| principal | le domaine racine, le www et le service de messagerie |
1er et 15 du mois |
| domotique | le sous-domaine de la domotique | 8 et 22 du mois |
Les dates sont décalées volontairement : deux renouvellements qui échoueraient pour la même raison ne tombent pas le même jour, ce qui laisse une fenêtre pour s'en apercevoir.