Fullmoon System

Kea DDNS mit BIND 9: TSIG und automatische Vorwärts- und Rückwärtsauflösung

EdwardMoon

Kea DDNS registriert bei der DHCP-Adressvergabe automatisch den A-Eintrag des Hostnamens und den PTR-Eintrag der IP-Adresse in BIND 9. Kea DHCPv4 bearbeitet die Zonendateien dabei nicht selbst. Es sendet einen Name Change Request an Kea D2, das ein dynamisches Update nach RFC 2136 mit TSIG signiert und an den BIND-9-Primary übermittelt.

Die Beispiele verwenden das Netz 10.20.30.0/24 und die interne Domain lab.example.internal. Eine frühere ISC-DHCP-Konfiguration mit ddns-update-style lässt sich nicht unverändert auf Kea übertragen. Rollentrennung, Schlüsselschutz, übereinstimmende Vorwärts- und Rückwärtszonen, DHCID-Konfliktbehandlung und Dienststartreihenfolge müssen zusammenpassen. Befehle und Einstellungen stehen in eigenen Codeblöcken.

Kea DDNS: DHCP-Leases aktualisieren Vorwärts- und Rückwärts-DNS in BIND 9
DHCPv4 übermittelt Lease-Änderungen an D2; D2 sendet TSIG-signierte Updates an die Vorwärts- und Rückwärtszonen von BIND 9.

Komponenten und Datenfluss

In dieser Übung laufen Kea DHCPv4, D2 und BIND gemeinsam auf dem Rocky-Linux-9-Server 10.20.30.53. Schlüsselerzeugung, lokales nsupdate und Dienstbefehle werden daher auf diesem Server ausgeführt; nur die Clientprüfung findet auf einem separaten Testgerät statt. Werden DHCP und DNS produktiv getrennt, das TSIG-Geheimnis über einen geschützten Verwaltungskanal auf den D2-Host verteilen und DNS-Zieladresse sowie Firewall anpassen.

Komponente Beispieladresse Aufgabe
Kea DHCPv4 10.20.30.53 Adressvergabe, Hostnamenrichtlinie und NCR-Versand an D2
Kea D2 127.0.0.1:53001 NCR in DNS-UPDATE-Nachricht umwandeln und mit TSIG signieren
BIND 9 primary 10.20.30.53:53 Autoritativer Server für dynamische Vorwärts- und Rückwärtszonen
Client 10.20.30.100~200 Name oder FQDN im DHCPREQUEST bereitstellen
  • In der Vorwärtszone lab.example.internal. entstehen A-Einträge zur Auflösung von Hostnamen in IPv4-Adressen.
  • In der Rückwärtszone 30.20.10.in-addr.arpa. entstehen PTR-Einträge zur Auflösung von IPv4-Adressen in FQDNs.
  • DHCID-Einträge verringern Konflikte, bei denen ein anderer DHCP-Client denselben Namen überschreiben würde.
  • TSIG schützt Authentizität und Integrität der Update-Nachricht, verschlüsselt aber nicht die DNS-Abfrageantworten selbst.
Offizielle Dokumentation: Kea DHCP-DDNS Server, DDNS-Konfiguration für Kea DHCPv4, Richtlinien für dynamische Updates in BIND 9 gemeinsam prüfen.

Schritt 1: Vorabprüfungen und Pakete

Kea und BIND 9 aus unterstützten Distributionspaketen oder einem freigegebenen ISC-Repository installieren. Vor dem Hinzufügen einer Quelle Versionen und Signaturen prüfen. Die folgenden Paketnamen sind Beispiele für EL9-Systeme.

# Zuerst dasselbe ISC-3.0-LTS-Repository wie im Kea-DHCP-Leitfaden vorbereiten.
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

Zuerst Hostname, Uhrzeit, Schnittstellen und Konflikte mit vorhandenen DHCP- oder DNS-Listenern prüfen.

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

Schritt 2: TSIG-Schlüssel erzeugen und Zugriffsrechte trennen

