PowerDNS: Database Back End and Poweradmin Web GUI

PowerDNS is a secure, scalable, and reliable DNS server solution licensed under the GPL. We show you how to create a primary server with a MySQL back end managed by a Poweradmin web GUI.

PowerDNS is an amazing, feature-rich and versatile DNS server solution. Originally created by PowerDNS.com BV as a commercial product, it was later opened up and licensed under the GPL. Today, it thrives with both commercial and community contributions, making it an outstanding DNS server alternative.

DNS, of course, is the distributed, hierarchical naming system that allows us to map what would be IP addresses to much more humanly digestible addresses. Thankfully, we no longer live in the early days of the Arpanet (precursor to today’s Internet), where we had to transfer large host files from node to node. Its compact codebase and focus on security, scalability, and reliability make PowerDNS (PDNS) a great nameserver choice; it is jam packed with features that would impress any network or sys admin (Table 1).

Table 1: PowerDNS Features
Authoritative DNS server (hosting)
Resolving DNS server (caching)
API to provision zones and records
DNSSEC support (as of 3.x)
Web-based management options
DNS data stored in plaintext (BIND compatible)
IPv4 and IPv6, UDP/TCP, 100% compliant
MySQL, PostgreSQL, Microsoft SQL Server, Oracle, Sybase database back ends
Load balancing/failover algorithms
SNMP support
Remotely pollable statistics for real-time graphing
Optional build in web server
Debugging tools
Support for Linux, BSD, Unix

PDNS Key Components

PowerDNS has two key distinct components: the authoritative server and the recursor. Other DNS servers combine these roles, but PowerDNS holds them separate, and you can configure PDNS as either option. An authoritative name server is just what it sounds like: It is the original and conclusive source of DNS zone information for a particular domain. A zone is merely a portion or set of administrative space. Authoritative domain servers are of two types: primary and secondary.

Primary Name Server. Sometimes called a master server, this is the original and definitive source for all zone records for a domain.

Secondary Name Server. Often called a slave server, this server is an identical replica used to provide redundancy and high availability. It goes without saying that providing additional redundancy is vital to a service as critical as DNS.

PowerDNS Recursor. The PowerDNS Recursor, on the other hand, simply provides caching or a standalone recursive resolver for clients accessing your network or the greater Internet (i.e., it is your first line of DNS for client machines). Recall that it isn’t authoritative but simply provides query resolution to network client resolvers (client-side portion used to perform DNS queries) on your local machine.

Supermaster/Superslave. The supermaster feature set in PowerDNS allows you to automate the provisioning of slaves. Superslaves can configure themselves automatically as a slave for a zone when they receive notification from a known supermaster.

PowerDNS Authoritative Server (MySQL Back End)

PowerDNS has many configuration options – so many, in fact, that someone could easily write an entire book on each. As such, I will limit my coverage herein to its use with a primary server with a MySQL back end with the Poweradmin web GUI. Because of scope constraints and the well-documented nature of the project, I’m sure you will be able to add secondary and tertiary servers as needed.

For information on configuring with a BIND back end (i.e., using BIND configuration files), please see my previous article in ADMIN Online on PowerDNS with BIND back end.

An Example Environment

The example environment will be built upon Ubuntu Server 12.04 LTS Precise Pangolin, and I'm assuming you have built your server and patched it as follows before continuing with this exercise:

primary:~#aptitude update && aptitude dist-upgrade

Moving forward, I'd like to automate updates for my PowerDNS server. To do so, I will use the unattended-upgrades package for Ubuntu Server 12.04 LTS. If you chose to load security updates while setting up Ubuntu, this package will already be installed:

primary:~$aptitude install unattended-upgrades

Configure it by uncommenting and changing the items in bold in the following configuration file:

primary:~$nano /etc/apt/apt.conf.d/50unattended-upgrades
 
