Installing PowerDNS

There are notes on installing PowerDNS on a CentOS 5 server. This is generic enough that it aught to work on any RPM based Linux distro with yum installed.
2009-01-20 Update: Fixed the section on local-address in the configuration file which prevented outside machines from accessing the name server.
2010-04-21 Update: Fixed error caught by Matt. Thanks, Matt!
Preliminary Setup
- Ensure BIND is not installed.
$ sudo yum erase bind
- Create a user to run as.
$ sudo useradd -c "PowerDNS" -M -r -s /sbin/nologin pdns
- Install MySQL
- Set MySQL root password. Please use different passwords.
$ /usr/bin/mysqladmin -u root password 'new password'
$ /usr/bin/mysqladmin -u root -h localhost password 'new password' - Run the following MySQL commands. Please change the passwords in the file first.
$ mysql --user=root mysql -p
Enter password:
mysql> source database-install.sql;
The database-install.sql is something I created. It has the following:
################################################################################
#
# Adjust users.
#
# !!! WARNING !!! Change the two passwords below!
#
################################################################################# Change the root password here.
UPDATE mysql.user SET password = PASSWORD('password') WHERE user = 'root';# Change the PowerDNS password here.
CREATE USER 'powerdns'@'localhost' IDENTIFIED BY 'password';DROP USER '';
FLUSH PRIVILEGES;
################################################################################
#
# Create database and tables.
#
################################################################################
CREATE DATABASE powerdns;USE powerdns;
CREATE TABLE domains
(
id INT AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
master VARCHAR(128) DEFAULT NULL,
last_check INT DEFAULT NULL,
type VARCHAR(6) NOT NULL,
notified_serial INT DEFAULT NULL,
account VARCHAR(40) DEFAULT NULL,
PRIMARY KEY (id)
) type=InnoDB;CREATE UNIQUE INDEX name_index ON domains(name);
CREATE TABLE records
(
id INT AUTO_INCREMENT,
domain_id INT DEFAULT NULL,
name VARCHAR(255) DEFAULT NULL,
type VARCHAR(6) DEFAULT NULL,
content VARCHAR(255) DEFAULT NULL,
ttl INT DEFAULT NULL,
prio INT DEFAULT NULL,
change_date INT DEFAULT NULL,
PRIMARY KEY(id)
) type=InnoDB;CREATE INDEX rec_name_index ON records(name);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);CREATE TABLE supermasters
(
ip VARCHAR(25) NOT NULL,
nameserver VARCHAR(255) NOT NULL,
account VARCHAR(40) DEFAULT NULL
) type=InnoDB;GRANT ALL ON domains TO powerdns;
GRANT ALL ON records TO powerdns;
GRANT SELECT ON supermasters TO powerdns;
$ sudo yum install mysql-server
$ sudo /sbin/service mysqld start
$ sudo /sbin/chkconfig --level 35 mysqld on
PowerDNS Setup
- Download PowerDNS RPM.
- Install RPM.
- Change the permissions on the PowerDNS config file since it holds passwords in plain text.
sudo chmod 440 /etc/powerdns/pdns.conf - Edit the PowerDNS config file.
sudo vim /etc/powerdns/pdns.conf - Find the setgid and setuid lines. Add the appropriate lines
setgid=pdns
setuid=pdns - Find the launch line. Add information for the MySQL database.
launch=gmysql
gmysql-host=localhost
gmysql-user=powerdns
gmysql-password=password
gmysql-dbname=powerdns
gmysql-socket=/var/lib/mysql/mysql.sock - Find the local-address line and add the IP address of the publicly-facing NIC. See Chapter 15 of the documentation.
local-address=xxx.xxx.xxx.xxx - Find the log-dns-details line and add the following:
log-dns-details=off
Testing
- Test the setup by running PowerDNS in monitor mode:
$ sudo /etc/init.d/pdns monitorJan 04 22:46:34 This is a standalone pdns
Jan 04 22:46:34 UDP server bound to 127.0.0.1:53
Jan 04 22:46:34 TCP server bound to 127.0.0.1:53
Jan 04 22:46:34 PowerDNS 2.9.21.2 (C) 2001-2008 PowerDNS.COM BV (Nov 16 2008, 14:07:43, gcc 4.2.3 (Ubuntu 4.2.3-2ubuntu7)) starting up
Jan 04 22:46:34 PowerDNS comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it according to the terms of the GPL version 2.
Jan 04 22:46:34 Set effective group id to 105
Jan 04 22:46:34 Set effective user id to 102
Jan 04 22:46:34 Creating backend connection for TCP
Jan 04 22:46:34 gmysql Connection succesful
Jan 04 22:46:34 About to create 3 backend threads for UDP
Jan 04 22:46:34 gmysql Connection succesful
Jan 04 22:46:34 gmysql Connection succesful
Jan 04 22:46:34 gmysql Connection succesful
Jan 04 22:46:34 Done launching threads, ready to distribute questions - If there are problems, see Chapter 4 of the documentation.
- Test the operation. Leave the monitor (previous item) running. Pull up a new shell. Execute the following host command and look for a similar response.
$ host www.test.com 127.0.0.1
Using domain server:
Name: 127.0.0.1
Address: 127.0.0.1#53
Aliases:Host www.test.com not found: 2(SERVFAIL)
In the monitor you should see the following message:
Not authoritative for 'www.test.com', sending servfail to 127.0.0.1 (recursion was desired) - Add some test records to the database:
$ mysql --user=root -p
mysql> source database-test.sql;
That file has the following commands, which I copied from the InterNet:
USE powerdns;INSERT INTO domains (name, type) values ('test.com', 'NATIVE');
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'test.com','localhost ahu@ds9a.nl 1','SOA',86400,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'test.com','dns-us1.powerdns.net','NS',86400,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'test.com','dns-eu1.powerdns.net','NS',86400,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'www.test.com','199.198.197.196','A',120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'mail.test.com','195.194.193.192','A',120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'localhost.test.com','127.0.0.1','A',120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'test.com','mail.test.com','MX',120,25); - Run the test again:
$ host www.test.com 127.0.0.1
Using domain server:
Name: 127.0.0.1
Address: 127.0.0.1#53
Aliases:www.test.com has address 199.198.197.196
- Try another test.
$ host -v -t mx www.test.com 127.0.0.1
Trying "www.test.com"
Using domain server:
Name: 127.0.0.1
Address: 127.0.0.1#53
Aliases:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27585
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0;; QUESTION SECTION:
;www.test.com. IN MX;; AUTHORITY SECTION:
test.com. 86400 IN SOA localhost. ahu.ds9a.nl. 1 10800 3600 604800 3600Received 86 bytes from 127.0.0.1#53 in 21 ms
- If you are receiving the following in the monitor:
Authoritative empty NO ERROR to 127.0.0.1 for 'www.test.com' (AAAA), other types do exist.
Then you did not put the log-dns-details=off in the configuration file. See the documentation, which saysAs the name implies, this is not an error. It tells you there are questions for a domain which exists in your database, but for which no record of the requested type exists. To get rid of this error, add log-dns-details=off to your configuration.
- Remove the test records.
$ mysql --user=root -p
mysql> USE powerdns;
mysql> DELETE FROM domains;
mysql> DELETE FROM records; - Add pdns to chkconfig and ensure that it’s set to run at boot time. I prefer to use system-config-services, but it’s just a graphical wrapper around chkconfig.
- Start the services as a dæmon and you’re done.
$ sudo /etc/init.d/pdns start

February 15th, 2009 at 11:47 pm
[...] This article talks about setting up your own public name server, allowing you to have complete control over DNS for your domains. It will cover the steps I went through to achieve this. Where I encountered difficulty will have greater amounts of detail. The actual installation of a name server is covered in my article Installing PowerDNS. [...]
May 5th, 2009 at 7:09 pm
anyluck setting up toplevel domains? I recently joined a vpn network, and i have tried to add a domain like .brd and well it doesn’t see it as a top level domain and refuses to add it.
any ideas?
May 5th, 2009 at 7:37 pm
Hey Mike,
I’ve not tried to set up a TLD. I think this would be a perfect question for the PowerDNS mailing list. Have you tried the elist yet?
April 20th, 2010 at 8:36 pm
Nice article, very useful for a PowerDNS first timer! Worked right away on CentOS 5… Thanks!
BTW, small error on the line : sudo yum /sbin/service mysqld start (yum?)
Thanks!
Matt.
April 20th, 2010 at 11:03 pm
Matt,
Thank you very much for catching that error! I’ve used these notes a couple of times and blew right past it.
Glad you found it useful, and thanks again for the bug catch.
James