Easily Install and Setup PowerDNS on Ubuntu 20.04

|
Last Updated:
|
|
Install and Setup PowerDNS on Ubuntu

Welcome to our tutorial on how to easily install and setup PowerDNS on Ubuntu 20.04. PowerDNS “is a premier supplier of open source DNS software, services and support“. It provides both the Authoritative Server and the Recursor DNS products. According to PowerDNS documentation page;

  • The Authoritative Server will answer questions about domains it knows about, but will not go out on the net to resolve queries about other domains. When the Authoritative Server answers a question, it comes out of the database, and can be trusted as being authoritative. There is no way to pollute the cache or to confuse the daemon.
  • The Recursor, conversely, by default has no knowledge of domains itself, but will always consult other authoritative servers to answer questions given to it.

Installing PowerDNS on Ubuntu 20.04

What Features Does PowerDNS Provide?

PowerDNS;

  • offers very high domain resolution performance.
  • supports a large number of different backends ranging from simple zonefiles to relational databases and load balancing/failover algorithms.
  • offers better security features.
  • its source code is reasonably small which makes auditing easy.
  • it give a lot of statistics on its operation which is both helpful in determining the scalability of an installation as well as for spotting problems.

Run System Update

To begin with, update your system package and upgrade to your system packages as well.

apt update
apt upgrade

If system reboot is required, then reboot;

[[ -f /var/run/reboot-required ]] && systemctl reboot -i

Install PowerDNS Relational Database (MariaDB)

As stated above, the authoritative PowerDNS server supports different backends ranging from database backends such as MySQL, PostgreSQL, Oracle and BIND zone files to co-processes and JSON API’s.

Since we are going to easily install PowerDNS as our local authoritative nameserver, we will use one of the relational databases, and in this setup, we go with MariaDB.

To install the latest and stable release version of MariaDB, you need to install MariaDB repos.

apt install software-properties-common gnupg2
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash
apt update
apt install mariadb-server

Once the installation is done, check if the MariaDB service is running (it should be running upon installation);

systemctl status mariadb

● mariadb.service - MariaDB 11.0.2 database server
     Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/mariadb.service.d
             └─migrated-from-my.cnf-settings.conf
     Active: active (running) since Tue 2023-07-25 19:47:24 UTC; 46s ago
       Docs: man:mariadbd(8)
             https://mariadb.com/kb/en/library/systemd/
   Main PID: 29789 (mariadbd)
     Status: "Taking your SQL requests now..."
      Tasks: 13 (limit: 2257)
     Memory: 79.4M
     CGroup: /system.slice/mariadb.service
             └─29789 /usr/sbin/mariadbd

Jul 25 19:47:24 focal mariadbd[29789]: 2023-07-25 19:47:24 0 [Note] Plugin 'wsrep-provider' is disabled.
Jul 25 19:47:24 focal mariadbd[29789]: 2023-07-25 19:47:24 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
Jul 25 19:47:24 focal mariadbd[29789]: 2023-07-25 19:47:24 0 [Note] Server socket created on IP: '127.0.0.1'.
Jul 25 19:47:24 focal mariadbd[29789]: 2023-07-25 19:47:24 0 [Note] InnoDB: Buffer pool(s) load completed at 230725 19:47:24
Jul 25 19:47:24 focal mariadbd[29789]: 2023-07-25 19:47:24 0 [Note] /usr/sbin/mariadbd: ready for connections.
Jul 25 19:47:24 focal mariadbd[29789]: Version: '11.0.2-MariaDB-1:11.0.2+maria~ubu2004'  socket: '/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution
Jul 25 19:47:24 focal systemd[1]: Started MariaDB 11.0.2 database server.
Jul 25 19:47:24 focal /etc/mysql/debian-start[29805]: Upgrading MySQL tables if necessary.
Jul 25 19:47:24 focal /etc/mysql/debian-start[29816]: Checking for insecure root accounts.
Jul 25 19:47:24 focal /etc/mysql/debian-start[29820]: Triggering myisam-recover for all MyISAM tables and aria-recover for all Aria tables

Run the initial MySQL security script to remove anonymous users and test databases, disallow remote root login.

mysql_secure_installation

Setting up PowerDNS on Ubuntu 20.04

Disable systemd-resolved service

Before you can install PowerDNS on Ubuntu 20.04, you need to disable systemd-resolved service (system service that provides network name resolution to local applications).

systemctl disable --now systemd-resolved

Update resolv.conf file with your custom DNS server details to enable you do the installation.

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