// Automatically upgrade packages from these (origin:archive) pairs
Unattended-Upgrade::Allowed-Origins {
        "${distro_id}:${distro_codename}-security";
        "${distro_id}:${distro_codename}-updates";
 
// Send email to this address for problems or packages upgrades
// If empty or unset then no email is sent, make sure that you
// have a working mail setup on your system. A package that provides
// 'mailx' must be installed. E.g. "user@example.com"
Unattended-Upgrade::Mail "username@yourdomain.com";

Next, edit the file 10periodic located in (/etc/apt/apt.conf.d/10periodic) as listed below to check for updates once a day:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

Be aware that all unattended upgrades are logged in /var/log/unattended-upgrades, so you might want to review it periodically, along with your other logs. Additionally you could do much the same with the commercial, and more feature-rich, Ubuntu Landscape. Now that the base system is set, you can fire up another box and set it up the same way.

Don’t Forget Redundancy

Redundancy is a must. Like any service as vital as DNS, you should build redundancy into your infrastructure – which means at least two or more of everything – or else you will need much more than two aspirins to deal with headaches caused by downtime. In the case of PowerDNS, that means two or three DNS servers; if you are using a database back end, you should not have a single back end for your entire infrastructure; rather, you should match them up with one back end per PowerDNS server.

With your servers up and running, you can now install your packages and configure them.

Installing PowerDNS – Creating a Master DNS Server

To get your configuration going, you need to install PowerDNS on your primary or master server first. To do so, modify the following in /etc/powerdns/pdns.d/pdns.local.gmysql:

#
# MySQL back end configuration
#
launch=gmysql
# Tells our PowerDNS server we are using MySQL backend

config-dir=/etc/powerdns/pdns.d/
#Specify our configuration file

gmysql-host=127.0.0.1
#Configures the IP address that PowerDNS will listen on

gmysql-user=puser
#Our configured PowerDNS username

gmysql-password=pleasepickastrongpassword
#This is our MySQL password. Please, for the love of all that is sacred, stop using weak passwords!

gmysql-dbname=pdns
#This details which MySQL database PDNS should use.

local-address=192.168.1.10
#Specifies the local IP for PowerDNS to listen on.

master=yes
#This tells PowerDNS to run this as the primary server. This primary server will send out a special notify packet to notify the secondary or slave of updates.

setgid=pdns
#Sets Group ID to this one for improved security

setuid=pdns
#Sets user id to this for improved security

version-string=Hostfile 0.1 Alpha
#Bogus server version is divulged via dig quiry, such as dig @ns1.example.com -c CH -t txt version.bind  There is no security through obscurity, but there is certainly absurdity... =P

Finally, you want to restart your PowerDNS service with the following:

sudo service pdns restart

Now with a base PowerDNS configuration, you can go about setting up your MySQL back end.

Installing MySQL

To begin, simply install MySQL with the command:

primary:~$sudo apt-get install mysql-server mysql-common

Next, as part of the installer, you will be asked to set your MySQL root passwords as below:

New password for the MySQL "root" user: 
pleasepickastrongpassword
Repeat password for the MySQL "root" user: 
pleasepickastrongpassword

Configuring Your MySQL Server

Your yet-to-be-configured server needs a bit of tweaking before you can add databases and users, so navigate over to edit /etc/mysql/my.cnf in your favorite text editor. In this case, you are going to change the address to which the MySQL servicer listens on your server localhost:

Bind-address            = 127.0.0.1

Connecting to the MySQL Server

Now you can connect to your newly minted MySQL server and begin configuring it:

primary:~$mysql -h localhost -u root -p

Next, you need to create and configure a MySQL database:

create database pdns;

Creating a Database User

Now that you have created a database, you need to add a user that will have access to that database. Doing so is as easy as:

GRANT ALL ON pdns.* TO 'puser'@'localhost' IDENTIFIED BY 'pleasepickastrongpassword';
GRANT ALL ON pdns.* TO 'puser'@'localhost.localdomain' IDENTIFIED BY 'pleasepickastrongpassword';
FLUSH PRIVILEGES;

Next, you create the database required for your install of PowerDNS:

use pdns;

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)
) Engine=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(10) DEFAULT NULL,
  content         VARCHAR(64000) DEFAULT NULL,
  ttl             INT DEFAULT NULL,
  prio            INT DEFAULT NULL,
  change_date     INT DEFAULT NULL,
  primary key(id)
) Engine=InnoDB;

CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);

create table supermasters (
  ip         VARCHAR(64) NOT NULL,
  nameserver VARCHAR(255) NOT NULL,
  account    VARCHAR(40) DEFAULT NULL
) Engine=InnoDB;

