Dynamic update of DNS with DHCP lease info between dual redundant pihole servers

Came up with a satisfactory solution using systemd and inotifywait to monitor the /etc/pihole/dhcp.leases file. When it is modified (but not zero length), I munge it into "hosts" format using awk/sort. I compare the resulting file to the last one generated - simple renewals, which are the bulk of changes to the dhcp.leases file don't change resulting custom.list file. But if it has, I copy it to the other servers /etc/pihole/custom.list and reload piehole. The second server, of course, has a reciprocating service.

Updates are pretty nearly instantaneous. As soon as a client has a lease, it can be resolved on either server. Code follows:

# /lib/systemd/system/SyncDHCP.service
[Unit]
Description=Updates DHCP DNS between two pihole servers

[Service]
ExecStart=/usr/bin/SyncDHCP.sh

[Install]
WantedBy=multi-user.target

#! /usr/bin/bash
# /usr/bin/SyncDHCP.sh
Target=dns1 # Points at the server recieving custom.list
Src=/etc/pihole/dhcp.leases
Dst=$(mktemp)
Tmp=$(mktemp)
Msg(){
printf "%s - %s\n" $(date +%u%m%d%H%M%S) "$"
}
inotifywait -m $Src -e modify |
while read -r f a
do
size=$(cksum $Src | awk '{print $2}')
if [ "$size" -ne 0 ]
then
awk '$4!="
"{printf "%s %s\n",$3,$4}' $Src | sort -k3 > $Tmp
if ! cmp -s $Dst $Tmp
then
diff $Dst $Tmp | awk '$1~/<|>/{
if ($1~/</)printf "released %s %s\n",$2,$3;
if ($1~/>/)printf "assigned %s %s\n",$2,$3;
}'
scp $Tmp root@$Target:/etc/pihole/custom.list > /dev/null &&
ssh root@$Target "pihole restartdns reload" &&
cp $Tmp $Dst &&
Msg "Updated custom.list on $Target"
fi
fi
done

2 Likes