PowerDNS Master Slave DNS Replication with MySQL backend

Written by - 0 comments

Published on April 1st 2019 - Listed in DNS PowerDNS Linux


This is the second article of an article series about PowerDNS. The previous article (PowerDNS Authoritative DNS Server 4.1 with MySQL backend on Ubuntu 18.04) covered the installation and basic configuration of a standalone PowerDNS server. 

As the title already reveals, this post is all about DNS Master-Slave replication. But first we need to understand what replication capabilities PowerDNS offers.

DNS Replication Modes

As you can read from the official documentation about DNS Modes of Operation, there are two operation (replication) modes. Let's start with the default (native) mode.

Native replication

When PowerDNS talks about "native" replication, it is meant that PowerDNS does no replication at all. It leaves all the data synchronization and replication to its backend, for example a MySQL database with the pdns-backend-mysql package installed.

Talking in terms of databases that means that PowerDNS expects the databases replicated/synced between the different nameservers.

Let's assume the following scenario: We have three nameservers ns1.example.com, ns2.example.com, ns3.example.com. NS1 is considered the primary nameserver and our master where DNS zone and record changes happens. NS2 and NS3 are slave nameservers being there for redundancy.

As PowerDNS is running with a MySQL backend, a classical MySQL Master-Slave-Replication can be configured where the changes on NS1's database are replicated to the databases on NS2 and NS3.

No configuration change is needed in PowerDNS. Due to the replicated data in the backend database, all three nameservers send the same query responses.

The following graphic should explain how the native replication works:

PowerDNS Native Replication with MySQL backend

Of course you need to monitor the native replication somehow. In this scenario the MySQL replication can be monitored with the monitoring plugin check_mysql_slavestatus.

Master replication

If you have been working with BIND in the past, this is what you would have expected as a DNS replication in the first place. The "Master" replication is the classical replication of DNS zones/records through the DNS protocol itself. The primary nameserver (aka DNS Master) sends a NOTIFY command via the DNS protocol (udp 53) to the slave servers of a domain/zone. The slave servers then initiate an AXFR command (zone transfer) and send it to the master server. If permitted, the master sends the zone records to the slaves.

It is important to understand what is deemed a slave or how PowerDNS defines a slave. Basically explained, PowerDNS sends the NOTIFY command to all servers found as a "NS" record within a zone (even itself). So in order to use a Master replication, make sure that all your slave DNS servers were added as NS records of your zone(s).

The following graphic explains how the master replication works:

PowerDNS DNS Master Replication with MySQL Backend

It is also possible to trigger an AXFR command on the slave servers without having received a NOTIFY first.

In this article the setup focuses on the latter method: Master Replication.

How to configure DNS Master Slave replication in PowerDNS

Based on the installation and configuration of PowerDNS in the previous article (PowerDNS Authoritative DNS Server 4.1 with MySQL backend on Ubuntu 18.04), the following changes need to be done in pdns.conf. The changes differ between the master node and the slave nodes.

Master config

There are two options which must be defined: allow-axfr-ips and master.

The allow-axfr-ips option tells PowerDNS which endpoints are allowed to initiate and receive zone transfers. And of course we need to allow our DNS slaves to do so. 

Let's assume that ns2.example.com runs on 192.168.250.153 and ns3.example.com runs on 192.168.250.253. These two IP's are explicitly allowed for zone transfers. You may also define full ranges, e.g. 192.168.250.0/24 in this case, but always make sure you restrict zone transfers to the bare minimum.

#################################
# allow-axfr-ips        Allow zonetransfers only to these subnets
#
# allow-axfr-ips=127.0.0.0/8,::1
allow-axfr-ips=192.168.250.153,192.168.250.253

The other setting is quite obviously the "master" parameter, but it can be easily forgotten (happened to me!). Set the value to "yes" so PowerDNS knows this DNS server is a master server.

#################################
# master        Act as a master
#
# master=no
master=yes

After these changes, restart PowerDNS

root@master:~# systemctl restart pdns

Slave config

On the slave servers there is only one mandatory setting in pdns.conf: set slave to yes so PowerDNS knows this server is a slave server. Additionally to that you may also want the slave server keep up to date with the master on its own, without waiting for a NOTIFY command, by using the slave-cycle-interval option.

