Fullmoon System

Kea DDNS et BIND 9 : TSIG et mises à jour DNS directes et inverses automatiques

EdwardMoon

Kea DDNS enregistre automatiquement dans BIND 9 l'enregistrement A d'un nom d'hôte et le PTR d'une adresse lorsqu'un bail DHCP est attribué. Kea DHCPv4 ne modifie pas directement les fichiers de zone : il envoie une Name Change Request à Kea D2, qui signe avec TSIG une mise à jour dynamique RFC 2136 et l'envoie au primaire BIND 9.

Ce guide utilise le réseau 10.20.30.0/24 et le domaine interne lab.example.internal. Copier un exemple ISC DHCP ddns-update-style dans Kea ne fonctionnera pas. Coordonnez les rôles des composants, la protection des clés, les zones directes et inverses, la gestion des conflits DHCID et l'ordre de démarrage. Commandes et configurations sont séparées en blocs de code.

Flux Kea DDNS des baux DHCP aux mises à jour DNS directes et inverses dans BIND 9
DHCPv4 envoie les changements de baux à D2, qui applique des mises à jour signées TSIG aux zones directes et inverses BIND 9.

Composants et circulation des données

Ce laboratoire installe Kea DHCPv4, D2 et BIND sur un même serveur Rocky Linux 9 à l'adresse 10.20.30.53. Générez les clés, exécutez les tests nsupdate locaux et gérez les services sur ce serveur ; seule la validation cliente se fait sur un appareil distinct. Si DHCP et DNS sont séparés en production, transmettez le secret TSIG à l'hôte D2 par un canal d'administration protégé et adaptez la cible DNS de D2 et les règles de pare-feu.

Composant Adresse d'exemple Rôle
Kea DHCPv4 10.20.30.53 Gère les baux et la politique de noms ; envoie les NCR à D2
Kea D2 127.0.0.1:53001 Convertit les NCR en messages DNS UPDATE et les signe avec TSIG
BIND 9 primary 10.20.30.53:53 Serveur faisant autorité pour les zones dynamiques directes et inverses
Client 10.20.30.100~200 Fournit un nom ou FQDN dans DHCPREQUEST
  • La zone directe lab.example.internal. contient les enregistrements A associant les noms aux adresses IPv4.
  • La zone inverse 30.20.10.in-addr.arpa. contient les PTR associant les adresses IPv4 aux FQDN.
  • Les enregistrements DHCID aident à empêcher un client DHCP d'écraser un nom appartenant à un autre.
  • TSIG authentifie les mises à jour et protège leur intégrité ; il ne chiffre pas les réponses aux requêtes DNS.
Consultez conjointement la documentation officielle du serveur Kea DHCP-DDNS, les paramètres DDNS de Kea DHCPv4 et la politique de mise à jour dynamique BIND 9.

1. Vérifications préalables et paquets

Installez Kea et BIND 9 depuis les paquets maintenus de la distribution ou un dépôt ISC approuvé. Vérifiez les versions candidates et les signatures avant d'ajouter des dépôts. Les noms de paquets suivants sont des exemples pour EL9.

# Configurer d'abord le dépôt ISC 3.0 LTS utilisé dans le guide Kea DHCP.
curl --fail --location --proto '=https' --tlsv1.2 \
  https://dl.cloudsmith.io/public/isc/kea-3-0/setup.rpm.sh \
  --output /tmp/isc-kea-3-0-setup.rpm.sh
less /tmp/isc-kea-3-0-setup.rpm.sh
sudo bash /tmp/isc-kea-3-0-setup.rpm.sh

sudo dnf --showduplicates list isc-kea-dhcp4 isc-kea-dhcp-ddns bind bind-utils
sudo dnf install -y isc-kea-dhcp4 isc-kea-dhcp-ddns bind bind-utils policycoreutils-python-utils
rpm -q isc-kea-dhcp4 isc-kea-dhcp-ddns bind bind-utils
kea-dhcp4 -V
named -V
systemctl show kea-dhcp-ddns -p User -p Group -p ExecStart

