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.