Tony Finch has created a gem of a utility called nsnotifyd. It's a teeny-tiny DNS "server" which sits around and listens for DNS NOTIFY messages which are sent by authority servers when they instruct their slaves that the zone has been updated and they should re-transfer (AXFR / IXFR) them. As soon as nsnotifyd receives a NOTIFY, it executes a shell script you provide. (This is a very welcome alternative to doing it in Perl, as I did when I wanted to be notified of new and changed KSK in a zone.)
The script you provide (Tony has a few examples in the repository) is passed the name of the notified zone, its SOA serial number and the address of the master authority server which emitted the NOTIFY. Whether or not you actually use that data is up to you, of course. nsnotifyd can be used for all sorts of things:
- Creating backups (discussed below). (You could even rsync zone files to a remote location.)
- Alerting humans or machines on zone changes.
- Taking snapshots of PowerDNS databases on zone changes.
- Read the zone, create reverse-DNS entries in another zone. Tony provides a script which helps with that.
- Poor-man's bump-in-the-wire DNSSEC signer; see repository.
So, let's assume I wish to keep a Git repository with changes to a few zones. I create a repository, add empty zone files, and create the shell script nsnotifyd will be invoking.
#!/bin/sh export GIT_AUTHOR_NAME='nsnotifyd' export GIT_AUTHOR_EMAILemail@example.com' export GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME export GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL ( cd /etc/nsd/backup || exit 2 zone=$1 serial=$2 master=$3 case $zone in (.) zone=root esac # BIND <= 9.9.0? You may want to replace +rrcomments with +multiline dig +noall +answer +onesoa +rrcomments @$master $zone axfr >$zone git commit -q -m "$zone IN SOA $serial" $zone ) 2>&1 | logger -p daemon.notice -t $0 -s
I add an explicit
notify statement to the zone stanza in NSD, and enable transfers from the address nsnotifyd runs on.
zone: name: "example.org" zonefile: "example.org.zone" allow-notify: 192.168.1.110 NOKEY request-xfr: 192.168.1.110 NOKEY provide-xfr: 192.168.1.110 NOKEY provide-xfr: 127.0.0.1 NOKEY notify: 127.0.0.1@5353 NOKEY
I then launch nsnotifyd which daemonizes itself.
$ nsnotifyd -4 -a 127.0.0.1 -p 5353 -s 127.0.0.1 /etc/nsd/nsnotifyd/jp2git.sh example.org
As soon as nsnotifyd starts up, it queries the SOA record of the specified zones, typically by querying the host's resolver. (I overrode that with the
-s option to force it to query a particular name server.) It then sits back and waits until refresh time has elapsed, whereupon it will check whether the serial number has changed; if so, it launches our script.
nsnotifyd: example.org refresh at 2015-06-16 15:22:12 +0000
I then issue a notify using
nsd notify (or Gavin Brown's pnotify). Following along in the file syslog logs to, we see:
nsnotifyd: example.org notify from 127.0.0.1/50028 nsnotifyd: example.org IN SOA 1434350317 unchanged nsnotifyd: example.org refresh at 2015-06-16 15:24:45 +0000
I then actually update the zone. NSD sends out its NOTIFY, and nsnotifyd reacts:
nsnotifyd: example.org notify from 127.0.0.1/45669 nsnotifyd: example.org IN SOA 1434350318 updated; running /etc/nsd/nsnotifyd/jp2git.sh nsnotifyd: example.org refresh at 2015-06-16 15:25:43 +0000
and our repository looks like this:
commit 23278840888ea80785e5c6efef8bdc3c5ec73842 Author: nsnotifyd <firstname.lastname@example.org> Date: Tue Jun 16 07:25:43 2015 +0000 example.org IN SOA 1434350318