Vérifiez d'abord le nom d'hôte, la synchronisation horaire, les interfaces et les conflits avec les services DHCP ou DNS déjà à l'écoute.

hostnamectl
chronyc tracking
ip -br address
sudo ss -luntp | grep -E ':(53|67|53001)\b' || true
getent passwd named
systemctl show kea-dhcp-ddns -p User -p Group

2. Générer et protéger le secret TSIG

BIND 9 et Kea D2 doivent utiliser le même secret TSIG. Générez-le en tant que root sans l'afficher ni l'inscrire dans l'historique, puis attribuez au bloc de clé BIND et au fichier secret Kea les permissions minimales nécessaires. Le nom de clé doit correspondre exactement des deux côtés, point final compris.

sudo install -d -o root -g named -m 0750 /etc/named/keys
sudo sh -c 'umask 077; tsig-keygen -a hmac-sha256 kea-ddns.lab.example.internal. > /etc/named/keys/kea-ddns.key'
sudo chown root:named /etc/named/keys/kea-ddns.key
sudo chmod 0640 /etc/named/keys/kea-ddns.key

Kea 2.5.8 et versions ultérieures prennent en charge secret-file : inutile d'insérer le secret directement dans la configuration.

# Vérifier le compte et le groupe de D2. Un paramètre systemd User vide signifie root.
D2_USER=$(systemctl show kea-dhcp-ddns -p User --value)
D2_USER=${D2_USER:-root}
D2_GROUP=$(systemctl show kea-dhcp-ddns -p Group --value)
D2_GROUP=${D2_GROUP:-$(id -gn "$D2_USER")}
sudo install -d -o root -g "$D2_GROUP" -m 0750 /etc/kea/secrets
sudo install -o root -g "$D2_GROUP" -m 0640 /dev/null /etc/kea/secrets/kea-ddns.secret
sudo awk -F'"' '/secret/{print $2}' /etc/named/keys/kea-ddns.key \
  | sudo tee /etc/kea/secrets/kea-ddns.secret >/dev/null
sudo restorecon -Rv /etc/kea/secrets
sudo stat -c '%U:%G %a %n' /etc/named/keys/kea-ddns.key /etc/kea/secrets/kea-ddns.secret
Ne copiez jamais de secrets TSIG dans des articles, des tickets, des dépôts Git ou des sorties de commande. En cas de compromission suspectée, générez une nouvelle clé, remplacez-la dans BIND et D2 selon un ordre planifié, puis révoquez l'ancienne.

3. Configurer les zones dynamiques BIND 9

Incluez le fichier de clé TSIG dans /etc/named.conf et définissez les zones primaires directe et inverse.

include "/etc/named/keys/kea-ddns.key";

zone "lab.example.internal" IN {
    type primary;
    file "dynamic/db.lab.example.internal";
    allow-update { key "kea-ddns.lab.example.internal."; };
};

zone "30.20.10.in-addr.arpa" IN {
    type primary;
    file "dynamic/db.10.20.30";
    allow-update { key "kea-ddns.lab.example.internal."; };
};

allow-update donne à la clé le droit de modifier toute la zone. Pour limiter plus finement les noms ou types d'enregistrements, concevez une update-policy BIND. N'utilisez pas les deux options dans une même zone.

Modifiez les paramètres suivants dans le bloc options existant de /etc/named.conf, sans créer un second bloc. Ce serveur fournit aussi la résolution récursive aux clients internes : limitez les requêtes et la récursion au réseau du laboratoire.

listen-on port 53 { 127.0.0.1; 10.20.30.53; };
listen-on-v6 port 53 { ::1; };
allow-query { localhost; 10.20.30.0/24; };
recursion yes;
allow-recursion { localhost; 10.20.30.0/24; };

Enregistrez les deux fichiers de zone ci-dessous sous db.lab.example.internal et db.10.20.30 dans le répertoire actuel, puis déployez-les avec les commandes install suivantes.

Fichier initial de la zone directe