Install PowerDNS on Ubuntu 20.04

Once that is done, install PowerDNS on Ubuntu 20.04. PowerDNS is provided by the pdns-server package.

apt install pdns-server

You also need to install PowerDNS nameserver MySQL backend;

apt install pdns-backend-mysql

Create PowerDNS Database on Ubuntu 20.04

Now that PowerDNS and its MySQL backend packages are installed, login to MariaDB and create a database for PowerDNS nameserver.

Be sure to use your preferred database names and database usernames. Names used here are not standard.

mariadb -u root -p -e "create database kifarunixdemopdns;"

Create a PowerDNS database user and grant all privileges on the PowerDNS database. Replace the password accordingly.

mariadb -u root -p -e "grant all on kifarunixdemopdns.* to pdnsadmin@localhost identified by 'PdnSPassW0rd';"

Reload the privileges tables;

mariadb -u root -p -e "flush privileges;"

Import PowerDNS Database Schema

The default PowerDNS database schema is available under /usr/share/pdns-backend-mysql/schema/ directory as schema.mysql.sql. You need to import this schema to the PowerDNS database created above;

mariadb -u pdnsadmin -p kifarunixdemopdns < /usr/share/pdns-backend-mysql/schema/schema.mysql.sql 

To verify the PowerDNS database schema import, try to list available tables;

mariadb-show kifarunixdemopdns

Database: kifarunixdemopdns
+----------------+
|     Tables     |
+----------------+
| comments       |
| cryptokeys     |
| domainmetadata |
| domains        |
| records        |
| supermasters   |
| tsigkeys       |
+----------------+

Configure PowerDNS Database Connection Details

Create a configuration file, as shown below, where to define the PowerDNS database connection details.

Be sure to update your database connection details accordingly.

vim /etc/powerdns/pdns.d/pdns.local.gmysql.conf

# MySQL Configuration
#
# Launch gmysql backend
launch+=gmysql

# gmysql parameters
gmysql-host=127.0.0.1
gmysql-port=3306
gmysql-dbname=kifarunixdemopdns
gmysql-user=pdnsadmin
gmysql-password=PdnSPassW0rd
gmysql-dnssec=yes
# gmysql-socket=

Save and exit the file.

Adjust the permissions of the database connection details.

chmod 640 /etc/powerdns/pdns.d/pdns.local.gmysql.conf

Verify PowerDNS database connection

If PowerDNS is already running, stop it and run it in the foreground to verify if it can connect to the database;

systemctl stop pdns.service
pdns_server --daemon=no --guardian=no --loglevel=9

Jul 25 20:03:11 Loading '/usr/lib/x86_64-linux-gnu/pdns/libbindbackend.so'
Jul 25 20:03:11 [bind2backend] This is the bind backend version 4.2.1 (with bind-dnssec-db support) reporting
Jul 25 20:03:11 Loading '/usr/lib/x86_64-linux-gnu/pdns/libgmysqlbackend.so'
Jul 25 20:03:11 [gmysqlbackend] This is the gmysql backend version 4.2.1 reporting
Jul 25 20:03:11 This is a standalone pdns
Jul 25 20:03:11 Listening on controlsocket in '/var/run/pdns.controlsocket'
Jul 25 20:03:11 UDP server bound to 0.0.0.0:53
Jul 25 20:03:11 UDPv6 server bound to [::]:53
Jul 25 20:03:11 TCP server bound to 0.0.0.0:53
Jul 25 20:03:11 TCPv6 server bound to [::]:53
Jul 25 20:03:11 PowerDNS Authoritative Server 4.2.1 (C) 2001-2019 PowerDNS.COM BV
Jul 25 20:03:11 Using 64-bits mode. Built using gcc 9.2.1 20200202.
Jul 25 20:03:11 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.
Jul 25 20:03:11 Set effective group id to 119
Jul 25 20:03:11 Set effective user id to 115
Jul 25 20:03:11 Creating backend connection for TCP
Jul 25 20:03:11 [bindbackend] Parsing 0 domain(s), will report when done
Jul 25 20:03:11 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
Jul 25 20:03:11 gmysql Connection successful. Connected to database 'kifarunixdemopdns' on '127.0.0.1'.
Jul 25 20:03:11 About to create 3 backend threads for UDP
Jul 25 20:03:11 gmysql Connection successful. Connected to database 'kifarunixdemopdns' on '127.0.0.1'.
Jul 25 20:03:11 gmysql Connection successful. Connected to database 'kifarunixdemopdns' on '127.0.0.1'.
Jul 25 20:03:12 gmysql Connection successful. Connected to database 'kifarunixdemopdns' on '127.0.0.1'.
Jul 25 20:03:12 Done launching threads, ready to distribute questions

