You can support us by downloading this article as PDF from the Link below. Download the guide as PDF

In this guide, we will cover the installation of PowerDNS Authoritative Name Server and PowerDNS-Admin on Ubuntu 18.04 and Debian 9 flavors of Linux. PowerDNS is a DNS server, written in C++ and licensed under the GPL. It runs on most Linux and all other Unix derivatives. As of this writing, the latest release is version 4.1.X.

Install PowerDNS on Ubuntu 18.04 / Debian 9

In this section we’re going to install and configure:

  • MariaDB database server.
  • PowerDNS service

Step 1: Install and Configure MariaDB Database Server

We need to install database server which will be used by PowerDNS to store zone files. Note that you also have an option to use text files like BIND. Our database server of choice is MariaDB.

For installation of MariaDB on Ubuntu 18.04, check

Install MariaDB 10.x on Ubuntu 18.04 and CentOS 7

For Debian 9 / Debian use:

How to Install MariaDB 10.3 on Debian 9 / Debian 8

Once the database server is installed and running, proceed to create the PowerDNS Database and User Account in MariaDB.

$ mysql -u root -p

Next is to create powerdns database user and assign privileges:

GRANT ALL ON powerdns.* TO 'powerdns'@'localhost' \
IDENTIFIED BY 'strongpassword';

Flush the privileges to update the user settings:


Switch to powerdns database to create tables:

USE powerdns;

Create the 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 UNSIGNED DEFAULT NULL,
  account               VARCHAR(40) CHARACTER SET 'utf8' DEFAULT NULL,
) Engine=InnoDB CHARACTER SET 'latin1';

CREATE UNIQUE INDEX name_index ON domains(name);

CREATE TABLE records (
  id                    BIGINT 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,
) Engine=InnoDB CHARACTER SET 'latin1';

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

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

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) CHARACTER SET 'utf8' DEFAULT NULL,
  comment               TEXT CHARACTER SET 'utf8' NOT NULL,
) Engine=InnoDB CHARACTER SET 'latin1';

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,
) Engine=InnoDB CHARACTER SET 'latin1';

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,
) Engine=InnoDB CHARACTER SET 'latin1';

CREATE INDEX domainidindex ON cryptokeys(domain_id);

CREATE TABLE tsigkeys (
  id                    INT AUTO_INCREMENT,
  name                  VARCHAR(255),
  algorithm             VARCHAR(50),
  secret                VARCHAR(255),
) Engine=InnoDB CHARACTER SET 'latin1';

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

You can confirm that your tables are created:

[pastacode lang=”bash” manual=”MariaDB%20%5Bpowerdns%5D%3E%20show%20tables%3B%0A%2B——————–%2B%0A%7C%20Tables_in_powerdns%20%7C%0A%2B——————–%2B%0A%7C%20comments%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20cryptokeys%20%20%20%20%20%20%20%20%20%7C%0A%7C%20domainmetadata%20%20%20%20%20%7C%0A%7C%20domains%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20records%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20supermasters%20%20%20%20%20%20%20%7C%0A%7C%20tsigkeys%20%20%20%20%20%20%20%20%20%20%20%7C%0A%2B——————–%2B%0A7%20rows%20in%20set%20(0.000%20sec)%0A” message=”” highlight=”” provider=”manual”/]

Now we have a database and an empty table. PowerDNS should now be able to launch with it.

Step 2: Install PowerDNS on Ubuntu 18.04 / Debian 9

Ubuntu 18.04 comes with systemd-resolve which you need to disable since it binds to port 53 which will conflict with PowerDNS ports.

Run the following commands to disable the resolved service:

sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved

Also, remove the symlinked resolv.conf file

$ ls -lh /etc/resolv.conf 
lrwxrwxrwx 1 root root 39 Jul 24 15:50 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
$ sudo rm /etc/resolv.conf

Then create new resolv.conf file.

sudo echo "nameserver" > /etc/resolv.conf

Note that you can install PowerDNS from the official apt repository or from PowerDNS repository. To install from apt repository, run:

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

Add official PowerDNS repository for Ubuntu 18.04.

$ cat /etc/apt/sources.list.d/pdns.list
deb [arch=amd64] bionic-auth-41 main

Import GPG key:

curl | sudo apt-key add -

Update package list and install PowerDNS package (pdns-server) and MySQL backend (pdns-backend-mysql).

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

For Debian 9, install the packages from the apt repository without adding new repo:

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