$TTL 300
@   IN SOA dns01.lab.example.internal. hostmaster.lab.example.internal. (
        2026072101  ; serial
        3600        ; refresh
        900         ; retry
        604800      ; expire
        300 )       ; minimum
    IN NS  dns01.lab.example.internal.
dns01 IN A 10.20.30.53

Fichier initial de la zone inverse

$TTL 300
@   IN SOA dns01.lab.example.internal. hostmaster.lab.example.internal. (
        2026072101  ; serial
        3600        ; refresh
        900         ; retry
        604800      ; expire
        300 )       ; minimum
    IN NS  dns01.lab.example.internal.
53  IN PTR dns01.lab.example.internal.
sudo install -d -o named -g named -m 0770 /var/named/dynamic
sudo install -o named -g named -m 0660 db.lab.example.internal /var/named/dynamic/
sudo install -o named -g named -m 0660 db.10.20.30 /var/named/dynamic/
sudo restorecon -Rv /etc/named/keys /var/named/dynamic
sudo named-checkconf /etc/named.conf
sudo named-checkzone lab.example.internal /var/named/dynamic/db.lab.example.internal
sudo named-checkzone 30.20.10.in-addr.arpa /var/named/dynamic/db.10.20.30

named crée des journaux pour les zones dynamiques. Conservez les contextes SELinux du paquet et rendez inscriptible uniquement le répertoire dynamique. Ne désactivez pas SELinux et n'appliquez pas le mode 0777 à tout /var/named.

sudo systemctl enable --now named
sudo systemctl --no-pager --full status named
sudo journalctl -u named -b --no-pager | tail -n 100
dig @127.0.0.1 SOA lab.example.internal +norecurse
dig @127.0.0.1 SOA 30.20.10.in-addr.arpa +norecurse

4. Tester les mises à jour BIND indépendamment

Tester BIND et TSIG avec nsupdate avant de relier Kea réduit le périmètre du diagnostic. Ce test crée des A et PTR temporaires, les vérifie, puis les supprime.

sudo nsupdate -k /etc/named/keys/kea-ddns.key <<'EOF'
server 127.0.0.1
zone lab.example.internal.
update add ddns-test.lab.example.internal. 300 A 10.20.30.250
send
zone 30.20.10.in-addr.arpa.
update add 250.30.20.10.in-addr.arpa. 300 PTR ddns-test.lab.example.internal.
send
EOF
dig @127.0.0.1 ddns-test.lab.example.internal A +short
dig @127.0.0.1 -x 10.20.30.250 +short
sudo journalctl -u named --since '-5 minutes' --no-pager
sudo nsupdate -k /etc/named/keys/kea-ddns.key <<'EOF'
server 127.0.0.1
update delete ddns-test.lab.example.internal. A
send
update delete 250.30.20.10.in-addr.arpa. PTR
send
EOF

5. Configurer Kea D2

Configurez /etc/kea/kea-dhcp-ddns.conf comme suit. L'adresse du serveur DNS doit désigner le primaire BIND 9.

{
  "DhcpDdns": {
    "ip-address": "127.0.0.1",
    "port": 53001,
    "dns-server-timeout": 1000,
    "ncr-protocol": "UDP",
    "ncr-format": "JSON",
    "tsig-keys": [
      {
        "name": "kea-ddns.lab.example.internal.",
        "algorithm": "HMAC-SHA256",
        "secret-file": "/etc/kea/secrets/kea-ddns.secret"
      }
    ],
    "forward-ddns": {
      "ddns-domains": [
        {
          "name": "lab.example.internal.",
          "key-name": "kea-ddns.lab.example.internal.",
          "dns-servers": [ { "ip-address": "10.20.30.53", "port": 53 } ]
        }
      ]
    },
    "reverse-ddns": {
      "ddns-domains": [
        {
          "name": "30.20.10.in-addr.arpa.",
          "key-name": "kea-ddns.lab.example.internal.",
          "dns-servers": [ { "ip-address": "10.20.30.53", "port": 53 } ]
        }
      ]
    },
    "loggers": [
      { "name": "kea-dhcp-ddns", "severity": "INFO" }
    ]
  }
}
sudo kea-dhcp-ddns -t /etc/kea/kea-dhcp-ddns.conf
sudo systemctl enable --now kea-dhcp-ddns
sudo systemctl --no-pager --full status kea-dhcp-ddns
sudo ss -lunp | grep ':53001'
sudo journalctl -u kea-dhcp-ddns -b --no-pager | tail -n 100

