Featured image of post Kea DDNS : un bail DHCP devient enfin un nom DNS
Retour d’expérience

Kea DDNS : un bail DHCP devient enfin un nom DNS

Comment j’ai relié Kea à Technitium avec TSIG, séparé les clients dynamiques et corrigé deux pièges révélés par un vrai renouvellement DHCP.

Tout était vert, sauf le test qui comptait vraiment.

Kea DHCPv4, son service DDNS D2 et le Control Agent tournaient sur mes deux OPNsense. Le mode HA hot-standby annonçait 15 baux synchronisés sur 15. CARP plaçait bien ses neuf adresses virtuelles sur fw-core-p1, avec fw-core-p2 en BACKUP. Technitium refusait les mises à jour DNS non signées et un second passage Ansible ne changeait plus rien.

Il manquait pourtant les enregistrements d’un vrai client. Mon Mac avait obtenu son bail avant l’activation du DDNS et ne l’avait pas renouvelé depuis. Les timestamps n’avaient pas bougé, Kea n’avait donc encore aucune raison de publier son nom. Ce silence était cohérent avec ddns-update-on-renew, mais il laissait toute la chaîne dans la catégorie « probablement correcte ».

J’ai forcé le renouvellement de en0. Quelques secondes plus tard, macbookpro.dhcp.int.homeblack.fr existait enfin.

Laisser D2 faire le lien

Kea sépare les rôles. DHCPv4 attribue et renouvelle les baux, puis envoie une demande de changement de nom à D2. Ce dernier effectue les mises à jour DNS dynamiques RFC 2136 vers Technitium : un enregistrement A dans la zone directe, un PTR dans la zone inverse et des enregistrements DHCID pour associer le nom au client.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Client DHCP
    │ renouvellement du bail
    ▼
Kea DHCPv4 ── demande de changement ──> D2
                                           │ RFC 2136 + TSIG
                                           ▼
                                     Technitium DNS
                                      ├─ A
                                      ├─ PTR
                                      └─ DHCID

La documentation Kea sur le DDNS pour DHCPv4 décrit ces demandes, appelées NameChangeRequests. Elle précise aussi que ddns-update-on-renew force une nouvelle mise à jour à chaque renouvellement, même si le nom et l’adresse n’ont pas changé. C’est utile pour réparer automatiquement un enregistrement supprimé ou une première tentative qui aurait échoué.

Dans mon cas, le premier renouvellement contrôlé a produit le message attendu côté D2 :

1
DHCP_DDNS_ADD_SUCCEEDED

Les résolutions directe et inverse se répondaient alors correctement :

1
2
3
4
5
$ dig +short macbookpro.dhcp.int.homeblack.fr A
10.40.0.100

$ dig +short -x 10.40.0.100
macbookpro.dhcp.int.homeblack.fr.

Une requête ciblée confirmait également la présence du DHCID. Je ne voulais pas seulement qu’un nom soit publié ; je voulais que Kea puisse vérifier à quel client il appartient avant de le remplacer. C’est le rôle de ce type d’enregistrement dans le mécanisme de résolution de conflits décrit par Kea.

Une zone dynamique à l’intérieur de la zone interne

J’aurais pu publier directement macbookpro.int.homeblack.fr. J’ai préféré réserver dhcp.int.homeblack.fr aux clients dynamiques.

Cette couche supplémentaire n’a rien à voir avec le fait que le nom serait « encore plus interne ». Elle marque surtout une frontière de gestion :

  • Ansible conserve les serveurs et services statiques dans int.homeblack.fr ;
  • Kea ne peut modifier que les clients sous dhcp.int.homeblack.fr ;
  • GUEST reste volontairement exclu, contrairement à HOME, TRUSTED et IOT ;
  • un nettoyage d’anciens baux ne risque pas d’emporter un enregistrement d’infrastructure.

La règle Technitium *.dhcp.int.homeblack.fr n’est donc pas un enregistrement DNS wildcard. C’est une politique qui autorise la clé TSIG de Kea à agir uniquement sous cette zone. Les types sont eux aussi bornés : A,DHCID en direct, PTR,DHCID en inverse.

J’ai ajouté une seconde barrière avec une liste de contrôle d’accès (ACL) limitée aux deux adresses physiques des firewalls et au VIP CARP TRUSTED. Enfin, chaque transaction est signée avec une clé TSIG HMAC-SHA256, conservée dans Bitwarden et chiffrée dans Ansible Vault. Une tentative RFC 2136 sans signature retourne bien REFUSED.

L’API HTTP de Technitium permet de gérer ces options de zone, les ACL et les politiques TSIG. Je l’utilise via un rôle Ansible qui fusionne la clé avec les clés existantes au lieu de remplacer aveuglément toute la configuration.

Les deux erreurs que seul le vrai trafic a montrées

Le premier essai n’a pas fonctionné du premier coup. C’est précisément pour cela qu’il valait mieux renouveler un vrai client que s’arrêter à l’état des services.

Le premier problème concernait les zones inverses. Je les avais initialement définies trop largement. Pour le réseau 10.40.0.0/24, D2 devait cibler 0.40.10.in-addr.arpa, pas 40.10.in-addr.arpa. Les trois réseaux activés utilisent désormais chacun leur zone /24 :

1
2
3
4
technitium_kea_ddns_reverse_zones:
  - 0.20.10.in-addr.arpa
  - 0.40.10.in-addr.arpa
  - 0.80.10.in-addr.arpa

Le second était plus subtil. J’avais autorisé les adresses physiques de p1 et p2 dans l’ACL Technitium. Pendant la transaction D2, FreeBSD a pourtant choisi le VIP CARP 10.40.0.1 comme adresse source. La signature TSIG était correcte, mais la source ne figurait pas dans l’ACL : mise à jour refusée.

Ajouter le VIP n’élargit pas l’accès à tout le VLAN. La liste reste limitée à trois adresses précises : le VIP partagé et les deux membres du cluster. Après cette correction, les mises à jour A, PTR et DHCID sont passées.

Du vert, mais avec des preuves

Après le renouvellement, j’ai repris les contrôles de bout en bout :

ContrôleRésultat observé
Kea DHCPv4, D2 et Control Agentactifs sur p1 et p2
HA Keahot-standby, 15 baux sur 15 synchronisés
CARP9 MASTER sur p1, 9 BACKUP sur p2
DNS réelA, PTR et DHCID présents pour 10.40.0.100
Mise à jour non signéeREFUSED
Second passage Technitiumchanged=0

Le déploiement suit maintenant un ordre volontaire : Technitium reçoit d’abord les zones, la clé et les politiques ; Kea est configuré ensuite. Cela évite de lancer D2 vers une cible qui refuserait encore ses transactions. Les deux chemins sont idempotents et prévoient leur sauvegarde de retour arrière avant modification.

La configuration avait l’air stable avant le test. Elle l’était réellement après lui. Entre les deux, il y avait un renouvellement DHCP, deux corrections assez instructives et cette petite satisfaction de voir enfin un bail se transformer en nom, dans les deux sens.

Généré avec Hugo
Thème Stack conçu par Jimmy