Skip to main content

📒 Using Catalog Zones for your DNS infrastructure: PowerDNS and Knot

Happy New Year!

Recently, I learned about a thing called ‘Catalog Zones’. A relatively new thing in DNS that helps simplify your DNS architecture. A Catalog Zones contains one or more ‘real’ zones. And it can be useful for configuring slave / secondary DNS servers.

(I would rather not get into the naming thing; I just want people to understand what I am writing.)

Before catalog zones, you had to provision each new zone to your slave DNS servers. Updates are no problem, most of the time. Just issue a NOTIFY and your slaves will AXFR the zone from the master. But configuring new zones onto slaves used to be a pain (unless you were using the superslave feature).

Now, with catalog zones, you can configure your slaves to listen for updates of a single zone (the catalog zone), and the rest will follow!

My setup is now a PowerDNS master server and Knot slaves. Why Knot? Because it is apparently the best performing. I used to be running PowerDNS on my slaves as well with the LMDB backend, but Knot is so elegant to configure, you’ll start to see why I went for it.

Ok. Let’s dive into some configuration and code snippets.

Configuring PowerDNS
#

Create a new zone like you normally would. It should have SOA and NS records. For the name, you could go with something like catalog.private. or catalog.internal.. To help you pick a private TLD, please check out RFC2606 and Appendix G of RFC6762. You could, of course, also make multiple catalogs, depending on how you want to architect your DNS infrastructure.

Then set the new zone as a ‘producer’

pdnsutil set-kind catalog.internal producer

Then, you can start adding zones to the catalog zone:

pdnsutil set-catalog example.com catalog.internal
pdnsutil set-kind example.com primary # set the zone you want to sync between slaves to primary, if it isn't already

To add all zones on your PowerDNS server to the catalog, you can use this one-liner

for zone in $(pdnsutil list-all-zones); do
    pdnsutil set-catalog $zone catalog.internal
    pdnsutil set-kind $zone primary 
done

You may also want to add this to your pdns.conf file to automatically add new zones to the catalog zone:

default-catalog-zone=catalog.internal.

Configuring Knot
#

After a friend showed me this, I was blown away.

Install Knot from the nic.cz repository: https://pkg.labs.nic.cz/doc/?project=knot-dns

Then, open /etc/knot/knot.conf and paste this

server:
    identity: nsx.example.nl
    version: "Nick's awesome DNS"
    nsid: nsx
    rundir: "/run/knot"
    user: knot:knot
    automatic-acl: on
    listen: [ 0.0.0.0@53, ::@53 ]

log:
  - target: syslog
    any: info

database:
    storage: "/var/lib/knot"

acl:
  - id: notify_from_primary
    address: [ <v6 address of master>, <v4 address of master> ]
    action: notify

remote:
  - id: primary
    address: [ <v6 address of master>, <v4 address of master> ]

template:
  - id: secondary_zones
    master: primary
    acl: notify_from_primary

zone:
  - domain: catalog.internal.
    master: primary
    acl: notify_from_primary
    catalog-role: interpret
    catalog-template: secondary_zones

Amazing, right? It’s so elegant and simple. Just save the file and restart Knot, and you’re done! Make sure to update the hostname and the version string. Furthermore, set the v6 and v4 addresses of your master so it accepts NOTIFYs from those.

Keep in mind PowerDNS will only notify the servers that are listed as NS in a zone, so make sure your zones are consistent.

You could easily wrap this up in an Ansible playbook and have new DNS slaves in seconds!