If you encounter any error, please fix it before you can proceed.

Restart PowerDNS

Restart PowerDNS to apply the changes made.

systemctl restart pdns

Check the status;

systemctl status pdns

● pdns.service - PowerDNS Authoritative Server
     Loaded: loaded (/lib/systemd/system/pdns.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2023-07-25 20:03:58 UTC; 19s ago
       Docs: man:pdns_server(1)
             man:pdns_control(1)
             https://doc.powerdns.com
   Main PID: 31590 (pdns_server)
      Tasks: 8 (limit: 2257)
     Memory: 6.1M
     CGroup: /system.slice/pdns.service
             └─31590 /usr/sbin/pdns_server --guardian=no --daemon=no --disable-syslog --log-timestamp=no --write-pid=no

Jul 25 20:03:58 focal pdns_server[31590]: TCPv6 server bound to [::]:53
Jul 25 20:03:58 focal pdns_server[31590]: PowerDNS Authoritative Server 4.2.1 (C) 2001-2019 PowerDNS.COM BV
Jul 25 20:03:58 focal pdns_server[31590]: Using 64-bits mode. Built using gcc 9.2.1 20200202.
Jul 25 20:03:58 focal pdns_server[31590]: PowerDNS comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it according to the terms >
Jul 25 20:03:58 focal pdns_server[31590]: Creating backend connection for TCP
Jul 25 20:03:58 focal pdns_server[31590]: [bindbackend] Parsing 0 domain(s), will report when done
Jul 25 20:03:58 focal pdns_server[31590]: [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
Jul 25 20:03:58 focal systemd[1]: Started PowerDNS Authoritative Server.
Jul 25 20:03:58 focal pdns_server[31590]: About to create 3 backend threads for UDP
Jul 25 20:03:58 focal pdns_server[31590]: Done launching threads, ready to distribute questions

Verify the DNS port UDP/TCP port 53 are opened

ss -alnp4 | grep pdns

udp    UNCONN  0       0                     0.0.0.0:53           0.0.0.0:*      users:(("pdns_server",pid=31590,fd=5))                                         
tcp    LISTEN  0       128                   0.0.0.0:53           0.0.0.0:*      users:(("pdns_server",pid=31590,fd=7)) 

Creating PowerDNS Forward Zone Records

Define PowerDNS Operation Mode

The basic configuration of PowerDNS is now done. You can proceed to add your DNS records into the database.

Login into the PowerDNS database;

mariadb -u pdnsadmin -p -D kifarunixdemopdns

To begin with, define the PowerDNS operation mode. There are various DNS operation modes you can define while inserting records into PowerDNS database. In this basic tutorial, we will go with the default Native operation mode.

insert into domains (name, type) values ('kifarunix-demo.com', 'NATIVE');

Create the domain SOA (Start Of Authority) record.

The SOA stored format is:

primary hostmaster serial refresh retry expire default_ttl

Where:

  • primary: default-soa-name configuration option
  • hostmaster: hostmaster@domain-name
  • serial: 0
  • refresh: 10800 (3 hours)
  • retry: 3600 (1 hour)
  • expire: 604800 (1 week)
  • default_ttl: 3600 (1 hour)
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'kifarunix-demo.com','localhost admin.kifarunix-demo.com 1 10380 3600 604800 3600','SOA',86400,NULL);

Create Nameserver NS records

Sample NS record;

INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'kifarunix-demo.com','ns1.kifarunix-demo.com','NS',86400,NULL);

Insert A Records for the Nameserver

Sample A records;

INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'ns1.kifarunix-demo.com','192.168.57.3','A',120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'news.kifarunix-demo.com','192.168.58.45','A',120,NULL);

Insert MX records

INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'kifarunix-demo.com','mail.kifarunix-demo.com','MX',120,25);

So far so good, that is enough for our demo and this is how our records look like;

select * from records;

