This post is the second part of a workshop on the PowerDNS DNS server. In the first part of this workshop, we set up the PowerDNS server and it’s MySQL database backend. In this part of the workshop, I will show you how to add some domain data to your database and how to synchronize this data to other PowerDNS servers automatically by using the so-called supermaster concept of PowerDNS. I will also show you how to enable AXFR transfers to ensure compatibility with remote Bind slave servers.
Prerequisites
For the rest of this workshop it is assumed that you’ve got two PowerDNS installations on two separate physical hosts with the IP addresses 192.168.0.1 and 192.168.1.2, respectively. The first server has the host name dns.example.net and the second server has the host name dns2.example.net.
Configure Master and Slave
You probably want one DNS server to act as the master server and a number of additional servers to act as slaves. PowerDNS supports multiple master servers for one domain and it can be slave and master at the same time.
We will now configure dns.example.net as the master and dns2.example.net as the slave. To do this, add master to the configuration file of the first server and slave to the configuration file of the second server.
In a traditional setup, you would configure a domain name both on the master and the slave server. Additionally, you would specify record data for the domain name on the master server. The slave would then query the master server and download the record data. Whenever you change the record data on the master server, it would notify the slave server and the slave server would refresh the record data by downloading the new record data from the master server. In fact, you can do this with PowerDNS and it will work just fine. But PowerDNS can do more: If you tell your slave(s), that your master is a so-called supermaster, you do not need to setup new domain names on the slave. All you need to do is to setup the new domain name and its record data on the master server. If the domain has a SOA record and your slave is listed as one of the authoritative name servers for the domain, the master will notify your slave of the new domain name. Your slave recognizes, that your master is a supermaster server and adds the domain name to its configuration automatically. It works like magic.
To tell your slave, that your master server is a supermaster server, execute the following SQL statement on your slave’s MySQL server.
INSERT INTO pdns.supermasters (`ip`, `nameserver`, `account`) VALUES ('192.168.0.1', 'dns2.example.net', 'test');
This tells your slave, that your PowerDNS server with the IP address 192.168.0.1 is a supermaster server. As you will see later, PowerDNS supports the concept of accounts. These do not have any influence on the operation of PowerDNS. You can specify account information for each domain name, which might be useful, if you want to find all domain names of a certain customer. If PowerDNS sets up a new domain name of a supermaster, it uses account information specified in the supermasters table for that supermaster server. In our case, all domains of the supermaster server dns.example.net will be added with the account information test. Note, that the nameserver column of the supermasters table is not the host name of the supermaster server. It is the host name of the slave server. Before the slave adds a new domain name from our supermaster server, it checks that the host name you specify in the the nameserver column is listed as one of the authoritative DNS servers for that domain name. Thus, we need to add the name of our slave there.
Enable AXFR
To exchange domain name and record data, your PowerDNS servers will use a method that is called AXFR. For security reasons, AXFR is disabled by default. Edit the configuration files of your PowerDNS master server:
allow-axfr-ips=192.168.2.1disable-axfr=no
This will enable AXFR for the IP address of your slave server. Do not allow AXFR for any server. This would pose a security risk. If you’ve got multiple slave servers, add all the IP addresses of the slave servers separated by a comma. AXFR is compatible with other name server software (e.g. Bind).
Running PowerDNS
PowerDNS should be in a state now, where it can start and connect to the MySQL database with no problems. For now, we will start PowerDNS in monitoring mode. That way we can follow everything that happens live on the console. To start up PowerDNS in monitoring mode, use the following command.
/etc/init.d/pdns monitor
Later, you may want to run PowerDNS in the background. To do this just run the following command.
/etc/init.d/pdns start
Once you have started up both the master and the slave PowerDNS server we can start adding domain names.
Adding your first domain name
To add a new domain name, you need to add a new entry to the domains table of your database. To do so, execute the following SQL query on the master server:
INSERT INTO `pdns.domains` (`id`, `name`, `type`, `account`) VALUES (1, 'example.com', 'MASTER', 'test');
This will add the example.com domain name to the database. The type MASTER indicates, that our master server will be the master for this domain. The account name is optional, it is for your information only. It is important to note, that the id of our new domain name is 1. We’ll need this in a second.
Next, we need to add some records, i.e. some zone data, to the database for PowerDNS to serve. The records need to be added to the records table of the database. PowerDNS supports a number of different records. Depending on the type of the record, you need to provide different values for the type, content and prio columns. Check the PowerDNS documentation on supported record types and their storage to get an idea of what you need. For your convenience, I’ll give you a few examples of common record types.
The first thing you want to add is a SOA record. A typical SOA record would look like this:
INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`) VALUES (1, 'example.com','SOA', 'dns.example.net. hostmaster.example.net. 2009042301 10800 3600 604800 3600', 3600);
Note the domain_id, which is set to the id value of our example.com domain. Then there is the fully qualified domain name, that this record is valid for. You are probably familiar with the values of the type, content and ttl columns. If not, check the documentation.
Next, let’s add a few name servers. It is important that your master and all your slaves are listed here, of course.
INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`) VALUES (1, 'example.com','NS', 'dns.example.net', 3600);INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`) VALUES (1, 'example.com','NS', 'dns2.example.net', 3600);
You probably want some A records:
INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`) VALUES (1, 'example.com','A', '192.168.0.3', 3600);INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`) VALUES (1, 'sales.example.com','A', '192.168.0.4', 3600);INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`) VALUES (1, '*.example.com','A', '192.168.0.2', 3600);
The first of these records is for the example.com domain name. The second is for a subdomain, i.e. sales.example.com. The third A record is special. It is a wildcard record. It matches any subdomain, that is not already specified, i.e. everything except example.com and sales.example.com.
Let’s finish by adding some MX records:
INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`, `prio`) VALUES (1, 'example.com', 'MX','mail.example.net', 3600, 10);INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`, `prio`) VALUES (1, 'example.com', 'MX','mailbackup.example.net', 3600, 20);
Within a short time you will see the following information showing up in the log file of your slave server. Don’t be impatient, it takes some time. You should see something within a minute, though.
Feb 07 21:43:26 Received NOTIFY for example.com from 192.168.0.1 for which we are not authoritativeFeb 07 21:43:26 Created new slave zone 'example.com' from supermaster 192.168.0.1, queued axfrFeb 07 21:43:27 gmysql Connection succesfulFeb 07 21:43:27 No serial for 'example.com' found - zone is missing?Feb 07 21:43:27 AXFR started for 'example.com', transaction startedFeb 07 21:43:27 AXFR done for 'example.com', zone committed
And the equivalent on the master server:
Feb 7 21:43:20 1 domain for which we are master needs notificationsFeb 7 21:43:20 Queued notification of domain 'example.com' to 192.168.1.2Feb 7 21:43:21 AXFR of domain 'example.com' initiated by 192.168.1.2Feb 7 21:43:21 Removed from notification list: 'example.com' to 192.168.1.2 (was acknowledged)Feb 7 21:43:21 gmysql Connection succesfulFeb 7 21:43:21 AXFR of domain ‘example.com’ to 192.168.1.2 finished Feb 7 21:43:23 No master domains need notifications
This looks like a successful AXFR of the example.com domain name. Let’s see, if the domain was really added to the MySQL database on the slave server:
mysql> SELECT * FROM pdns.domains WHERE name='example.com';+----+--------------+---------------+------------+-------+-----------------+---------+| id | name | master | last_check | type | notified_serial | account |+----+--------------+---------------+------------+-------+-----------------+---------+| 1 | example.com | 192.168.0.2 | 1234039407 | SLAVE | NULL | test |+----+--------------+---------------+------------+-------+-----------------+---------+1 row in set (0.00 sec)
Quite cool, isn’t it? You can also query the records table. All your records will be there. Every time you add a new record and raise the serial number, PowerDNS will notify your slave and the record data will be updated automatically.
Adding slave domains
Sometimes, you might want to add a slave domain to one of your servers manually. Suppose your master server acts as a slave server for the domain example.org. Say, the master server of the example.org domain is a remote Bind server with the IP address 192.168.2.34. First, make sure that AXFR with that server is allowed (see above). Then, execute the following SQL query on your server.
INSERT INTO `pdns.domains` (`id`, `name`, `master`, `type`, `account`) VALUES (2, 'example.org', '192.168.2.34', 'SLAVE', 'test');
VoilĂ . That’s it. PowerDNS will take care of the rest.
Limitations of the supermaster mode
Unfortunately, supermaster mode is not equivalent to database synchronization. Automatic set up of new domain names and record data works like a charm. What doesn’t work, though, is the automatic deletion of domain names. If you delete your domain name on the master server, you need to delete it on all slaves manually.
Tags: debian, dns, howto, pdns, powerdns, workshop
Shameless plug: If this post was useful to you, please consider buying yourself something from one of my Amazon stores: US store, UK store, FR store, DE store, CA store. If you're not into Amazon, why not donate something to GNOME, Mozilla or Wikipedia? Thank you!



