Announce: NoZone 1.0 – a Bind DNS zone generator
My web servers host a number of domains for both personal sites and open source projects, which of course means managing a number of DNS zone files. I use Gandi as my registrar, and they throw in free DNS hosting when you purchase a domain. When you have more than 2-3 domains to manage and want to keep the DNS records consistent across all of them, dealing with the pointy-clicky web form interfaces is really incredibly tedious. Thus I have traditionally hosted my own DNS servers, creating the Bind DNS zone files in emacs. Anyone who has ever used Bind though, will know that its DNS zone file syntax is one of the most horrific formats you can imagine. It is really easy to make silly typos which will screw up your zone in all sorts of fun ways. Keeping the DNS records in sync across domains is also still somewhat tedious.
What I wanted is a simpler, safer configuration file format for defining DNS zones, which can minimise the duplication of data across different domains. There may be tools which do this already, but I fancied writing something myself tailored to my precise use case, so didn’t search for any existing solutions. The result of a couple of evenings hacking efforts is a tool I’m calling NoZone, which now has its first public release, version 1.0. The upstream source is available in a GIT repository
The /etc/nozone.cfg configuration file
The best way to illustrate what NoZone can do, is to simply show a sample configuration file. For reasons of space, I’m cutting out all the comments – the copy that is distributed contains copious comments. In this example, 3 (hypothetical) domain names are being configured, nozone.com
, nozone.org
which are the public facing domains, and an internal domain for testing purposes qa.nozone.org
. All three domains are intended to be configured with the same DNS records, the only difference is that the internal zone (qa.nozone.org
) needs to have different IP addresses for its records. For each domain, there will be three physical machines involved, gold
, platinum
and silver
The first step is to define a zone with all the common parameters specified. Note that this zone isn’t specifying any machine IP addresses, or domain names. It is just referring to the machine names to define an abstract base for the child zones
zones = { common = { hostmaster = dan-hostmaster lifetimes = { refresh = 1H retry = 15M expire = 1W negative = 1H ttl = 1H } default = platinum mail = { mx0 = { priority = 10 machine = gold } mx1 = { priority = 20 machine = silver } } dns = { ns0 = gold ns1 = silver } names = { www = platinum } aliases = { db = gold backup = silver } wildcard = platinum }
With the common parameters defined, a second zone is defined called “production” which lists the domain names nozone.org
and nozone.com
and the IP details for the physical machines hosting the domains.
production = { inherits = common domains = ( nozone.org nozone.com ) machines = { platinum = { ipv4 = 12.32.56.1 ipv6 = 2001:1234:6789::1 } gold = { ipv4 = 12.32.56.2 ipv6 = 2001:1234:6789::2 } silver = { ipv4 = 12.32.56.3 ipv6 = 2001:1234:6789::3 } } }
The third zone is used to define the internal qa.nozone.org
domain.
testing = { inherits = common domains = ( qa.nozone.org ) machines = { platinum = { ipv4 = 192.168.1.1 ipv6 = fc00::1:1 } gold = { ipv4 = 192.168.1.2 ipv6 = fc00::1:2 } silver = { ipv4 = 192.168.1.3 ipv6 = fc00::1:3 } } } }
Generating the Bind DNS zone files
With the /etc/nozone.org
configuration file created, the Bind9 DNS zone files can now be generated by invoking the nozone
command.
$ nozone
This generates a number of files
# ls /etc/named nozone.com.conf nozone.conf nozone.org.conf qa.nozone.org.conf $ ls /var/named/data/ named.run named.run-20130317 nozone.org.data named.run-20130315 nozone.com.data qa.nozone.org.data
The final step is to add one line to /etc/named.conf
and then restart bind.
$ echo 'include "/etc/named/nozone.conf";' >> /etc/named.conf $ systemctl restart named.service
The generated files
The /etc/named/nozone.conf
file is always generated and contains references to the conf files for each domain named
include "/etc/named/nozone.com.conf"; include "/etc/named/nozone.org.conf"; include "/etc/named/qa.nozone.org.conf";
Each of these files defines a domain name and links to the zone file definition. For example, nozone.com.conf
contains
zone "nozone.com" in { type master; file "/var/named/data/nozone.com.data"; };
Finally, the interesting data is in the actual zone files, in this case /var/named/data/nozone.com.data
$ORIGIN nozone.com. $TTL 1H ; queries are cached for this long @ IN SOA ns1 hostmaster ( 1363531990 ; Date 2013/03/17 14:53:10 1H ; slave queries for refresh this often 15M ; slave retries refresh this often after failure 1W ; slave expires after this long if not refreshed 1H ; errors are cached for this long ) ; Primary name records for unqualfied domain @ IN A 12.32.56.1 ; Machine platinum @ IN AAAA 2001:1234:6789::1 ; Machine platinum ; DNS server records @ IN NS ns0 @ IN NS ns1 ns0 IN A 12.32.56.2 ; Machine gold ns0 IN AAAA 2001:1234:6789::2 ; Machine gold ns1 IN A 12.32.56.3 ; Machine silver ns1 IN AAAA 2001:1234:6789::3 ; Machine silver ; E-Mail server records @ IN MX 10 mx0 @ IN MX 20 mx1 mx0 IN A 12.32.56.2 ; Machine gold mx0 IN AAAA 2001:1234:6789::2 ; Machine gold mx1 IN A 12.32.56.3 ; Machine silver mx1 IN AAAA 2001:1234:6789::3 ; Machine silver ; Primary names gold IN A 12.32.56.2 gold IN AAAA 2001:1234:6789::2 platinum IN A 12.32.56.1 platinum IN AAAA 2001:1234:6789::1 silver IN A 12.32.56.3 silver IN AAAA 2001:1234:6789::3 ; Extra names www IN A 12.32.56.1 ; Machine platinum www IN AAAA 2001:1234:6789::1 ; Machine platinum ; Aliased names backup IN CNAME silver db IN CNAME gold ; Wildcard * IN A 12.32.56.1 ; Machine platinum * IN AAAA 2001:1234:6789::1 ; Machine platinum
As of 2 days ago, I’m using nozone to manage the DNS zones for all the domains I own. If it is useful to anyone else, it can be downloaded from CPAN. I’ll likely be submitting it for a Fedora review at some point too.