isc-dhcp: add dynamic dns integration for local bind server 14240/head
authorPhilip Prindeville <philipp@redfish-solutions.com>
Tue, 15 Dec 2020 20:39:34 +0000 (13:39 -0700)
committerPhilip Prindeville <philipp@redfish-solutions.com>
Wed, 13 Jan 2021 18:43:52 +0000 (11:43 -0700)
Start after named is running.

Add support for "cname", "domain", "mxhost", and "srvhost" configs.

Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
net/isc-dhcp/Makefile
net/isc-dhcp/files/dhcpd.init

index a92763b90b8b2e4a216f3f739b102bda360f760b..68c60e58a5f4274e3ede2fabbeb9bf4f1aacbbc3 100644 (file)
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
 PKG_NAME:=isc-dhcp
 UPSTREAM_NAME:=dhcp
 PKG_VERSION:=4.4.1
-PKG_RELEASE:=11
+PKG_RELEASE:=12
 
 PKG_LICENSE:=BSD-3-Clause
 PKG_LICENSE_FILES:=LICENSE
@@ -109,12 +109,14 @@ define Package/isc-dhcp-server-ipv4
   $(call Package/isc-dhcp/Default)
   TITLE+= server (without IPv6)
   VARIANT:=ipv4
+  DEPENDS+=bind-server bind-client
 endef
 
 define Package/isc-dhcp-server-ipv6
   $(call Package/isc-dhcp/Default)
   TITLE+= server (with IPv6)
   VARIANT:=ipv6
+  DEPENDS+=bind-server bind-client
 endef
 
 define Package/isc-dhcp-server/description
index a5de526686df08723c020c554ccf8336df7f3d3c..2c8d21b25eec2f8b575637fb5689a5e5c08d0ad0 100755 (executable)
@@ -1,12 +1,23 @@
 #!/bin/sh /etc/rc.common
 
-START=19
+START=25
 USE_PROCD=1
 PROG=/usr/sbin/dhcpd
 
+TTL=3600
+PREFIX="update add"
+
 lease_file=/tmp/dhcpd.leases
 config_file=/tmp/run/dhcpd.conf
 