When asked whether to configure the PowerDNS database with dbconfig-common, answer No

Configure PowerDNS to use MySQL backend:

Here is my MySQL configuration for PowerDNS:

# cat /etc/powerdns/pdns.d/pdns.local.gmysql.conf 
# MySQL Configuration
# Launch gmysql backend
# gmysql parameters
# gmysql-socket=

Restart pdns service

sudo systemctl restart pdns

You can now test PowerDNS to confirm that the service is online:

[pastacode lang=”bash” manual=”%23%20netstat%20-tap%20%7C%20grep%20pdns%0A%0Atcp%20%20%20%20%20%20%20%200%20%20%20%20%20%200%*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20LISTEN%20%20%20%20%20%2031719%2Fpdns_server%20%20%20%0Atcp6%20%20%20%20%20%20%200%20%20%20%20%20%200%20%5B%3A%3A%5D%3Adomain%20%20%20%20%20%20%20%20%20%20%20%20%20%5B%3A%3A%5D%3A*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20LISTEN%20%20%20%20%20%2031719%2Fpdns_server%20%20%20%0A” message=”” highlight=”” provider=”manual”/]

Check if PowerDNS service is responding correctly:

[pastacode lang=”bash” manual=”%23%20dig%20%40127.0.0.1%0A%0A%3B%20%3C%3C%3E%3E%20DiG%209.11.3-1ubuntu1.1-Ubuntu%20%3C%3C%3E%3E%20%40127.0.0.1%0A%3B%20(1%20server%20found)%0A%3B%3B%20global%20options%3A%20%2Bcmd%0A%3B%3B%20Got%20answer%3A%0A%3B%3B%20-%3E%3EHEADER%3C%3C-%20opcode%3A%20QUERY%2C%20status%3A%20REFUSED%2C%20id%3A%2065465%0A%3B%3B%20flags%3A%20qr%20rd%3B%20QUERY%3A%201%2C%20ANSWER%3A%200%2C%20AUTHORITY%3A%200%2C%20ADDITIONAL%3A%201%0A%3B%3B%20WARNING%3A%20recursion%20requested%20but%20not%20available%0A%0A%3B%3B%20OPT%20PSEUDOSECTION%3A%0A%3B%20EDNS%3A%20version%3A%200%2C%20flags%3A%3B%20udp%3A%201680%0A%3B%3B%20QUESTION%20SECTION%3A%0A%3B.%09%09%09%09IN%09NS%0A%0A%3B%3B%20Query%20time%3A%200%20msec%0A%3B%3B%20SERVER%3A%20127.0.0.1%2353(” message=”” highlight=”” provider=”manual”/]

Install PowerDNS-Admin on Ubuntu 18.04 / Debian 9

PowerDNS-Admin is a PowerDNS web interface with the following advanced features:

  • Multiple domain management
  • Domain template
  • User management
  • User access management based on domain
  • User activity logging
  • Local DB / LDAP / Active Directory user authentication
  • Support SAML authentication
  • Google OAuth authentication
  • Github OAuth authentication
  • Support Two-factor authentication (TOTP)
  • Dashboard and pdns service statistics
  • DynDNS 2 protocol support
  • Edit IPv6 PTRs using IPv6 addresses directly (no more editing of literal addresses!)

Install Python 3 development package

sudo apt-get install python3-dev

Install required packages for building python libraries from requirements.txt file

sudo apt-get install -y libmysqlclient-dev python-mysqldb libsasl2-dev libffi-dev \
libldap2-dev libssl-dev libxml2-dev libxslt1-dev libxmlsec1-dev pkg-config

Install yarn to build asset files:

sudo curl -sS | apt-key add -
sudo echo "deb stable main" > /etc/apt/sources.list.d/yarn.list
sudo apt-get update 
sudo apt-get install  yarn

Checkout source code and create virtualenv:

git clone /opt/web/powerdns-admin
cd /opt/web/powerdns-admin
virtualenv -p python3 flask


Already using interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /opt/web/powerdns-admin/flask/bin/python3
Also creating executable in /opt/web/powerdns-admin/flask/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.

Activate your python3 environment and install libraries:

. ./flask/bin/activate
pip install -r requirements.txt

Create and configure Database:

$ mysql -u root -p
CREATE DATABASE powerdnsadmin;
GRANT ALL PRIVILEGES ON powerdnsadmin.* TO 'pdnsadminuser'@'%' \
IDENTIFIED BY 'strongpassword';

Before running PowerDNS-Admin, make sure you have available. Let’s create one from the template:


Edit the file to


These are the required config:

  • DB connection information
  • PNDS API service endpoint and API key
  • Port Number used
  • Bind Address

Comment out SQLite SQLALCHEMY_DATABASE_URI line and uncomment MySQL one:

#You'll need MySQL-python
SQLA_DB_USER = 'powerdns'
SQLA_DB_PASSWORD = 'strongpassword'
SQLA_DB_HOST = 'localhost'
SQLA_DB_NAME = 'powerdns'

#SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'pdns.db')

See below screenshot:

Once you your is ready. Create the database schema by running commands:

(flask) $ export FLASK_APP=app/
(flask)$ flask db upgrade
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 787bdba9e147, Init DB

Then run db migrate:

(flask)$ flask db migrate -m "Init DB"
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [] Detected removed index 'domainidindex' on 'cryptokeys'
INFO [] Detected removed table 'cryptokeys'
INFO [] Detected removed index 'namealgoindex' on 'tsigkeys'
INFO [] Detected removed table 'tsigkeys'
INFO [] Detected removed table 'supermasters'
INFO [] Detected removed index 'nametype_index' on 'records'
INFO [] Detected removed table 'records'
INFO [] Detected removed index 'domainmetadata_idx' on 'domainmetadata'
INFO [] Detected removed table 'domainmetadata'
INFO [] Detected removed index 'name_index' on 'domains'
INFO [] Detected removed table 'domains'
INFO [] Detected removed index 'comments_name_type_idx' on 'comments'
INFO [] Detected removed index 'comments_order_idx' on 'comments'
INFO [] Detected removed table 'comments'
Generating /opt/web/powerdns-
admin/migrations/versions/ ... done

Generate asset files with yarn:

(flask)$ yarn install --pure-lockfile
yarn install v1.9.4
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
Done in 14.59s.

(flask)$ flask assets build
Building bundle: generated/login.js
[INFO] Building bundle: generated/login.js
Building bundle: generated/login.css
[INFO] Building bundle: generated/login.css
Building bundle: generated/main.js
[INFO] Building bundle: generated/main.js
Building bundle: generated/main.css
[INFO] Building bundle: generated/main.css

Test that your PowerDNS-Admin runs fine:

(flask)$ ./
[INFO] * Running on (Press CTRL+C to quit)
[INFO] * Restarting with stat
[WARNING] * Debugger is active!
[INFO] * Debugger PIN: 466-405-858

Configure systemd service and Nginx

We’re going to be managing PowerDNS-Admin with systemd. Create a service unit file like below:

$ sudo vim /etc/systemd/system/powerdns-admin.service

ExecStart=/opt/web/powerdns-admin/flask/bin/gunicorn --workers 2 --bind unix:/opt/web/powerdns-admin/powerdns-admin.sock app:app


Start Powerdns-Admin service and set it to start on boot:

sudo systemctl daemon-reload
sudo systemctl start powerdns-admin
sudo systemctl enable powerdns-admin

Confirm that status is running state:

[pastacode lang=”bash” manual=”%23%20systemctl%20status%20powerdns-admin%0A%E2%97%8F%20powerdns-admin.service%20-%20PowerDNS-Admin%0A%20%20%20Loaded%3A%20loaded%20(%2Fetc%2Fsystemd%2Fsystem%2Fpowerdns-admin.service%3B%20enabled%3B%20vendor%20preset%3A%20enabled)%0A%20%20%20Active%3A%20active%20(running)%20since%20Fri%202018-08-10%2016%3A45%3A16%20UTC%3B%2022s%20ago%0A%20Main%20PID%3A%2010405%20(gunicorn)%0A%20%20%20%20Tasks%3A%203%20(limit%3A%201152)%0A%20%20%20CGroup%3A%20%2Fsystem.slice%2Fpowerdns-admin.service%0A%20%20%20%20%20%20%20%20%20%20%20%E2%94%9C%E2%94%8010405%20%2Fopt%2Fweb%2Fpowerdns-admin%2Fflask%2Fbin%2Fpython3%20%2Fopt%2Fweb%2Fpowerdns-admin%2Fflask%2Fbin%2Fgunicorn%20–workers%202%20–bind%20unix%3A%2Fopt%2Fweb%2Fpowerdns-admi%0A%20%20%20%20%20%20%20%20%20%20%20%E2%94%9C%E2%94%8010427%20%2Fopt%2Fweb%2Fpowerdns-admin%2Fflask%2Fbin%2Fpython3%20%2Fopt%2Fweb%2Fpowerdns-admin%2Fflask%2Fbin%2Fgunicorn%20–workers%202%20–bind%20unix%3A%2Fopt%2Fweb%2Fpowerdns-admi%0A%20%20%20%20%20%20%20%20%20%20%20%E2%94%94%E2%94%8010428%20%2Fopt%2Fweb%2Fpowerdns-admin%2Fflask%2Fbin%2Fpython3%20%2Fopt%2Fweb%2Fpowerdns-admin%2Fflask%2Fbin%2Fgunicorn%20–workers%202%20–bind%20unix%3A%2Fopt%2Fweb%2Fpowerdns-admi%0A%0AAug%2010%2016%3A45%3A16%20ubuntu-01%20systemd%5B1%5D%3A%20Started%20PowerDNS-Admin.%0AAug%2010%2016%3A45%3A17%20ubuntu-01%20gunicorn%5B10405%5D%3A%20%5B2018-08-10%2016%3A45%3A17%20%2B0000%5D%20%5B10405%5D%20%5BINFO%5D%20Starting%20gunicorn%2019.7.1%0AAug%2010%2016%3A45%3A17%20ubuntu-01%20gunicorn%5B10405%5D%3A%20%5B2018-08-10%2016%3A45%3A17%20%2B0000%5D%20%5B10405%5D%20%5BINFO%5D%20Listening%20at%3A%20unix%3A%2Fopt%2Fweb%2Fpowerdns-admin%2Fpowerdns-admin.sock%20(%0AAug%2010%2016%3A45%3A17%20ubuntu-01%20gunicorn%5B10405%5D%3A%20%5B2018-08-10%2016%3A45%3A17%20%2B0000%5D%20%5B10405%5D%20%5BINFO%5D%20Using%20worker%3A%20sync%0AAug%2010%2016%3A45%3A17%20ubuntu-01%20gunicorn%5B10405%5D%3A%20%5B2018-08-10%2016%3A45%3A17%20%2B0000%5D%20%5B10427%5D%20%5BINFO%5D%20Booting%20worker%20with%20pid%3A%2010427%0AAug%2010%2016%3A45%3A17%20ubuntu-01%20gunicorn%5B10405%5D%3A%20%5B2018-08-10%2016%3A45%3A17%20%2B0000%5D%20%5B10428%5D%20%5BINFO%5D%20Booting%20worker%20with%20pid%3A%2010428%0A” message=”” highlight=”” provider=”manual”/]

Install and Configure Nginx for Powerdns-Admin

Install Nginx using:

sudo apt-get install nginx

Configure Nginx

sudo vim /etc/nginx/conf.d/powerdns-admin.conf

Add content like below:

[pastacode lang=”bash” manual=”server%20%7B%0A%20%20listen%20**%20%20%5C.(jpg%7Cjpeg%7Cpng%7Cgif)%24%20%7B%0A%20%20%20%20%20%20expires%20365d%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20location%20~*%20%5E.%2B.(css%7Cjs)%24%20%7B%0A%20%20%20%20%20%20expires%207d%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A%0A%20%20location%20%2F%20%7B%0A%20%20%20%20proxy_pass%20%20%20%20%20%20%20%20%20%20%20%20http%3A%2F%2Funix%3A%2Fopt%2Fweb%2Fpowerdns-admin%2Fpowerdns-admin.sock%3B%0A%20%20%20%20proxy_read_timeout%20%20%20%20120%3B%0A%20%20%20%20proxy_connect_timeout%20120%3B%0A%20%20%20%20proxy_redirect%20%20%20%20%20%20%20%20off%3B%0A%20%20%7D%0A%7D%0A” message=”” highlight=”” provider=”manual”/]

Check nginx syntax then restart nginx service:

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# systemctl restart nginx

Visit PowerDNS-Admin web interface.

Click “Create an account” button and Register a user. The first user will be in the Administrator role.

When you log in with created username and password, you should get an interface like below:

Enjoy Administering PowerDNS with PowerDNS-Admin on Ubuntu 18.04 / Debian 9 server.

Similar articles:

How to Install and Configure Dnsmasq on Ubuntu 18.04 LTS

How to Setup ISPConfig DNS Only on CentOS 7

You can support us by downloading this article as PDF from the Link below. Download the guide as PDF