Now, leave the MySQL shell with:

quit;

Note on MySQL Security. Obviously, you can do much more to secure MySQL, but for the sake of brevity, I don’t include much detail. Like any other application, it deserves some time to improve security from its default install state.

Web GUI

At this point you could, of course, manage this PowerDNS configuration back end in many ways. Unlike simple text-file-based configuration (known as a BIND-compatible back end), you would have to use any number of database management tools, bake your own scripts, or use a Web administration interface. Generally, if you don’t plan to script or code your own solution, going with a web GUI is a good choice. A graphical interface has many benefits, including

  • ease of administration,
  • encouraging proper syntax, and
  • decreasing syntactic errors.

Poweradmin

Poweradmin is an open source, friendly, and easy-to-use web GUI for PowerDNS that supports key features. With this feature-rich web application, you will be managing your DNS environment in no time flat. However, before starting, you need to installed it; like most applications, it has a few prerequisites:

  • MySQL or PostgreSQL
  • Apache
  • PHP
  • Session, gettext, mcrypt
  • PEAR, PEAR::MDB2
  • GNU gettext

Because a nifty Poweradmin package is lacking, you will need to install the prerequisites and then grab the binaries:

primary:~$ sudo apt-get install apache2 libapache2-mod-php5 php5 php5-common php5-curl php5-dev php5-gd php-pear php5-imap php5-mcrypt php5-common php5-ming php5-mysql php5-xmlrpc gettext
primary:~$sudo pear install MDB2
primary:~$sudo pear install MDB2_Driver_mysql

Now that you have your prerequisites, you can install the Poweradmin application itself with:

primary:~$cd /tmp
primary:~$wget https://github.com/downloads/Poweradmin/Poweradmin/Poweradmin-2.1.6.tgz
primary:~$tar xvfz Poweradmin-2.1.4.tgz
primary:~$mv Poweradmin-2.1.4 /var/www/Poweradmin
primary:~$touch /var/www/Poweradmin/inc/config.inc.php
primary:~$chown -R www-data:www-data /var/www/Poweradmin/

Now that you have your prerequisites, you can install the Poweradmin application itself with:

primary:~$cd /tmp
primary:~$wget https://github.com/downloads/Poweradmin/Poweradmin/Poweradmin-2.1.6.tgz
primary:~$tar xvfz Poweradmin-2.1.4.tgz
primary:~$mv Poweradmin-2.1.4 /var/www/Poweradmin
primary:~$touch /var/www/Poweradmin/inc/config.inc.php
primary:~$chown -R www-data:www-data /var/www/Poweradmin/

Now you are ready to fire up the browser of your choice and connect to:

http://primary/Poweradmin/install/index.php

Note that I’ve only highlighted the steps that might require some user customization. Obvious steps in the sequence in Figures 1–4 were excluded explicitly.

Figure 1: Select Your Language

Figure 2: Enter Your MySQL Information

Figure 3: Enter Your Basic DNS Domain Information

Figure 4: Give Poweradmin Rights

Now you want to give limited rights to Poweradmin so it can update the data in the tables. To do this, you should create a new user and give it rights to select, delete, insert, and update records in the PowerDNS database.

After you have added the new user, go back to MySQL and execute:

primary:~$mysql -h localhost -u root -p

use pdns;

GRANT SELECT, INSERT, UPDATE, DELETE
ON pdns.*
TO 'padmin'@'localhost'
IDENTIFIED BY 'pleasepickastrongpassword';
quit;

Once you are finished with initial setup you should do one more thing for security sake: remove the install directory:

primary:~$rm -fr /var/www/Poweradmin/install/

Poweradmin Configuration File

Like other PHP-based web applications, Poweradmin has a core configuration file that you can edit and customize to your heart’s content at:

/var/www/Poweradmin/inc/config.inc.php

In the event you would like to further customize your config file, you can edit this or explore the rest of this application’s subdirectories.

Logging In to Poweradmin

To access your Poweradmin server go to http://primary/Poweradmin/index.php (Figure 5). Once there, you should add your master zone by clicking Add master zone from the initial login screen (Figure 5), add the information required for your base domain, and click Add zone (Figure 6). From here, click on List zones (Figure 7) and then Edit an existing example.com zone, as in Figure 8.