BIND 9 und Kea D2 müssen dasselbe TSIG-Geheimnis verwenden. Den Schlüssel nicht auf dem Bildschirm oder im Shell-Verlauf ausgeben. Als root erzeugen und BIND-Schlüsselblock sowie Kea-Geheimnisdatei jeweils mit minimalen Rechten ablegen. Der Schlüsselname muss einschließlich abschließendem Punkt auf beiden Seiten exakt übereinstimmen.

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

Ab Kea 2.5.8 kann secret-file verwendet werden, statt das Geheimnis direkt in die Konfiguration einzutragen.

# Tatsächliches D2-Konto und Gruppe prüfen; ein leeres systemd-User-Feld bedeutet 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
TSIG-Geheimnisse nicht in Beiträge, Tickets, Git-Repositories oder Befehlsausgaben kopieren. Bei Verdacht auf Offenlegung einen neuen Schlüssel erstellen, BIND und D2 in geplanter Reihenfolge umstellen und den alten Schlüssel anschließend verwerfen.

Schritt 3: dynamische BIND-9-Zonen konfigurieren

In /etc/named.conf die TSIG-Schlüsseldatei einbinden und primäre Vorwärts- sowie Rückwärtszone definieren.

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 gewährt dem Schlüssel Update-Rechte für die gesamte Zone. Für feinere Namens- oder Record-Beschränkungen update-policy entwerfen. Beide Optionen dürfen nicht gleichzeitig in derselben Zone verwendet werden.

In /etc/named.conf die folgenden Einträge innerhalb des vorhandenen options-Blocks ändern. Keinen zweiten options-Block hinzufügen. Da der Server auch rekursives DNS für interne Clients anbietet, Abfragen und Rekursion auf das Übungsnetz begrenzen.

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; };

Die folgenden Zonendateien im aktuellen Arbeitsverzeichnis als db.lab.example.internal und db.10.20.30 speichern und anschließend mit dem gezeigten install-Befehl ablegen.

Ausgangsdatei der Vorwärtszone

$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

Ausgangsdatei der Rückwärtszone

$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 erzeugt die Journaldateien dynamischer Zonen selbst. SELinux nicht deaktivieren und /var/named nicht pauschal auf 0777 setzen. Die Paket-Standardkontexte erhalten und nur das dynamic-Verzeichnis beschreibbar machen.

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

Schritt 4: BIND-Updates separat testen

Vor der Anbindung von Kea zunächst BIND und TSIG allein mit nsupdate testen. So lässt sich ein Fehlerbereich eingrenzen. Der Test legt temporäre A- und PTR-Einträge an, prüft sie und entfernt sie wieder.

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

Schritt 5: Kea D2 konfigurieren

/etc/kea/kea-dhcp-ddns.conf wie folgt einrichten. Die DNS-Serveradresse muss auf den BIND-9-Primary zeigen.