+----+-----------+-------------------------+------+-------------------------------------------------------------+-------+------+----------+-----------+------+
| id | domain_id | name                    | type | content                                                     | ttl   | prio | disabled | ordername | auth |
+----+-----------+-------------------------+------+-------------------------------------------------------------+-------+------+----------+-----------+------+
|  1 |         1 | kifarunix-demo.com      | SOA  | localhost admin.kifarunix-demo.com 1 10380 3600 604800 3600 | 86400 | NULL |        0 | NULL      |    1 |
|  2 |         1 | kifarunix-demo.com      | NS   | ns1.kifarunix-demo.com                                      | 86400 | NULL |        0 | NULL      |    1 |
|  3 |         1 | ns1.kifarunix-demo.com  | A    | 192.168.57.3                                                |   120 | NULL |        0 | NULL      |    1 |
|  4 |         1 | news.kifarunix-demo.com | A    | 192.168.58.45                                               |   120 | NULL |        0 | NULL      |    1 |
|  5 |         1 | kifarunix-demo.com      | MX   | mail.kifarunix-demo.com                                     |   120 |   25 |        0 | NULL      |    1 |
+----+-----------+-------------------------+------+-------------------------------------------------------------+-------+------+----------+-----------+------+
5 rows in set (0.001 sec)

Exit the database;

\q

Verify PowerDNS Forward Resolution

Once the records are populated into the DB, very the PowerDNS resolution;

dig ns1.kifarunix-demo.com @127.0.0.1


; <<>> DiG 9.16.1-Ubuntu <<>> ns1.kifarunix-demo.com @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51535
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;ns1.kifarunix-demo.com.		IN	A

;; ANSWER SECTION:
ns1.kifarunix-demo.com.	120	IN	A	192.168.57.3

;; Query time: 4 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Jul 25 20:11:11 UTC 2023
;; MSG SIZE  rcvd: 67

dig MX kifarunix-demo.com @127.0.0.1 +short
25 mail.kifarunix-demo.com.

Creating PowerDNS Reverse Zone Records

Login into the PowerDNS database again;

mariadb -u pdnsadmin -p -D kifarunixdemopdns

Insert SOA Record for the Reverse Zone

Sample reverse SOA record;

INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (2,'57.168.192.in-addr.arpa','localhost admin.kifarunix-demo.com 1 10380 3600 604800 3600','SOA',86400,NULL);

Insert NS Reverse Zone Record

Sample NS record;

INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (2,'57.168.192.in-addr.arpa','ns1.kifarunix-demo.com','NS',120,NULL);

Insert PTR Records for NS

Sample PTR records;

INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (2,'3.57.168.192.in-addr.arpa','ns1.kifarunix-demo.com','PTR',120,NULL);

Insert Other Domains PTR Records

INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (2,'45.58.168.192.in-addr.arpa','news.kifarunix-demo.com','PTR',120,NULL);

Now the general database records look like;

select * from records;

+----+-----------+----------------------------+------+-------------------------------------------------------------+-------+------+----------+-----------+------+
| id | domain_id | name                       | type | content                                                     | ttl   | prio | disabled | ordername | auth |
+----+-----------+----------------------------+------+-------------------------------------------------------------+-------+------+----------+-----------+------+
|  1 |         1 | kifarunix-demo.com         | SOA  | localhost admin.kifarunix-demo.com 1 10380 3600 604800 3600 | 86400 | NULL |        0 | NULL      |    1 |
|  2 |         1 | kifarunix-demo.com         | NS   | ns1.kifarunix-demo.com                                      | 86400 | NULL |        0 | NULL      |    1 |
|  3 |         1 | ns1.kifarunix-demo.com     | A    | 192.168.57.3                                                |   120 | NULL |        0 | NULL      |    1 |
|  4 |         1 | news.kifarunix-demo.com    | A    | 192.168.58.45                                               |   120 | NULL |        0 | NULL      |    1 |
|  5 |         1 | kifarunix-demo.com         | MX   | mail.kifarunix-demo.com                                     |   120 |   25 |        0 | NULL      |    1 |
|  6 |         2 | 57.168.192.in-addr.arpa    | SOA  | localhost admin.kifarunix-demo.com 1 10380 3600 604800 3600 | 86400 | NULL |        0 | NULL      |    1 |
|  7 |         2 | 57.168.192.in-addr.arpa    | NS   | ns1.kifarunix-demo.com                                      |   120 | NULL |        0 | NULL      |    1 |
|  8 |         2 | 3.57.168.192.in-addr.arpa  | PTR  | ns1.kifarunix-demo.com                                      |   120 | NULL |        0 | NULL      |    1 |
| 12 |         2 | 45.58.168.192.in-addr.arpa | PTR  | news.kifarunix-demo.com                                     |   120 | NULL |        0 | NULL      |    1 |
+----+-----------+----------------------------+------+-------------------------------------------------------------+-------+------+----------+-----------+------+
9 rows in set (0.000 sec)