6. Relier DHCPv4 à D2

L'exemple utilise ddns-override-client-update: true pour confier à Kea les A et PTR quand un client demande des mises à jour. Il respecte le refus de mise à jour d'un client avec ddns-override-no-update: false. Tous les appareils n'obtiendront donc pas automatiquement des A/PTR : examinez ensemble l'option FQDN et les journaux NCR réels.

L'exemple suivant montre les parties essentielles de /etc/kea/kea-dhcp4.conf. Adaptez l'interface, le routeur, le DNS et la plage au réseau réel. dhcp-ddns.enable-updates et ddns-send-updates doivent tous deux être activés pour transmettre les demandes à D2.

{
  "Dhcp4": {
    "interfaces-config": { "interfaces": [ "ens192" ] },
    "lease-database": {
      "type": "memfile",
      "persist": true,
      "name": "/var/lib/kea/kea-leases4.csv"
    },
    "renew-timer": 900,
    "rebind-timer": 1800,
    "valid-lifetime": 3600,
    "dhcp-ddns": {
      "enable-updates": true,
      "server-ip": "127.0.0.1",
      "server-port": 53001,
      "ncr-protocol": "UDP",
      "ncr-format": "JSON"
    },
    "ddns-send-updates": true,
    "ddns-override-no-update": false,
    "ddns-override-client-update": true,
    "ddns-replace-client-name": "when-not-present",
    "ddns-generated-prefix": "host",
    "ddns-qualifying-suffix": "lab.example.internal",
    "ddns-update-on-renew": false,
    "ddns-conflict-resolution-mode": "check-with-dhcid",
    "subnet4": [
      {
        "id": 100,
        "subnet": "10.20.30.0/24",
        "pools": [ { "pool": "10.20.30.100 - 10.20.30.200" } ],
        "option-data": [
          { "name": "routers", "data": "10.20.30.1" },
          { "name": "domain-name-servers", "data": "10.20.30.53" },
          { "name": "domain-name", "data": "lab.example.internal" }
        ]
      }
    ],
    "loggers": [ { "name": "kea-dhcp4", "severity": "INFO" } ]
  }
}

ddns-replace-client-name ne génère ici un nom que s'il manque. Si la politique impose un nom attribué par le serveur à tous les clients, envisagez always, après avoir défini des réservations et règles de nommage évitant les conflits avec les noms existants.

sudo kea-dhcp4 -t /etc/kea/kea-dhcp4.conf
sudo systemctl enable --now kea-dhcp4
sudo systemctl --no-pager --full status kea-dhcp4
sudo ss -lunp | grep -E ':(67|53001)\b'
sudo journalctl -u kea-dhcp4 -b --no-pager | tail -n 100

7. Vérifier les véritables enregistrements A, PTR et DHCID

Obtenez un nouveau bail sur un client de test, puis interrogez les DNS direct et inverse avec l'adresse et le FQDN réellement attribués. Renouveler le bail d'une interface en production peut la déconnecter : utilisez une console ou un appareil de test distinct.

# Renouveler le bail du client de test selon la méthode adaptée à son environnement
sudo dhclient -r ens192
sudo dhclient -v ens192
ip -4 address show dev ens192
dig @10.20.30.53 client01.lab.example.internal A +noall +answer
dig @10.20.30.53 -x 10.20.30.101 +noall +answer
dig @10.20.30.53 client01.lab.example.internal DHCID +noall +answer
sudo journalctl -u kea-dhcp4 -u kea-dhcp-ddns -u named \
  --since '-10 minutes' --no-pager