+dyndir=/tmp/bind
+conf_local_file=$dyndir/named.conf.local
+
+session_key_name=local-ddns
+session_key_file=/var/run/named/session.key
+
+dyn_file=$(mktemp -u /tmp/dhcpd.XXXXXX)
+
 time2seconds() {
        local timestring=$1
        local multiplier number suffix
@@ -67,12 +78,36 @@ typeof() {
 '
 }
 
+rev_quad() {
+       local ip="$1"
+
+       echo "$ip" | awk -F '.' '{ printf "%s.%s.%s.%s\n", $4, $3, $2, $1; }'
+}
+
+update() {
+       local lhs="$1" family="$2" type="$3"
+       shift 3
+
+       echo -e "$PREFIX" "$lhs $family $type $@\nsend"
+}
+
 explode() {
        local arg="$1"
 
        echo "$arg" | sed -e 's/\./, /g'
 }
 
+create_empty_zone()
+{
+       local zone="$1"
+
+       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"
+       fi
+}
+
 append_routes() {
        local tuple tuples="$1"
        local string=
@@ -122,6 +157,85 @@ append_dhcp_options() {
        echo " option $tag $formatted;"
 }
 
+static_cname_add() {
+       local cfg="$1"
+       local cname target
+
+       config_get cname "$cfg" "cname"
+       [ -n "$cname" ] || return 0
+       config_get target "$cfg" "target"
+       [ -n "$target" ] || return 0
+
+       update "$cname.$domain." IN CNAME "$target.$domain."
+}
+
+static_cnames() {
+       config_foreach static_cname_add cname "$@"
+}
+
+static_domain_add() {
+       local cfg="$1"
+       local name ip revip
+
+       config_get name "$cfg" "name"
+       [ -n "$name" ] || return 0
+       config_get ip "$cfg" "ip"
+       [ -n "$ip" ] || return 0
+
+       revip="$(rev_quad "$ip")"
+
+       update "$name.$domain." IN A "$ip"
+       update "$revip.in-addr.arpa." IN PTR "$name.$domain."
+}
+
+static_domains() {
+       config_foreach static_domain_add domain "$@"
+}
+
+static_mxhost_add() {
+       local cfg="$1"
+       local domain2 relay pref
+
+       config_get domain2 "$cfg" "domain"
+       [ -n "$domain2" ] || return 0
+       config_get relay "$cfg" "relay"
+       [ -n "$relay" ] || return 0
+       config_get pref "$cfg" "pref"
+       [ -n "$pref" ] || return 0
+
+       if [ "$domain2" = "@" ]; then
+               update "$domain." IN MX "$pref" "$relay.$domain."
+       else
+               update "$domain2.$domain." IN MX "$pref" "$relay.$domain."
+       fi
+}
+
+static_mxhosts() {
+       config_foreach static_mxhost_add mxhost "$@"
+}
+
+static_srvhost_add() {
+       local cfg="$1"
+       local srv target port priority weight
+
+       config_get srv "$cfg" "srv"
+       [ -n "$srv" ] || return 0
+       config_get target "$cfg" "target"
+       [ -n "$target" ] || return 0
+       config_get port "$cfg" "port"
+       [ -n "$port" ] || return 0
+       config_get priority "$cfg" "priority"
+       [ -n "$priority" ] || return 0
+       config_get weight "$cfg" "weight"
+       [ -n "$weight" ] || return 0
+
+       update "$srv.$domain." IN SRV "$priority" "$weight" "$port" "$target"
+}
+
+static_srvhosts() {
+       config_foreach static_srvhost_add srvhost "$@"
+}
+
 static_host_add() {
        local cfg="$1"
        local broadcast hostid macn macs mac name ip leasetime
@@ -278,6 +392,7 @@ general_config() {
        config_get log_facility "isc_dhcpd" "log_facility"
 
        config_get domain "isc_dhcpd" "domain"
+       config_get_bool dynamicdns "isc_dhcpd" dynamicdns 0
 
        [ $always_broadcast -eq 1 ] && echo "always-broadcast true;"
        [ $authoritative -eq 1 ] && echo "authoritative;"
@@ -288,6 +403,56 @@ general_config() {
        max_lease_time="$(time2seconds "$max_lease_time")"
        [ "$?" -ne 0 ] && return 1
 
+       if [ $dynamicdns -eq 1 ]; then
+               create_empty_zone "$domain"
+
+               create_empty_zone "168.192.in-addr.arpa"
+
+               cat <<EOF > $conf_local_file
+zone "$domain" {
+  type master;
+  file "$dyndir/db.$domain";
+  allow-update { key $session_key_name; };
+  allow-transfer { key $session_key_name; };
+};
+
+zone "168.192.in-addr.arpa" {
+  type master;
+  file "$dyndir/db.168.192.in-addr.arpa";
+  allow-update { key $session_key_name; };
+  allow-transfer { key $session_key_name; };
+};
+
+EOF
+               /etc/init.d/named reload
+               sleep 1
+
+               cat <<EOF
+ddns-domainname "$domain.";
+ddns-update-style standard;
+ddns-updates on;
+ignore client-updates;
+
+update-static-leases on;
+use-host-decl-names on;
+update-conflict-detection off;
+update-optimization off;
+
+include "$session_key_file";
+
+zone $domain. {
+       primary 127.0.0.1;
+       key local-ddns;
+}
+
+zone 168.192.in-addr.arpa. {
+       primary 127.0.0.1;
+       key local-ddns;
+}
+
+EOF
+       fi
+
        if [ -n "$log_facility" ] ; then
                echo "log-facility $log_facility;"
        fi
@@ -312,7 +477,7 @@ boot() {
 }
 
 start_service() {
-       local domain dhcp_ifs authoritative
+       local domain dhcp_ifs authoritative dynamicdns
 
        if [ -n "$DHCPD_BOOT" ] ; then
                return 0
@@ -335,6 +500,27 @@ start_service() {
 
                static_hosts >> $config_file
 
+               if [ $dynamicdns -eq 1 ]; then
+                       cat <<EOF > $dyn_file
+; Generated by /etc/init.d/dhcpd at $(date)
+
+ttl $TTL
+
+EOF
+
+                       static_cnames >> $dyn_file
+
+                       static_domains >> $dyn_file
+
+                       static_mxhosts >> $dyn_file
+
+                       static_srvhosts >> $dyn_file
+
+                       nsupdate -l -v $dyn_file
+
+                       rm -f $dyn_file
+               fi
+
                [ -z "$dhcp_ifs" ] && return 0
        fi