Setup PowerDNS and Poweradmin on Ubuntu with MySQL Backend

PowerDNS and Poweradmin can be combined to create a simple, lightweight and easy to manage authoritative DNS server. These instructions have been tested on Ubuntu LTS releases 14.04 and 16.04.

This guide assumes you have a MySQL Server and Nginx instances setup. If not, you can follow the guides for MySQL and Nginx.

We’re going to use sudo a lot. Let’s launch a root shell

sudo -i

Update repositories

apt-get update

Install PowerDNS

apt-get install pdns-server pdns-backend-mysql

Select no when asked to automatically configure databases

Remove included config files- we want to configure things manually

rm /etc/powerdns/pdns.d/*

Create and edit a new config file

nano /etc/powerdns/pdns.d/pdns.conf

Add the following, changing credentials to suit the environment

launch=gmysql

gmysql-host=YOUR.MYSQL.SERVER.ADDRESS
gmysql-user=powerdns
gmysql-dbname=powerdns
gmysql-password=SUPER.SECURE.PASSWORD

recursor=8.8.8.8

The line recursor=8.8.8.8 will forward all unresolvable queries to Google DNS

Next, setup the MySQL database. On the MySQL server

mysql -u root -p

Create the PowerDNS database user

CREATE USER 'powerdns'@'POWER.DNS.SERVER.ADDRESS' IDENTIFIED BY 'SUPER.SECURE.PASSWORD';

Create PowerDNS database

CREATE DATABASE powerdns;

Grant the powerdns user privileges

GRANT ALL PRIVILEGES ON `powerdns`. * TO 'powerdns'@'POWER.DNS.SERVER.ADDRESS';

Flush privileges

FLUSH PRIVILEGES;

Select the PowerDNS database

USE powerdns;

Create required tables

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,
  disabled              TINYINT(1) DEFAULT 0,
  ordername             VARCHAR(255) BINARY DEFAULT NULL,
  auth                  TINYINT(1) DEFAULT 1,
  PRIMARY KEY (id)
) Engine=InnoDB;

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


CREATE TABLE supermasters (
  ip                    VARCHAR(64) NOT NULL,
  nameserver            VARCHAR(255) NOT NULL,
  account               VARCHAR(40) NOT NULL,
  PRIMARY KEY (ip, nameserver)
) Engine=InnoDB;


CREATE TABLE comments (
  id                    INT AUTO_INCREMENT,
  domain_id             INT NOT NULL,
  name                  VARCHAR(255) NOT NULL,
  type                  VARCHAR(10) NOT NULL,
  modified_at           INT NOT NULL,
  account               VARCHAR(40) NOT NULL,
  comment               VARCHAR(64000) NOT NULL,
  PRIMARY KEY (id)
) Engine=InnoDB;

CREATE INDEX comments_domain_id_idx ON comments (domain_id);
CREATE INDEX comments_name_type_idx ON comments (name, type);
CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);


CREATE TABLE domainmetadata (
  id                    INT AUTO_INCREMENT,
  domain_id             INT NOT NULL,
  kind                  VARCHAR(32),
  content               TEXT,
  PRIMARY KEY (id)
) Engine=InnoDB;

CREATE INDEX domainmetadata_idx ON domainmetadata (domain_id, kind);


CREATE TABLE cryptokeys (
  id                    INT AUTO_INCREMENT,
  domain_id             INT NOT NULL,
  flags                 INT NOT NULL,
  active                BOOL,
  content               TEXT,
  PRIMARY KEY(id)
) Engine=InnoDB;

CREATE INDEX domainidindex ON cryptokeys(domain_id);


CREATE TABLE tsigkeys (
  id                    INT AUTO_INCREMENT,
  name                  VARCHAR(255),
  algorithm             VARCHAR(50),
  secret                VARCHAR(255),
  PRIMARY KEY (id)
) Engine=InnoDB;

CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);

Setup Poweradmin

Again, launch a root shell or prefix all commands with sudo

sudo -i

Change to the web directory root

cd /usr/share/nginx/html

On newer releases, this will likely be

cd /var/www/html

If unsure, check your default Nginx config at

/etc/nginx/sites-available/default

Download Poweradmin from Github

git clone https://github.com/poweradmin/poweradmin.git

Create config file

touch /usr/share/nginx/html/poweradmin/inc/config.inc.php

Change owner to the user the web server runs as and set permissions

chown -R www-data:www-data /usr/share/nginx/html/poweradmin
chmod -R 755 /usr/share/nginx/html/poweradmin

Here is an example Nginx config using php5 and the sub domain poweradmin.example.com

server {
        listen 80;

        root /usr/share/nginx/html/poweradmin;

        index index.php;

        server_name poweradmin.example.com;

        location / {
                try_files $uri $uri/ /index.php;
        }

        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
                root /usr/share/nginx/html;
        }

        location ~ \.php$ {
                try_files $uri =404;
                include fastcgi_params;
                fastcgi_index index.php;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
}

Reload Nginx to have to config take effect

service nginx reload

In a web browser, visit

http://poweradmin.example.com/install

Follow the steps, filling in credentials along the way. Finally, remove the installer files

rm -rf /usr/share/nginx/html/poweradmin/install

Visit poweradmin.example.com, where you can log in with the credentials used during setup, add DNS zones and finally, add records.

Check the status of PowerDNS with

service pdns status

Verify DNS queries are being resolved

dig example.com @127.0.0.1

4 Comments

  1. How did you get around the issue of no PHP5 for Ubuntu 16 in your testing for Nginx? I have been banging my head against a wall on that one for awhile. PHP7 is not compatible for poweradmin from what I have been finding on google .

Leave a Reply

Your email address will not be published. Required fields are marked *