You know the drill: you provision a server with a master zone, and then you have to hop over to all secondary servers and add the slave zone to their configuration. You probably do that with some form of automation, or you use something slightly convoluted like what we’ve discussed previously in automatic provisioning of slave DNS servers. If your master and slave servers are BIND, you’re in luck: catalog zones will automate this for you within the BIND code itself: there’ll no longer be a need for “hacking” this to accomplish automatic provisioning of slave BIND servers.

Catalog zones are scheduled for release in BIND 9.11, but Evan Hunt graciously let me have a peek at a preview of the code, and I must warn you: first, this is a work in progres and hasn’t been released yet, and second (and more importantly) what I’m going to show you is the little I know of catalog zones. Be warned on both accounts! Update: Catalog zones are now in BIND 9.11.0a3.

Catalog zones are based on an Internet-Draft called draft-muks-dnsop-dns-catalog-zones-01, updated in draft-toorop-dnsop-dns-catalog-zones-01, which describes a method for automatic synchronization of zones among primary and secondary servers. The way this is works is that a zone contains the names (and optional metadata) describing which zones are to be used on slave (secondary) servers; these zone names in a catalog are called member zones. The secondary server obtains a copy of this catalog (via zone transfer (AXFR/IXFR)) and uses it to update the internal catalog of zones it ought to have; once it detects a change, it adds and slaves the member zone or deletes it, depending on whether the member zone was added or removed.

More concisely: we add one or more member zones to the catalog zone which is transferred to its slaves where it triggers the creation (or removal) of the member zones.

Catalog zones

Let’s see how this works in practice with a preliminary copy of BIND which supports this.

Primary and secondary servers

On my primary test server, I add the following to named.conf:

options {
        directory "/etc/namedb";
        server-id "authoritative";
        allow-new-zones yes;

zone "" {
        type master;
        file "";
        also-notify {; };
        notify explicit;

Pay attention to the allow-new-zones directive. The catalog zone proper is mostly empty: mname, rname and NS are irrelevant, and the relative version label specifies the catalog zone format version (currently “2”):

$TTL 3600
@       IN SOA . . 1 86400 3600 86400 3600
@       IN NS  nop.
version IN TXT "2"

On a secondary ( I have the following configuration:

options {
        directory "/etc/namedb";
        masterfile-format text;
        zone-statistics yes;
        server-id "slave";

        allow-new-zones yes;
        catalog-zones {
                zone ""
                      zone-directory "cat-zones"
                      in-memory no
                      default-masters {; };

zone "" {
        type slave;
        file "";
        masters {; };

Here we also add allow-new-zones so that the secondary can create member zones on the fly, and we use the new catalog-zones stanza to define the primary server which holds our catalog. The default-masters statement in the catalog-zones stanza defines the default masters for its member zones.

The optional zone-directory in “catalog-zones” allows master files for slaves provisioned by catalog zones to be stored in a directory other than the server’s working directory.

If in-memory is set to yes, local copies of master files on slaves will be stored in memory only and not on the file system.

Adding a new member zone

On the primary server I add a new zone, either dynamically with rndc addzone or manually; I’ll use the former:

$ rndc addzone '{type master; file "";};'
$ dig +short @ soa
localhost. root.localhost. 22 10800 3600 604800 3600

From this point onwards, my primary server is ready to serve this master zone, but I want the secondary to serve the zone as well. Here’s what I do:

  1. I create a hash of a value. Basically any value should do, but it must currently be a valid BIND “nzf” hash. (The pre-alpha code I have does a little oops if it isn’t – I’m reporting that as we speak.) ISC is considering loosening this rule to allow me to use any label I wish to, but for interoperability with possible future implementations which comply with the draft, the hash is preferable.
  2. I then add a record to the catalog zone in which I name the member zone, bump its serial and reload the zone.
#!/usr/bin/env python

import   # pip install dnspython
import hashlib
import sys


I run the above (thanks Witold!) to create the hash:

$ ./

Another way of creating the hash (thanks, Peter) is:

$ printf '\7example\3org\0' | openssl sha1

I’ve dropped a slightly more useful Python program here.

I now use that hash for step 2 and add a record containing the member zone:

@ 3600 SOA . . 2 86400 3600 86400 3600
@ 3600 IN NS nop.

47ac1a4d93b61fffdb4762c18c9e7d1a6b046d33.zones           PTR

When I reload named on the primary (rndc reload), I watch the transfer logs; they look very promising:

xfer-out: info: client ( transfer of '': AXFR-style IXFR started (serial 2)
xfer-out: info: client ( transfer of '': AXFR-style IXFR ended
xfer-out: info: client ( transfer of '': AXFR started (serial 22)
xfer-out: info: client ( transfer of '': AXFR ended

Note how first the catalog zone was transferred, and then our new zone.

So, what’s on the secondary?

$ ls -l /etc/namedb/cat-zones
-rw-r--r-- 1 root root  316 Jun  2 13:33

The __catz__* file contains a copy of the slaved zone.

If I delete a member zone record from the catalog the process is reversed, and the secondaries remove the zone completely:

catz: updating catalog zone '' with serial 3
catz: deleting zone '' from catalog '' - success
catz: catz_delzone_taskaction: zone '' deleted


BIND can use metadata on a zone which is transferred with the catalog: for example different master servers for a particular zone. This allows us to add a member zone to the catalog, which is configured with different master servers. So, on my primary server, I can add the following to the catalog: the first record specifies a member zone, and the second record the master(s) for that zone.

45414dc99ae20a84507692de578c0dd9d2522134.zones           IN PTR
masters.45414dc99ae20a84507692de578c0dd9d2522134.zones   IN A

When the secondaries get the catalog, this member zone is created and configured to obtain a copy of its data from the specified master server.

Another interesting feature is the possibility of setting ACLs on particular member zones within the catalog. This is done using Address Prefix Lists (RFC 3123):

allow-transfer.45414dc99ae20a84507692de578c0dd9d2522134.zones   IN APL  1: 1:

The above example would allow transfers from the two addresses only.

Catalog zones may also carry TSIG signatures for member zones; this is described in the BIND ARM.


It goes without saying (so why am I?) that the catalog zone can be dynamically updated of course; this makes provisioning easy and ensures the SOA serial number is bumped.

We should probably all wish for other Open Source DNS server implementations to embrace catalog zones and add support for them in order to increase interoperability between DNS server software brands.


BIND and DNS :: 24 May 2016 :: e-mail