Symptôme Première vérification Cause typique
Ni A ni PTR Journaux DHCPv4 et UDP 53001 Liaison D2 désactivée, politique de noms ou service D2 arrêté
Seul A est créé Domaines reverse-ddns et zone inverse Nom de zone inverse ou adresse DNS incorrects
NOTAUTH Primaire BIND et déclarations de zones Mise à jour envoyée au secondaire ou nom de zone incorrect
NOTAUTH ou REFUSED Nom, secret et algorithme TSIG Clé différente ou autorisation allow-update manquante
YXDOMAIN ou conflit Enregistrements A/DHCID existants et identifiant client Un autre client possède le même nom

Gérer les zones dynamiques sans modifier directement les fichiers actifs

Pendant l'exécution de named, une zone dynamique est gérée avec son journal .jnl. Modifier directement le fichier peut entraîner l'écrasement des changements ou une incohérence avec le journal. Si une intervention manuelle est nécessaire, synchronisez la zone, gelez-la, effectuez et validez la modification, puis dégelez-la.

sudo rndc freeze lab.example.internal
sudoedit /var/named/dynamic/db.lab.example.internal
sudo named-checkzone lab.example.internal /var/named/dynamic/db.lab.example.internal
sudo rndc thaw lab.example.internal
sudo rndc zonestatus lab.example.internal
Ne supprimez pas en bloc les fichiers .jnl ou les enregistrements A/PTR/DHCID pour faire disparaître les erreurs. Examinez d'abord le propriétaire du bail DHCP et les enregistrements directs, inverses et DHCID, puis planifiez l'arrêt du service, la sauvegarde et la récupération.

Vérifier le pare-feu, SELinux et les permissions

Les clients ont besoin du port 53 TCP et UDP vers le serveur DNS faisant autorité, ainsi que des ports DHCP correspondants entre serveur et clients. D2 écoute sur UDP 53001 uniquement sur le bouclage du même hôte : n'exposez pas ce port à l'extérieur.

sudo firewall-cmd --get-active-zones
sudo firewall-cmd --permanent --zone=internal --add-service=dns
sudo firewall-cmd --permanent --zone=internal --add-service=dhcp
sudo firewall-cmd --reload
sudo firewall-cmd --zone=internal --list-all
sudo ss -luntp | grep -E ':(53|67|53001)\b'
sudo ausearch -m AVC -ts recent | tail -n 50
Désactiver firewalld ou SELinux ne résout pas le problème. Autorisez named à écrire uniquement dans le répertoire dynamique, limitez le fichier secret de D2 à root et au véritable compte d'exécution, et accordez les droits TSIG uniquement sur les zones nécessaires.

Haute disponibilité, sauvegarde et supervision

  1. Vérifier par des tests de bascule que les deux serveurs Kea HA peuvent atteindre D2 et le DNS faisant autorité.
  2. Synchroniser les secondaires DNS par NOTIFY et IXFR/AXFR depuis le primaire, et cibler explicitement ce primaire pour les mises à jour D2.
  3. Sauvegarder la configuration Kea, les bases de baux, la configuration BIND, les zones, journaux et clés TSIG selon leur niveau de sensibilité.
  4. Restreindre la restauration des clés et répéter régulièrement leur rotation et l'ordre de redémarrage des services.
  5. Surveiller les files D2, les résultats DNS UPDATE, les divergences A/PTR et les numéros de série des zones, en plus de la réussite des baux.
sudo systemctl is-active kea-dhcp4 kea-dhcp-ddns named
sudo kea-dhcp4 -t /etc/kea/kea-dhcp4.conf
sudo kea-dhcp-ddns -t /etc/kea/kea-dhcp-ddns.conf
sudo named-checkconf -z /etc/named.conf
sudo rndc status
sudo rndc zonestatus lab.example.internal

Articles associés

Conclusion

Un déploiement Kea DDNS sûr valide les frontières par étapes : zones BIND, test TSIG indépendant, liaison D2, puis bail DHCP réel. Examinez ensemble les A directs, PTR inverses et DHCID. Intégrez permissions des secrets, journaux des zones dynamiques, sauvegardes et rotation des clés aux procédures pour que l'automatisation préserve la cohérence des données.