
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.
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
- Ensure that your firewall is allowing traffic on port 53 both UDP and TCP. If you do not, you’ll encounter strange errors with the DNS server not being found. (Ahem, yes, I did this recently.)
- Test the setup by running PowerDNS in monitor mode:
$ sudo /etc/init.d/pdns monitor Jan 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 3600 Received 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 says
As 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;
- Ensure pdns is set to run at boot time.
$ sudo /sbin/chkconfig --level 35 pdns on
- Start the services as a dæmon and you’re done.
$ sudo /etc/init.d/pdns start
Updates
- 2009-01-20
- Fixed the section on local-address in the configuration file which prevented outside machines from accessing the name server.
- 2010-04-21
- Fixed error caught by Matt. Thanks, Matt!
- 2011-01-22
- Added a note to remind that port 53 must be opened for both TCP and UDP.
Pingback: Setting Up Public Name Servers | James Reuben Knowles
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?
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?
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.
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
why i can’n nslookup google.com when i install powerdns ?
** server can’t find google.com: SERVFAIL
any suggestion ?
thanks
I would highly recommend you subscribe to the mailing. You can find more information on the PowerDNS wiki.
Excellent starters guide, got it up and running in no time.
Just a note if migrating from BIND 9, PowerDNS comes with a tool called ‘zone2sql’ which allows you to convert your BIND zones to gMYSQL format.
Do something like…
/usr/bin/zone2sql -gmysql –named-conf=
You can also process individual zone files, as opposed to your entire conf file.
That’s a great comment, Gareth. I’ve never had the need to migrate, but I’m sure it’s a common thing to do. Thanks!
The test databse works great SOA comes right up. But when i try my real website SOA is missing. A and MX are all there. I Don’t get it and I want to. Any Ideas. Thanks!
I’m not an expert on either DNS or PowerDNS unfortunately. It’s usually a small thing, like when I set up another server recently I forgot to open port 53 for UDP.
I would highly recommend you subscribe to the mailing list and look on the PowerDNS wiki.