PowerDNS with BIND Backend

It’s been a while since I wrote about PowerDNS, but I recently had the opportunity to look at the BIND backend. This backend enables PowerDNS to serve BIND-format zone files – which is a boon for any migration from BIND to PowerDNS. The BIND backend also supports serving DNSSEC RRs.

In this article, I will cover the installation of the latest version of PowerDNS Authoritative Server on a pair of CentOS 7.1 hosts – one set up as a master (centos-ns1) and the other as a slave (centos-ns2). Both of these servers will use the BIND backend. I’ll cover setting up these servers to run under systemd, and appropriate firewall configuration using firewall-cmd. Read my previous article for more detail on PowerDNS, the MySQL backend, chroot-ing the installation, and other topics.

First, install the required prerequisite packages:

As you can see, I also install bind-utils so that I obtain the dig utility – required for testing the nameservers.

Next, download the latest version of PowerDNS Authoritative Server from the PowerDNS website. I’ve downloaded to /usr/local/src on both servers. Untar the installation package:

As you can see, version 3.4.3 was current at the time of writing this article. Ensure that you grab the latest version of the software so that all appropriate security errata are applied.

Next, configure the installation, compile, and install.

Create a symlink to your installation – this will make upgrades easier (you just install the new version to the appropriate --prefix, and then update the symlink).

Next, copy the supplied systemd unit file into place. Modify it accordingly.

My complete pdns.service unit file looks like this:

Ensure the paths to ExecStart and ExecStop are correct for your installation. Next, we’ll configure the master and slave servers.

Next, we’ll add a pdns user (and implicitly a pdns group) that the server will run as:

Master Server Configuration

Create /usr/local/pdns/etc/pdns.conf as follows:

Let’s have a look. It’s a *very* minimal pdns.conf with just enough configuration to get the BIND backend up and running.

The configuration is fairly self-explanatory. We allow AXFR from our slave server IP address, specify that the backend should check for zonefile updates every 300 seconds, then launch the bind backend with the configuration file /usr/local/pdns/etc/bindbackend.conf. This configuration file is essentially a minimal named.conf-format file. More on that soon. We then specify the local bind address (i.e. the local IP address of the interface to which you want PowerDNS to bind to), define that this server is indeed a master, and then set the server up to run as UID pdns and GID pdns. We then specify version-string to be anonymous so that a dig CH TXT version.bind @nameserver doesn’t give the script kiddies anything to go on.

Next we’ll create our bind-config file:

And let’s have a look at what’s been configured:

As you can see, it’s just a minimal named.conf – I’ve specified a single zone – example.com. Don’t get fancy and use a lot of BIND configuration as PowerDNS will ignore it. PowerDNS is configured in pdns.conf!

Let’s make our zonefile directory, and create our first zonefile:

Next, ensure the appropriate firewall ports are open. For this, I open port 53/udp for queries, and port 53/tcp for AXFR and larger queries.

Let’s start the master server, and verify correct operation:

Now, we can move onto slave server configuration.

Slave Server Configuration

Create /usr/local/pdns/etc/pdns.conf as follows:

Again, it’s a minimal pdns.conf with just enough configuration to get the BIND backend up and running as a slave server.

The only difference between this and the master’s pdns.conf is that we specify slave=yes instead of master=yes. Let’s take a look at bindbackend.conf on the slave:

Create the zone directory and set appropriate permissions:

Again, this is a very simple BIND named.conf-format configuration file. Open the firewall and start the server:

Checking /var/log/messages, you should first note the following error as the zone has not yet been transferred:

You should note that the slave considers the zone stale, and initiates an AXFR:

Now we can query the slave, and the zone’s RRs return as expected:

Adding a New Zone

In order to add a new zone online without restarting the servers, follow this procedure. First, on the master, create the new zonefile and update bindbackend.conf.

Verify that the zone is loaded:

Next, use pdns_control to load the zone:

On the slave, update bindbackend.conf as follows:

Run a rediscover:

And next, retrieve:

You should now be able to query the slave:

 Updating a Zone

Updating a zone is a simple case of modifying the zonefile, incrementing the serial and either waiting for bind-check-interval to pass, or issuing a pdns_control bind-reload-now:

You should see lines along the following in /var/log/messages:

The slave will now be up-to-date.