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.


export GIT_AUTHOR_NAME='nsnotifyd'

        cd /etc/nsd/backup || exit 2
        zone=$1 serial=$2 master=$3
        case $zone in
        (.) zone=root
        # 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.

        name: ""
        zonefile: ""
        allow-notify: NOKEY
        request-xfr: NOKEY
        provide-xfr: NOKEY
        provide-xfr: NOKEY
        notify: NOKEY

A similar configuration for a BIND zone could look like

zone "" IN {
        type master;
        file "";

        allow-transfer {; };
        update-policy {
                grant local-ddns zonesub ANY;

        also-notify port 5353 {; };

I then launch nsnotifyd which daemonizes itself.

$ nsnotifyd -4 -a -p 5353 -s /etc/nsd/nsnotifyd/

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[5117]: refresh at 2015-06-16 15:22:12 +0000

I then issue a notify using nsd notify (or Gavin Brown’s pnotify, or rndc notify – you get the drift). Following along in the file syslog logs to, we see:

nsnotifyd[5117]: notify from
nsnotifyd[5117]: IN SOA 1434350317 unchanged
nsnotifyd[5117]: refresh at 2015-06-16 15:24:45 +0000

I then actually update the zone. NSD sends out its NOTIFY, and nsnotifyd reacts:

nsnotifyd[5117]: notify from
nsnotifyd[5117]: IN SOA 1434350318 updated; running /etc/nsd/nsnotifyd/
nsnotifyd[5117]: refresh at 2015-06-16 15:25:43 +0000

and our repository looks like this:

commit 23278840888ea80785e5c6efef8bdc3c5ec73842
Author: nsnotifyd <>
Date:   Tue Jun 16 07:25:43 2015 +0000 IN SOA 1434350318

nsnotifyd is perfect for keeping backups of zones, particularly if you update them dynamically.