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.
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.
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:
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.
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:
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.
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.
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
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:
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
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.
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.
Sapar from wrote on Jan 6th, 2023:
I understand. I'll probably create some kind of cron or something if I cannot find another way, but the official documentation (this time here: https://doc.powerdns.com/authoritative/modes-of-operation.html - Primary operation) suggests (to my mind) that the primary does that all by itself:
"When operating as a master, PowerDNS sends out notifications of changes to slaves, which react to these notifications by querying PowerDNS to see if the zone changed, and transferring its contents if it has."
and
"To resolve this issue, PowerDNS tries multiple tactics to figure out the IP addresses of the slaves and notifies everybody. In contrived configurations, this may lead to duplicate notifications being sent out, which shouldn’t hurt."
Just putting it out there in case you do write a blog about it :)
Thanks for your input. This has been helpful!
ck from Switzerland wrote on Jan 6th, 2023:
Sapar, not sure out of my head where this setting is set but since PowerDNS 4.1 (and right now on PowerDNS 4.6) I got used to either use Opera PowerDNS UI or use scripts which run a notify at the end. Maybe there is indeed a way to automate this though but this is how I do it. Coming (and still using BIND), I got used to the manual reload/notify commands :-)
This kind of reminds me I should create a new blog post on newer PowerDNS versions but time is my enemy these days.
Sapar from wrote on Jan 6th, 2023:
@ck I thought that activating autoprimary would solve this though. https://doc.powerdns.com/authoritative/modes-of-operation.html#autoprimary-operation
It is not clear to me if I'm supposed to be adding autosecondary to the primary or to the secondary (one would think it's on the secondary only), but I've added it to both to no avail.
The supermasters table must have the right information, because manual notify does work (it didn't work before when I added the wrong IP) and the NS record also contains the slave/secondary IP (which can be resolved).
Indeed, I'm not using anything that triggers this automatically, but I expected it to do it automatically from what I've been reading on the internet. A rather daunting experience. Your site was one of the few sources which make some sense of that horrid official documentation :)
ck from Switzerland wrote on Jan 6th, 2023:
Sapar, if you are using the command line to update/add dns records in the master, you will have to run the NOTIFY manually. Yes, that is similar to BIND by the way. I am using the Powedns UI (from Opera) which triggers this via the PowerDNS API and therefore automates this.
Sapar from wrote on Jan 6th, 2023:
This works great in my case (I'm using postgresql), but the master (not changed into primary and secondary respectively) won't do the notifying automatically unfortunately. I'm not sure how I can automate this without having to manually run the notify command.
ck from Switzerland wrote on Jan 15th, 2022:
Hendra, the article was for PowerDNS 4.1, maybe there are additional settings needed for newer versions. See also comments from other users.
My guess would be that your slave servers dont recognize the master server. Maybe missing superserver entry if you use the same version 4.1?
I will upgrade PowerDNS in the coming weeks and will write a new article about it.
Hendra from Indonesia wrote on Jan 15th, 2022:
Thank for structured article, it is very helpful for me.
1. What command to show this : "On the slave server, the following log entries appear:"
2. I am using tcpdump -n 'host ip_host and port 53' and get " notify Refused*- 0/0/0 (27)"
Please guide some suggestions.
Nick from Collogne wrote on May 12th, 2021:
Future Tip.
Up from Version 4.5
superslave=yes
is deprecated and will be renamed to:
autosecondary=yes
see official doc: https://doc.powerdns.com/authoritative/settings.html#superslave
Nick from wrote on May 8th, 2021:
Ab from Powerdns 4.3 u must add another command to the slave server:
add:
superslave=yes
ck from Switzerland wrote on Jun 18th, 2020:
Frank, to my knowledge you only need to run the notify command with the domain name (example.com), without mentioning a slave server. PowerDNS looks up all NS records in the domain and sends a notify to all the servers being a nameserver: pdns_control notify example.com.
Frank from wrote on Jun 17th, 2020:
Hi, when I issue the command
pdns_control notify-host mydomain.dev ns.mydomain.local
I get
Unable to convert 'ns.mydomain.local' to an IP address
I also added the ip in /etc/hosts
192.168.4.8 ns.mydomain.local
AWS Android Ansible Apache Apple Atlassian BSD Backup Bash Bluecoat CMS Chef Cloud Coding Consul Containers CouchDB DB DNS Database Databases Docker ELK Elasticsearch Filebeat FreeBSD Galera Git GlusterFS Grafana Graphics HAProxy HTML Hacks Hardware Icinga Influx Internet Java KVM Kibana Kodi Kubernetes LVM LXC Linux Logstash Mac Macintosh Mail MariaDB Minio MongoDB Monitoring Multimedia MySQL NFS Nagios Network Nginx OSSEC OTRS Office PGSQL PHP Perl Personal PostgreSQL Postgres PowerDNS Proxmox Proxy Python Rancher Rant Redis Roundcube SSL Samba Seafile Security Shell SmartOS Solaris Surveillance Systemd TLS Tomcat Ubuntu Unix VMWare VMware Varnish Virtualization Windows Wireless Wordpress Wyse ZFS Zoneminder