So what is domain_id, name, type, prio, ttl? Read about them on the PowerDNS Regular Queries page.

Exit the database connection;

\q

Verify PowerDNS Reverse Resolution

Exit the database and run the reverse DNS queries to confirm if all is well.

dig -x 192.168.58.45 @127.0.0.1 +short
news.kifarunix-demo.com.
dig -x 192.168.57.3 @127.0.0.1 +short
ns1.kifarunix-demo.com.

Magnificent!!!

Manage DNS Zones and Records from Web Interface

Note that all this can be easily be done from the web;

Easily Install and Setup PowerDNS Admin on Ubuntu 20.04

Open DNS Port on UFW

For the remote hosts to be able to use the PowerDNS for their name resolution, you need to open the DNS port 53/UDP;

ufw allow from 192.168.0.0/16 to any port 53 proto udp

This allows DNS queries from 192.168.0.0/16 subnet.

Configure DNS Server on Client Systems

For testing purposes, overwrite your /etc/resolv.conf file with PowerDNS nameserver entry.

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

Verify Client Forward DNS Resolution

Next, perform DNS resolution using any DNS utilities.

dig news.kifarunix-demo.com


; <<>> DiG 9.18.12-0ubuntu0.22.04.2-Ubuntu <<>> news.kifarunix-demo.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30215
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;news.kifarunix-demo.com.	IN	A

;; ANSWER SECTION:
news.kifarunix-demo.com. 120	IN	A	192.168.58.45

;; Query time: 4 msec
;; SERVER: 192.168.57.3#53(192.168.57.3) (UDP)
;; WHEN: Tue Jul 25 20:23:57 UTC 2023
;; MSG SIZE  rcvd: 68
nslookup ns1.kifarunix-demo.com

Server:		192.168.57.3
Address:	192.168.57.3#53

Name:	ns1.kifarunix-demo.com
Address: 192.168.57.3
host ns1.kifarunix-demo.com
ns1.kifarunix-demo.com has address 192.168.57.3

Verify Client Reverse DNS Resolution

dig -x 192.168.57.3 +short
ns1.kifarunix-demo.com.
nslookup 192.168.57.3
3.57.168.192.in-addr.arpa name = ns1.kifarunix-demo.com.
host 192.168.57.3
3.57.168.192.in-addr.arpa domain name pointer ns1.kifarunix-demo.com.

Beautiful. In our next guide, we will learn how to manage PowerDNS using a web tool called PowerDNS Admin (link is provided below).

Easily Install and Setup PowerDNS Admin on Ubuntu 20.04

Reference

PowerDNS Authoritative Nameserver Documentation

Configure Local DNS Server using Dnsmasq on Ubuntu 20.04

Setup Caching-Only DNS Server using BIND9 on Ubuntu 20.04

SUPPORT US VIA A VIRTUAL CUP OF COFFEE

We're passionate about sharing our knowledge and experiences with you through our blog. If you appreciate our efforts, consider buying us a virtual coffee. Your support keeps us motivated and enables us to continually improve, ensuring that we can provide you with the best content possible. Thank you for being a coffee-fueled champion of our work!

Photo of author
koromicha
I am the Co-founder of Kifarunix.com, Linux and the whole FOSS enthusiast, Linux System Admin and a Blue Teamer who loves to share technological tips and hacks with others as a way of sharing knowledge as: "In vain have you acquired knowledge if you have not imparted it to others".

5 thoughts on “Easily Install and Setup PowerDNS on Ubuntu 20.04”

  1. Super howto, thanks a lot!!

    i think there a little error in reversdns config,
    | 4 | 1 | news.kifarunix-demo.com | A | 192.168.58.45
    | 9 | 2 | 45.57.168.192.in-addr.arpa | PTR | news.kifarunix-demo.com
    If news server is in a different subnet, (192.168.58.45/24) should we create another reverse zone with SOA?

    Reply
  2. I installed PowerDNS on an AWS-EC2 Ubuntu 20.04 instance. Everything works fine up to the section :Configure DNS Server on Client Systems” until I changed the content of /etc/resolv.conf from 8.8.8.8 to 172.31.58.45 (since the ec2 IPv4 CIDR is 172.31.0.0/16) and ran “dig news.view-demo.com” The command just times out.
    When I set it back to 8.8.8.8, dig news.view-demo.com gives the expected output.

    Any ideas why?

    Reply

Leave a Comment