[...] PowerDNS is setup successfully. The initial setup is completed. See you later for part two of this workshop, in which we will insert some random domain data into our new database and setup a typical [...]
Superb guide, but I seem to have problems with the slave server, it does not seem to get it’s updates for some reason, or rather, the masterserver does not notify the slave server. Where does the master-server actually find out who is his slave servers? I cannot see any configuration for this, although PowerDNS is truly awesome, it looks kinda weird that it doesn’t need to be specified.
Kind regards,
Vegard Hansen
Hei Vegard,
during the set-up of a new domain name, you’ll add some “NS” records (see above), which specify the master and slave DNS servers of your domain name. This is the relevant configuration. The master server will look at the NS records and initiate an AXFR transfer with the slaves, if everything is set up correctly.
Have a look at the DB and check that all the records are there. Check that everything is set up correctly. What does the log file/monitor mode output of PowerDNS say?
There is also a tool called pdns_control (see http://doc.powerdns.com/pdns-internals.html#PDNSCONTROL for more info) that you can use to trigger a notify on demand and have PowerDNS rediscover the database, etc. Check if that works. Normally this should not be necessary, though. If you can’t get it to work at all, feel free to send me a mail and I’ll have a look.
Cheers!
:-) Patrick
Hei hei, Patrick :-)
Thanks for the tips, I will double check my installation, and see if there is any inconstancy! Monitor says that it loads up gmysql-module fine, and that it accept connections. Other than that monitor gives me the standard output you’d expect, like opening up UDP-connections, and denying alot of recursor-requests from misc. Internet drones.
They are not running as recursor, as these nameservers is supposed to only serve as … nameservers. This (to my knowledge) should not have anything to do with AXFR. AXFR is actually configured on both servers. I have tried to only have it active on one server at a time too. Could I be wrong?
I’ll try to go over things a few more times and check some documentation (pdns_control), but i might have to take you up on that email ;-)
Kind regards,
Vegard
Aaah – pdns_contol did the trick! Thanks alot!
Kind regards,
Vegard
Hi,
excellent tutorial. How much harder is to setup a Bind (master) / Powerdns (slave)? Im getting crazy to achieve that.
Thanks