Figure 5: Poweradmin management web GUI.

Figure 6: Adding a master zone.

Figure 7: Listing existing zones.

Figure 8: Editing an existing zone.

As you can see, the GUI is very simple and will guide you through the process of creating your basic required DNS records. Once done, go back to the same domain and add any additional records you would like.

Configure an Iptables Firewall

Personally, I like learning at least two ways to do the same thing. Ubuntu has an option to use its “uncomplicated firewall” tool, which helps you create iptable rules in a rather simple fashion. In this case, create the following uncomplicated firewall rules:

sudo ufw enable
primary:~$ufw logging on
primary:~$ufw default deny
primary:~$ufw allow 22/tcp
primary:~$ufw allow 80/tcp
primary:~$ufw allow 53/udp
primary:~$ufw allow 53/tcp
primary:~$ufw status

Of course, if you are more comfortable doing this with iptables, go right ahead. More stringent rules might be in order, depending on your environment and goals.

DNS and Security

DNS is a commonly exploited service that requires you take time in your engineering stages to deploy it properly. Unfortunately, DNS has supernumerary attack vectors. Although the risks to a service as critical to the functioning of your network as DNS are many, you can take some simple steps to ameliorate them.

Patch, Patch, Patch. As silly as it sounds, some people don’t believe or invest in automating patch management. If you do so, it will solve quite a few known issues.

Split Servers Across Networks. Placing all your DNS servers on a single network space could be highly problematic if that core router dies or if that network comes under a distributed denial of service attack. Split your servers across several properly redundant and fault-tolerant network/server infrastructures.

Firewalls. As we all know, firewalls are by no means perfect, but they are still a good practice. Firing up iptables on your DNS box will at the very least add additional layers to keep out those with malicious intent. Besides, thinking about ingress and egress rules with networks services is always a good discipline.

Explore and Deploy TSIG/TKEY and DNSSEC. Use transaction signature/transaction key (TSIG/TKEY) for securing zone transfers, and deploy DNSSEC to help protect against cache poisoning. Although not detailed herein for brevity’s sake, I point you to the copious documentation on these features on the project website.

I’m a big proponent of thinking of security as a priority in everything I do in Information Technology, and I see a rising consciousness of its importance. When you build with security as step 0, your problem set is dramatically reduced.

Testing the PowerDNS Server

Now that your server is up and running, you should do a bit of testing to make sure it is working:

primary:~$dig +norecurs @127.0.0.1 ns1.example.com A

dig +norecurs @127.0.0.1 ns1.example.com A

; <<>> DiG 9.9.2-P1 <<>> +norecurs @127.0.0.1 ns1.example.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62937
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;ns1.example.com.              IN      A

;; ANSWER SECTION:
ns1.example.com.       86400   IN      A       192.168.1.10

If your server isn’t responding to queries, you can start to troubleshoot the issue by looking to see whether PDNS running with ps and taking a look at your trusty syslog logs (tail your logfiles). Additionally, the feature-rich PDNS package includes the pdns_control application that lets you see the status and restart and all-around control your PowerDNS server. For example, you can:

test to see whether the server is alive:

$ sudo pdns_control ping

purge the cache entries:

$ sudo pdns_control purge

inform the back ends that contents of the domains have changed:

$ sudo pdns_control reload

show usage statistics:

$ sudo pdns_control status

show a specific statistic (use * for complete verbose details):

$ sudo pdns_control 

and restart a PowerDNS instance:

$ sudo pdns_control cycle

Creating Secondary (and Tertiary) Servers

Now that you have created a primary server and it is up and running, you have more work to do to create true redundancy. As I said before, having any single point of failure (SPOF) is always unwise. To that end, you have a number of ways to create a secondary server, but I’ll leave those for you to explore in your own time and hope you will have fun.

I hope this short article has whet your appetite to explore this tremendously performant, feature-rich, flexible DNS software. PowerDNS rocks! Happy Hacking!

#powerdns on Open and Free Technology Community IRC: irc.oftc.net

Powered by eZ Publish™ CMS Open Source Web Content Management. Copyright © 1999-2014 eZ Systems AS (except where otherwise noted). All rights reserved.