.@ Tony Finch – blog

About ten days ago, I was wondering how I could automatically and promptly record changes to a zone in git. The situation I had in mind was a special zone which was modified by nsupdate but hosted on a server whose DR plan is “rebuild from Git using Ansible”. So I thought it would be a good idea to record updates in git so they would not be lost.

My initial idea was to use BIND’s update-policy external feature, which allows you to hook into its dynamic update handling. However that would have problems with race conditions, since the update handler doesn’t know how much time to allow for BIND to record the update.

So I thought it might be better to write a DNS NOTIFY handler, which gets told about updates just after they have been recorded. And I thought that wiring a DNS server daemon would not be much harder than writing an update-policy external daemon.

@jpmens responded with enthusiasm, and a some hours later I had something vaguely working.

What I have written is a special-purpose DNS server called nsnotifyd. It is actually a lot more general than just recording a zone’s history in git. You can run any command as soon as a zone is changed - the script for recording changes in git is just one example.

Another example is running nsdiff to propagate changes from a hidden master to a DNSSEC signer. You can do the same job with BIND’s inline-signing mode, but maybe you need to insert some evil zone mangling into the process, say…

Basically, anywhere you currently have a cron job which is monitoring updates to DNS zones, you might want to run it under nsnotifyd instead, so your script runs as soon as the zone changes instead of running at fixed intervals.

Since a few people expressed an interest in this program, I have written documentation and packaged it up, so you can download it from the nsnotifyd home page, or from one of several git repository servers.

(Epilogue: I realised halfway through this little project that I had a better way of managing my special zone than updating it directly with nsupdate. Oh well, I can still use nsnotifyd to drive @diffroot!)