#################################
# slave Act as a slave
#
# slave=no
slave=yes

#################################
# slave-cycle-interval Schedule slave freshness checks once every .. seconds
#
# slave-cycle-interval=60
slave-cycle-interval=60

Now something that could be forgotten easily is the "supermasters" table in the backend. As we have a MySQL database as pdns backend, the master server needs to be added into the backend config, too.

The data you insert into the supermasters table consists of three values:

  1. The IP address of the DNS master (192.168.250.53)
  2. The FQDN of the slave server (myself)
  3. The role which should be assigned, should be admin role

Be aware that each slave must have its own FQDN as second value. 

So on NS2:

mysql> insert into powerdns.supermasters values ('192.168.250.53', 'ns2.example.com', 'admin');

And on NS3:

mysql> insert into powerdns.supermasters values ('192.168.250.53', 'ns3.example.com', 'admin');

After these changes, restart PowerDNS:

root@slave:~# systemctl restart pdns

Testing the replication

When a new zone was added to the master server, nothing happens yet:

root@master:~# pdnsutil create-zone replicateme.dev
Creating empty zone 'replicateme.dev'

On the slave, the domain does not show up:

root@slave:~# pdns_control list-zones | grep replicateme
root@slave:~#

That's normal because the zone does not have NS entries (and therefore no slave servers) yet.

Let's add the NS entries for NS1 (the master itself) and NS2 (the first slave):

root@master:~# pdnsutil add-record replicateme.dev @ NS ns1.example.com
New rrset:
replicateme.dev. IN NS 3600 ns1.example.com

root@master:~# pdnsutil add-record replicateme.dev @ NS ns2.example.com
New rrset:
replicateme.dev. IN NS 3600 ns1.example.com
replicateme.dev. IN NS 3600 ns2.example.com

Nothing has happened on the slave server yet. We first need to increase the zone's serial and then send a notify:

root@master:~# pdnsutil increase-serial replicateme.dev
SOA serial for zone replicateme.dev set to 2019040101

root@master:~# pdns_control notify replicateme.dev
Added to queue

On the slave server, the following log entries appear:

Apr  1 12:00:10 slave pdns_server[19527]: Received NOTIFY for replicateme.dev from 192.168.250.53 for which we are not authoritative
Apr  1 12:00:10 slave pdns_server[19527]: Created new slave zone 'replicateme.dev' from supermaster 192.168.250.53
Apr  1 12:00:10 slave pdns_server[19527]: 1 slave domain needs checking, 0 queued for AXFR
Apr  1 12:00:10 slave pdns_server[19527]: Received serial number updates for 1 zone, had 0 timeouts
Apr  1 12:00:10 slave pdns_server[19527]: Domain 'replicateme.dev' is stale, master serial 2019040101, our serial 0
Apr  1 12:00:10 slave pdns_server[19527]: Initiating transfer of 'replicateme.dev' from remote '192.168.250.53'
Apr  1 12:00:10 slave pdns_server[19527]: Starting AXFR of 'replicateme.dev' from remote 192.168.250.53:53
Apr  1 12:00:10 slave pdns_server[19527]: AXFR started for 'replicateme.dev'
Apr  1 12:00:10 slave pdns_server[19527]: AXFR of 'replicateme.dev' from remote 192.168.250.53:53 done
Apr  1 12:00:10 slave pdns_server[19527]: Backend transaction started for 'replicateme.dev' storage
Apr  1 12:00:10 slave pdns_server[19527]: AXFR done for 'replicateme.dev', zone committed with serial number 2019040101

And the domain now shows up on the slave and it can be queried:

root@slave:~# pdns_control list-zones | grep replicateme
replicateme.dev.

root@slave:~# dig -t NS replicateme.dev @localhost +short
ns1.example.com.
ns2.example.com.

Next up

The next article in this series will explain how to install a modern user interface (Opera DNS UI) for PowerDNS. The link to the article will be posted here once completed.


Add a comment

Show form to leave a comment

Comments (newest first)

No comments yet.