{
  "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

Schritt 6: DHCPv4 mit D2 verbinden

Mit ddns-override-client-update: true übernimmt Kea in diesem Beispiel A und PTR, wenn der Client Updates anfordert. Ein clientseitiges Update-Verbot wird durch ddns-override-no-update: false respektiert. Deshalb entstehen nicht zwingend für jedes Endgerät A- und PTR-Einträge. FQDN-Option und tatsächliche NCR-Logs gemeinsam prüfen.

Das folgende Beispiel zeigt die wesentlichen Teile von /etc/kea/kea-dhcp4.conf. Schnittstelle, Router, DNS-Adresse und Pool an das tatsächliche Netz anpassen. Sowohl dhcp-ddns.enable-updates als auch ddns-send-updates müssen aktiv sein, damit Anfragen an D2 gesendet werden.

{
  "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 erzeugt hier nur dann einen Namen, wenn keiner vorhanden ist. Soll der Server gemäß Verwaltungsrichtlinie alle Namen bestimmen, kann always geprüft werden. Zuerst jedoch Reservierungs- und Namensregeln entwerfen, die nicht mit bestehenden Clientnamen kollidieren.

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

Schritt 7: tatsächliche A-, PTR- und DHCID-Einträge prüfen

Auf dem Testclient eine neue DHCP-Lease beziehen und anhand der tatsächlich vergebenen Adresse und des FQDN sowohl Vorwärts- als auch Rückwärtsauflösung abfragen. Eine Lease-Erneuerung an einer produktiven Schnittstelle kann die Verbindung unterbrechen; deshalb über Konsole oder ein separates Testgerät durchführen.

# Lease auf dem Testclient mit einem zur Umgebung passenden Verfahren erneuern
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
Symptom Zuerst prüfen Typische Ursache
Weder A noch PTR vorhanden DHCPv4-Logs und UDP 53001 D2-Verbindung deaktiviert, Namensrichtlinie oder gestopptes D2
Nur A wird erzeugt reverse-ddns-Domain und Rückwärtszone Falscher Rückwärtszonenname oder abweichende DNS-Serveradresse
NOTAUTH BIND-Primary und Zonendefinition Update an Secondary gesendet oder Zonenname abweichend
NOTAUTH oder REFUSED TSIG-Schlüsselname, Geheimnis und Algorithmus Schlüssel stimmen nicht überein oder allow-update fehlt
YXDOMAIN oder Konflikt Bestehende A- und DHCID-Einträge sowie Clientbezeichner Ein anderer Client besitzt bereits denselben Namen

Dynamische Zonendateien im Betrieb nicht direkt bearbeiten

Eine laufende dynamische Zone wird von named zusammen mit ihrem .jnl-Journal verwaltet. Direkte Dateibearbeitung kann überschrieben werden oder zu Abweichungen vom Journal führen. Ist ein manueller Eingriff erforderlich, zuerst synchronisieren, die Zone mit freeze anhalten, Änderungen prüfen und anschließend mit thaw wieder freigeben.

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
.jnl-Dateien sowie A-, PTR- und DHCID-Einträge nicht pauschal löschen, um Fehler schnell zu beseitigen. Zuerst DHCP-Lease-Eigentümer, Vorwärts- und Rückwärtseinträge sowie DHCID gemeinsam prüfen und Dienststopp, Sicherung und Wiederherstellung planen.

Firewall, SELinux und Rechte prüfen

Zwischen Clients und autoritativem DNS-Server werden TCP und UDP 53 benötigt; zwischen DHCP-Server und Clients die DHCP-Ports. D2 ist auf UDP 53001 nur an Loopback desselben Hosts gebunden und benötigt keine externe Freigabe.

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
Das Abschalten von firewalld oder SELinux löst die Ursache nicht. named darf nur in das dynamic-Verzeichnis schreiben. Das D2-Geheimnis dürfen ausschließlich root und das tatsächliche D2-Dienstkonto lesen; TSIG-Rechte auf die benötigten Zonen begrenzen.

Checkliste für HA, Sicherung und Monitoring

  1. Durch Failover-Tests prüfen, dass beide DHCP-Server einer Kea-HA-Konfiguration D2 und autoritatives DNS erreichen.
  2. DNS-Secondaries über NOTIFY und IXFR/AXFR vom Primary synchronisieren; D2-Updates ausdrücklich an den Primary richten.
  3. Kea-Konfiguration, Lease-Datenbank, BIND-Konfiguration, Zonen, Journale und TSIG-Schlüssel gemäß unterschiedlichen Schutzklassen sichern.
  4. Rechte zur Schlüsselwiederherstellung begrenzen und Schlüsselwechsel sowie Dienstneustartreihenfolge regelmäßig üben.
  5. Neben erfolgreichen DHCP-Leases auch D2-Warteschlange, DNS-UPDATE-Ergebnisse, A-/PTR-Abweichungen und Zonenseriennummern beobachten.
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

Weiterführende Artikel

Zusammenfassung

Kea DDNS schrittweise prüfen: zuerst BIND-Zonen, dann TSIG allein, danach D2-Anbindung und schließlich tatsächliche DHCP-Leases. A-, PTR- und DHCID-Einträge gemeinsam beobachten. Geheimnisrechte, Journale dynamischer Zonen, Sicherungen und Schlüsselwechsel gehören zum Betrieb, damit die Automatisierung die Datenkonsistenz bewahrt.