isc-dhcp: create zones using rndc
authorDavid Härdeman <[email protected]>
Sun, 3 Aug 2025 20:10:53 +0000 (22:10 +0200)
committerNoah Meyerhans <[email protected]>
Sat, 13 Sep 2025 20:36:41 +0000 (13:36 -0700)
This changes isc-dhcp's init script to create bind zones using the tools
bind provides for that scenario instead of crafting separate zone
configuration by hand.

At the same time, remove the use of /tmp/bind/named.conf.local and add
permissions for dynamic zone creation to bind.

Signed-off-by: David Härdeman <[email protected]>
net/bind/files/bind/named.conf
net/bind/files/named.init
net/isc-dhcp/Makefile
net/isc-dhcp/files/dhcpd.init

index dd44932c9619b9dcd488a2268debe04437c52094..8eb6be694d0cc8f25ac35e1f2be3d76bce09bde6 100644 (file)
@@ -4,9 +4,10 @@ options {
        // Default directory for ephemeral zones, long-lived zones
        // can be stored under /var/lib/bind (aka /etc/bind/zones)
        directory "/var/cache/bind";
-};
 
-include "/tmp/bind/named.conf.local";
+       // This is used e.g. by isc-dhcp
+       allow-new-zones yes;
+};
 
 // prime the server with knowledge of the root servers
 zone "." {
index 7f09bf6b510d6d84d89005c13f8ac96790b294cf..fd9130be0ae810fe6632845082c23ce5adbd8a79 100644 (file)
@@ -15,7 +15,6 @@ zone_dir=$config_dir/zones
 lib_dir=/var/lib/bind
 
 config_file=$config_dir/named.conf
-config_local_file=$dyn_dir/named.conf.local
 
 reload_service() {
        rndc -q reload
@@ -44,8 +43,6 @@ start_service() {
                chmod 0640 /etc/bind/rndc.key
        fi
 
-       touch $config_local_file
-
        if [ -z "$(ip -6 -o route show default)" ]; then
                args="-4"
        else
@@ -54,7 +51,7 @@ start_service() {
 
        procd_open_instance
        procd_set_param command /usr/sbin/named -u bind -f $args -c $config_file
-       procd_set_param file $config_file $config_local_file $config_dir/db.*
+       procd_set_param file $config_file $config_dir/db.*
        procd_set_param respawn
        procd_close_instance
 }
index d46429cc0b36d2baa13bada5ef7f2e4b63424cd3..f4486423144abfa90a40e4024fd80f14d1fa9614 100644 (file)
@@ -11,7 +11,7 @@ PKG_NAME:=isc-dhcp
 UPSTREAM_NAME:=dhcp
 PKG_REALVERSION:=4.4.3-P1
 PKG_VERSION:=4.4.3_p1
-PKG_RELEASE:=10
+PKG_RELEASE:=11
 
 PKG_LICENSE:=BSD-3-Clause
 PKG_LICENSE_FILES:=LICENSE
@@ -136,7 +136,10 @@ endef
 define Package/isc-dhcp-dyndns
   $(call Package/isc-dhcp/Default)
   TITLE+= server dynamic DNS dependencies (meta)
-  DEPENDS+=@(PACKAGE_isc-dhcp-server-ipv4||PACKAGE_isc-dhcp-server-ipv6) +bind-server +bind-client
+  DEPENDS+=@(PACKAGE_isc-dhcp-server-ipv4||PACKAGE_isc-dhcp-server-ipv6) \
+       +bind-server \
+       +bind-rndc \
+       +bind-client
 endef
 
 define Package/isc-dhcp-dyndns/description
index 66b76061755b042d173a7bed4802fccbca0374fd..5b5f2b4e03797051a3e1dfdb4b1ad742cefe244f 100755 (executable)
@@ -11,8 +11,7 @@ PREFIX="update add"
 lease_file=/tmp/dhcpd.leases
 config_file=/tmp/run/dhcpd.conf
 
-dyndir=/tmp/bind
-conf_local_file=$dyndir/named.conf.local
+dyndir=/var/run/dhcp
 
 session_key_name=local-ddns
 session_key_file=/var/run/named/session.key
@@ -134,13 +133,55 @@ rev_str() {
        echo "$result"
 }
 
+write_empty_zone() {
+       local zpath
+       zpath="$1"
+
+       cat > "$zpath" <<\EOF
+;
+; BIND empty zone created by isc-dhcp-server
+;
+$TTL   604800
+@      IN      SOA     localhost. root.localhost. (
+                             1         ; Serial
+                        604800         ; Refresh
+                         86400         ; Retry
+                       2419200         ; Expire
+                        604800 )       ; Negative Cache TTL
+;
+@      IN      NS      localhost.
+EOF
+}
+
 create_empty_zone() {
-       local zone="$1"
+       local zone error zpath
+       zone="$1"
+       zpath="$dyndir/db.$zone"
+
+       if [ ! -d "$dyndir" ]; then
+               mkdir -p "$dyndir" || return 1
+               chown bind:bind "$dyndir" || return 1
+       fi
 
-       if [ ! -f $dyndir/db."$zone" ]; then
-               cp -p /etc/bind/db.empty $dyndir/db."$zone"
-               chmod g+w $dyndir/db."$zone"
-               chgrp bind $dyndir/db."$zone"
+       write_empty_zone "$zpath"
+       chown bind:bind "$zpath" || return 1
+       chmod 0664 "$zpath" || return 1
+
+       if ! error=$(rndc addzone $zone "{
+               type primary;
+               file \"$zpath\";
+               update-policy {
+                       grant $session_key_name zonesub any;
+               };
+       };" 2>&1); then
+               case "$error" in
+                       *"already exists"*)
+                               ;;
+                       *)
+                               logger -p info -t isc-dhcp "Failed to add zone $zone: $error"
+                               return 1
+                               ;;
+               esac
        fi
 }
 
@@ -523,6 +564,8 @@ general_config() {
        [ $? -ne 0 ] && return 1
 
        if [ $dynamicdns -eq 1 ]; then
+               rndc freeze
+
                create_empty_zone "$domain"
 
                local mynet
@@ -532,40 +575,7 @@ general_config() {
                        create_empty_zone "$mynet.in-addr.arpa"
                done
 
-               local need_reload=
-
-               cp -p $conf_local_file ${conf_local_file}_
-
-               cat <<EOF > $conf_local_file
-zone "$domain" {
-       type master;
-       file "$dyndir/db.$domain";
-       update-policy {
-               grant $session_key_name zonesub any;
-       };
-};
-
-EOF
-
-               for mynet in $rfc1918_nets; do
-                       mynet="$(rev_str "$mynet" ".")"
-                       cat <<EOF >> $conf_local_file
-zone "$mynet.in-addr.arpa" {
-       type master;
-       file "$dyndir/db.$mynet.in-addr.arpa";
-       update-policy {
-               grant $session_key_name zonesub any;
-       };
-};
-
-EOF
-               done
-
-               cmp -s $conf_local_file ${conf_local_file}_ || need_reload=1
-               rm -f ${conf_local_file}_
-
-               [ -n "$need_reload" ] && /etc/init.d/named reload
-               sleep 1
+               rndc thaw
 
                cat <<EOF
 ddns-domainname "$domain.";