isc-dhcp: send ddns updates to a remote Bind server

Signed-off-by: Jaymin Patel <jem.patel@gmail.com>
This commit is contained in:
Jaymin Patel 2022-09-15 14:58:16 +05:30
parent a9ae9bad06
commit ed877f6105
2 changed files with 119 additions and 93 deletions

View File

@ -2,10 +2,18 @@
uci -q get dhcp.isc_dhcpcd && exit 0
touch /etc/config/dhcp
[ -f /etc/bind/rndc.conf ] && key_secret=$(awk -F'"' '/secret/{print $2; exit;}' /etc/bind/rndc.conf)
[ -z "$key_secret" ] && key_secret=$(rndc-confgen | awk -F'"' '/secret/{print $2; exit;}')
uci batch <<EOF
set dhcp.isc_dhcpd=isc_dhcpd
set dhcp.isc_dhcpd.authoritative='1'
set dhcp.isc_dhcpd.default_lease_time='3600'
set dhcp.isc_dhcpd.max_lease_time='86400'
set dhcp.dynamicdns=dynamicdns
set dhcp.dynamicdns.server=127.0.0.1
set dhcp.dynamicdns.key_algo=hmac-sha256
set dhcp.dynamicdns.key_secret=$key_secret
set dhcp.dynamicdns.key_name=local-dns
commit dhcp
EOF

View File

@ -116,11 +116,11 @@ typeof() {
}
update() {
local lhs="$1" family="$2" type="$3"
shift 3
local lhs="$1" leasetime="$2" family="$3" type="$4"
shift 4
[ $dynamicdns -eq 1 ] && \
echo -e "$PREFIX" "$lhs $family $type $@\nsend" >> $dyn_file
echo -e "$PREFIX" "$lhs ${leasetime} $family $type $@\nsend" >> $dyn_file
}
rev_str() {
@ -134,14 +134,99 @@ rev_str() {
echo "$result"
}
create_empty_zone() {
local zone="$1"
create_zone_update_file() {
local zone=$1
local zonefile="$dyndir/db.$zone"
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"
cp -p /etc/bind/db.empty "$zonefile"
cat <<EOF >> ${conf_local_file}_
zone "$zone" {
type master;
file "$zonefile";
update-policy {
grant $session_key_name zonesub any;
};
};
EOF
}
generate_dhcp_ddns_config() {
local zone=$1
local cfg=$2
local server
config_get server "$cfg" server
cat <<EOF
zone $zone. {
primary $server;
key $session_key_name;
}
EOF
}
generate_session_file() {
local cfg=$1
config_get session_key_name $cfg key_name local-dns
config_get key_algo $cfg key_algo hmac-sha256
config_get key_secret $cfg key_secret
cat <<EOF > "$session_key_file"
key "$session_key_name" {
algorithm $key_algo;
secret "$key_secret";
};
EOF
}
generate_ddns_config() {
local domain=$1
local cfg=dynamicdns
local server zones
local named_reload=0
config_get server $cfg server
config_get zones $cfg zones
generate_session_file "$cfg"
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";
EOF
config_list_foreach $cfg zones create_zone_update_file "$cfg"
config_list_foreach $cfg zones generate_dhcp_ddns_config "$cfg"
cmp -s $conf_local_file ${conf_local_file}_ || {
named_reload=1
cp ${conf_local_file}_ ${conf_local_file}
}
rm -f ${conf_local_file}_
chmod g+w "$dyndir" -R
chgrp bind "$dyndir" -R
if [ "$named_reload" = "1" ]; then
/etc/init.d/named reload
sleep 1
fi
init_dynamicdns_config
echo -e "server $server" >> $dyn_file
echo -e "zone ${zones// /\\nzone }" >> $dyn_file
}
append_routes() {
@ -210,7 +295,7 @@ static_cname_add() {
config_get target "$cfg" "target"
[ -n "$target" ] || return 0
update "$cname.$domain." IN CNAME "$target.$domain."
update "$cname.$domain." "" IN CNAME "$target.$domain."
}
static_cnames() {
@ -230,9 +315,9 @@ static_domain_add() {
for ip in $ips; do
revip="$(rev_str "$ip" ".")"
update "$name.$domain." IN A "$ip"
update "$name.$domain." "" IN A "$ip"
[ -n "$(rfc1918_prefix "$ip")" ] && \
update "$revip.in-addr.arpa." IN PTR "$name.$domain."
update "$revip.in-addr.arpa." "" IN PTR "$name.$domain."
done
}
@ -252,9 +337,9 @@ static_mxhost_add() {
[ -n "$pref" ] || return 0
if [ "$domain2" = "@" ]; then
update "$domain." IN MX "$pref" "$relay.$domain."
update "$domain." "" IN MX "$pref" "$relay.$domain."
else
update "$domain2.$domain." IN MX "$pref" "$relay.$domain."
update "$domain2.$domain." "" IN MX "$pref" "$relay.$domain."
fi
}
@ -277,7 +362,7 @@ static_srvhost_add() {
config_get weight "$cfg" "weight"
[ -n "$weight" ] || return 0
update "$srv.$domain." IN SRV "$priority" "$weight" "$port" "$target.$domain"
update "$srv.$domain." "" IN SRV "$priority" "$weight" "$port" "$target.$domain"
}
static_srvhosts() {
@ -377,8 +462,8 @@ static_host_add() {
for ip in $ips; do
revip="$(rev_str "$ip" ".")"
update "$name.$domain." IN A "$ip"
update "$revip.in-addr.arpa." IN PTR "$name.$domain."
update "$name.$domain." "$leasetime" IN A "$ip"
update "$revip.in-addr.arpa." "$leasetime" IN PTR "$name.$domain."
done
}
@ -386,6 +471,14 @@ static_hosts() {
config_foreach static_host_add host "$@"
}
init_dynamicdns_config() {
cat <<EOF > $dyn_file
; Generated by /etc/init.d/dhcpd at $(date)
ttl $TTL
EOF
}
gen_dhcp_subnet() {
local cfg="$1"
@ -517,82 +610,7 @@ general_config() {
max_lease_time="$(time2seconds "$max_lease_time")"
[ $? -ne 0 ] && return 1
if [ $dynamicdns -eq 1 ]; then
create_empty_zone "$domain"
local mynet
for mynet in $rfc1918_nets; do
mynet="$(rev_str "$mynet" ".")"
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
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 $session_key_name;
}
EOF
for mynet in $rfc1918_nets; do
mynet="$(rev_str "$mynet" ".")"
cat <<EOF
zone $mynet.in-addr.arpa. {
primary 127.0.0.1;
key $session_key_name;
}
EOF
done
fi
[ $dynamicdns -eq 1 ] && generate_ddns_config "$domain"
if [ -n "$log_facility" ] ; then
echo "log-facility $log_facility;"