This tutorial is about how to easily install and setup PowerDNS on Debian 11/Debian 10. 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.
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.
Table of Contents
Installing PowerDNS on Debian
Run System Update
To begin with, update your system package cache.
apt update
Install PowerDNS Relational Database
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.
In this tutorial, will use one of the relational databases, specifically, MariaDB.
Hence, to install the latest and stable release version of MariaDB, execute the commands below
apt install software-properties-common gnupg2 -y
wget -qO- https://mariadb.org/mariadb_release_signing_key.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/mariadb_release_signing_key.gpg
Next, head over to MariaDB repositories site and choose your installation mirrors. In this setup, we use the ukfast.co.uk mirrors.
echo "deb [arch=amd64,arm64,ppc64el] http://mirrors.ukfast.co.uk/sites/mariadb/repo/10.6/debian $(lsb_release -sc) main" > /etc/apt/sources.list.d/mariadb.list
Update the system package cache and install MariaDB 10.6 on Debian 11/Debian 10;
apt update
apt install mariadb-server -y
Once the installation is done, run the initial MySQL security script to remove anonymous users and test databases, disallow remote root login.
mysql_secure_installation
Setup PowerDNS on Debian 11/Debian 10
Disable systemd-resolved
service
systemd-resolved
service provides network name resolution to local applications. We want to use PowerDNS instead
systemctl disable --now systemd-resolved
Update resolv.conf
file with custom DNS server details to enable you do the installation.
echo "nameserver 8.8.8.8" > /etc/resolv.conf
Next, install PowerDNS on Debian 11/Debian 10. PowerDNS is provided by the pdns-server
package.
To ensure that you install the latest release, you need to install PowerDNS repositories.
PowerDNS 4.5 is the current stable release as of this writing. Hence the repos below;
echo "deb [arch=amd64] http://repo.powerdns.com/debian $(lsb_release -sc)-auth-45 main" > /etc/apt/sources.list.d/pdns.list
cat > /etc/apt/preferences.d/pdns << EOL
Package: pdns-*
Pin: origin repo.powerdns.com
Pin-Priority: 600
EOL
wget -qO- https://repo.powerdns.com/FD380FBB-pub.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/pdns.gpg
apt update
apt install pdns-server
You also need to install PowerDNS MySQL backend;
apt install pdns-backend-mysql
Create PowerDNS Database on Debian 11/Debian 10
Now that PowerDNS and its MySQL backend packages are installed, login to MariaDB and create a database for PowerDNS nameserver.
mysql -u root
Be sure to use your preferred database names and database usernames. Names used here are not standard.
create database kifarunixdemopdns;
Create a PowerDNS database user and grant all privileges on the PowerDNS database. Replace the password accordingly.
grant all on kifarunixdemopdns.* to pdnsadmin@localhost identified by 'PdnSPassW0rd';
Reload the privileges tables and exit the database;
flush privileges;
quit
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;
mysql -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;
mysqlshow kifarunixdemopdns
Database: kifarunixdemopdns
+----------------+
| Tables |
+----------------+
| comments |
| cryptokeys |
| domainmetadata |
| domains |
| records |
| supermasters |
| tsigkeys |
+----------------+
Configure PowerDNS Database Connection Details
Create a configuration file to define the PowerDNS database connection details. Replace the specifics accordingly.
cat > /etc/powerdns/pdns.d/pdns.local.gmysql.conf << 'EOL'
# 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=
EOL
Adjust the permissions of the database connection details.
chown pdns: /etc/powerdns/pdns.d/pdns.local.gmysql.conf
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
Nov 25 20:50:49 Loading '/usr/lib/x86_64-linux-gnu/pdns/libbindbackend.so'
Nov 25 20:50:49 [bind2backend] This is the bind backend version 4.5.2 (Nov 9 2021 22:40:46) (with bind-dnssec-db support) reporting
Nov 25 20:50:49 Loading '/usr/lib/x86_64-linux-gnu/pdns/libgmysqlbackend.so'
Nov 25 20:50:50 [gmysqlbackend] This is the gmysql backend version 4.5.2 (Nov 9 2021 22:40:46) reporting
Nov 25 20:50:50 This is a standalone pdns
Nov 25 20:50:50 Created local state directory '/var/run/pdns/'
Nov 25 20:50:50 Listening on controlsocket in '/var/run/pdns/pdns.controlsocket'
Nov 25 20:50:50 [bindbackend] Parsing 0 domain(s), will report when done
Nov 25 20:50:50 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
Nov 25 20:50:50 gmysql Connection successful. Connected to database 'kifarunixdemopdns' on '127.0.0.1'.
Nov 25 20:50:50 UDP server bound to 0.0.0.0:53
Nov 25 20:50:50 UDP server bound to [::]:53
Nov 25 20:50:50 TCP server bound to 0.0.0.0:53
Nov 25 20:50:50 TCP server bound to [::]:53
Nov 25 20:50:50 PowerDNS Authoritative Server 4.5.2 (C) 2001-2021 PowerDNS.COM BV
Nov 25 20:50:50 Using 64-bits mode. Built using gcc 10.2.1 20210110 on Nov 9 2021 22:40:46 by root@80a4278afe39.
Nov 25 20:50:50 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.
Nov 25 20:50:50 [stub-resolver] Doing stub resolving for 'auth-4.5.2.security-status.secpoll.powerdns.com.|TXT', using resolvers: 8.8.8.8
Nov 25 20:50:50 [stub-resolver] Question for 'auth-4.5.2.security-status.secpoll.powerdns.com.|TXT' got answered by 8.8.8.8
Nov 25 20:50:50 Polled security status of version 4.5.2 at startup, no known issues reported: OK
Nov 25 20:50:50 Creating backend connection for TCP
Nov 25 20:50:50 gmysql Connection successful. Connected to database 'kifarunixdemopdns' on '127.0.0.1'.
Nov 25 20:50:50 About to create 3 backend threads for UDP
Nov 25 20:50:50 gmysql Connection successful. Connected to database 'kifarunixdemopdns' on '127.0.0.1'.
Nov 25 20:50:50 gmysql Connection successful. Connected to database 'kifarunixdemopdns' on '127.0.0.1'.
Nov 25 20:50:50 gmysql Connection successful. Connected to database 'kifarunixdemopdns' on '127.0.0.1'.
Nov 25 20:50:50 Done launching threads, ready to distribute questions
If you encounter any error, please fix it before you can proceed.
Restart PowerDNS
Press Ctrl+C to stop PDNS running in the background.
Restart PowerDNS to apply the changes made.
systemctl restart pdns
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=9986,fd=5))
tcp LISTEN 0 128 0.0.0.0:53 0.0.0.0:* users:(("pdns_server",pid=9986,fd=7))
Creating PowerDNS Forward Zone Records
As much as you can create zones by manipulating the database directly, it is recommended to use pdnsutil
tool instead.
Hence, to start with create Forward Zone;
pdnsutil create-zone kifarunix-demo.com
There are various PowerDNS operation modes. Native operation mode is the default mode for PowerDNS. You can list by running;
pdnsutil list-all-zones native
Inserting Forward Zone DNS Records into PowerDNS Database
Use the command below to add records;
pdnsutil add-record ZONE NAME TYPE [ttl] content
When you create a zone, SOA (Start Of Authority) record is inserted automatically.
You can show the details by running the command;
pdnsutil list-zone kifarunix-demo.com
Sample Output;
Nov 25 22:59:40 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
$ORIGIN .
kifarunix-demo.com 3600 IN SOA a.misconfigured.dns.server.invalid hostmaster.kifarunix-demo.com 0 10800 3600 604800 3600
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)
Update the SOA to accordingly.
export EDITOR=vim
pdnsutil edit-zone kifarunix-demo.com
We will only update the default-soa-content name and hostmaster such that it may look like;
; Warning - every name in this file is ABSOLUTE!
$ORIGIN .
kifarunix-demo.com 3600 IN SOA ns1.kifarunix-demo.com admin.kifarunix-demo.com 0 10800 3600 604800 3600
Save and exit the file and apply the changes.
[Error] No NS record at zone apex in zone 'kifarunix-demo.com'
Checked 1 records of 'kifarunix-demo.com', 1 errors, 0 warnings.
There was a problem with your zone
Options are: (e)dit your changes, (r)etry with original zone, (a)pply change anyhow, (q)uit:
a
Detected the following changes:
-kifarunix-demo.com 3600 IN SOA a.misconfigured.dns.server.invalid hostmaster.kifarunix-demo.com 0 10800 3600 604800 3600
+kifarunix-demo.com 3600 IN SOA ns1.kifarunix-demo.com admin.kifarunix-demo.com 0 10800 3600 604800 3600
(a)pply these changes, (e)dit again, (r)etry with original zone, (q)uit: a
Adding empty non-terminals for non-DNSSEC zone 'kifarunix-demo.com', 1 updates
Create Nameserver NS records
pdnsutil add-record kifarunix-demo.com @ NS 86400 ns1.kifarunix-demo.com
Insert A Records for the Nameserver.
Replace the IPs accordingly.
pdnsutil add-record kifarunix-demo.com ns1 A 120 192.168.58.22
Insert other systems A records;
pdnsutil add-record kifarunix-demo.com news A 120 192.168.59.12
pdnsutil add-record kifarunix-demo.com mail A 120 192.168.57.25
Insert MX records
pdnsutil add-record kifarunix-demo.com @ MX 120 "10 mail.kifarunix-demo.com"
So far so good, that is enough for our demo and this is how our records look like;
pdnsutil list-zone kifarunix-demo.com
Nov 25 16:08:18 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
$ORIGIN .
kifarunix-demo.com 120 IN MX 10 mail.kifarunix-demo.com.
kifarunix-demo.com 86400 IN NS ns1.kifarunix-demo.com.
kifarunix-demo.com 3600 IN SOA ns1.kifarunix-demo.com admin.kifarunix-demo.com 0 10800 3600 604800 3600
news.kifarunix-demo.com 120 IN A 192.168.59.12
ns1.kifarunix-demo.com 120 IN A 192.168.58.22
Verify PowerDNS Forward Resolution
Once the records are populated into the DB, very the PowerDNS resolution;
apt install dnsutils -y
dig ns1.kifarunix-demo.com @127.0.0.1
; <<>> DiG 9.11.5-P4-5.1+deb10u6-Debian <<>> ns1.kifarunix-demo.com @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63327
;; 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.58.22
;; Query time: 2 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Nov 25 16:09:03 EST 2021
;; MSG SIZE rcvd: 67
dig MX kifarunix-demo.com @127.0.0.1
; <<>> DiG 9.11.5-P4-5.1+deb10u6-Debian <<>> MX kifarunix-demo.com @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5092
;; 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:
;kifarunix-demo.com. IN MX
;; ANSWER SECTION:
kifarunix-demo.com. 120 IN MX 10 mail.kifarunix-demo.com.
;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Nov 25 16:09:27 EST 2021
;; MSG SIZE rcvd: 68
Creating PowerDNS Reverse Zone Records
Create reverse zone;
pdnsutil create-zone 58.168.192.in-addr.arpa
Update reverse zone SOA;
pdnsutil list-zone 58.168.192.in-addr.arpa
Note, if you have multiple networks like 192.168.58.x/x, 192.168.59.x/x, 192.168.57.x/x, then you can just create a reverse zone like;
pdnsutil create-zone 168.192.in-addr.arpa
Update the name and hostmaster such that they may look like a shown below.
pdnsutil edit-zone 168.192.in-addr.arpa
Nov 26 13:46:09 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
$ORIGIN .
168.192.in-addr.arpa 3600 IN SOA ns1.kifarunix-demo.com admin.kifarunix.demo.com 0 10800 3600 604800 3600
Insert NS Reverse Zone Record
pdnsutil add-record 168.192.in-addr.arpa @ NS 86400 ns1.kifarunix-demo.com
Insert PTR Records for NS
pdnsutil add-record 168.192.in-addr.arpa 22.58 PTR 120 ns1.kifarunix-demo.com
Insert Other Domains PTR Records
pdnsutil add-record 168.192.in-addr.arpa 12.59 PTR 120 news.kifarunix-demo.com
pdnsutil add-record 168.192.in-addr.arpa 25.57 PTR 120 mail.kifarunix-demo.com
Now the general reverse records look like;
pdnsutil list-zone 168.192.in-addr.arpa
Nov 26 13:56:58 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
$ORIGIN .
12.59.168.192.in-addr.arpa 120 IN PTR news.kifarunix-demo.com
168.192.in-addr.arpa 86400 IN NS ns1.kifarunix-demo.com.
168.192.in-addr.arpa 3600 IN SOA ns1.kifarunix-demo.com admin.kifarunix.demo.com 0 10800 3600 604800 3600
22.58.168.192.in-addr.arpa 120 IN PTR ns1.kifarunix-demo.com
25.57.168.192.in-addr.arpa 120 IN PTR mail.kifarunix-demo.com
Verify PowerDNS Reverse Resolution
Exit the database and run the reverse DNS queries to confirm if all is well.
dig -x 192.168.58.22 @127.0.0.1
; <<>> DiG 9.11.5-P4-5.1+deb10u6-Debian <<>> -x 192.168.58.22 @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15391
;; 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:
;22.58.168.192.in-addr.arpa. IN PTR
;; ANSWER SECTION:
22.58.168.192.in-addr.arpa. 120 IN PTR ns1.kifarunix-demo.com.
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri Nov 26 13:58:15 EST 2021
;; MSG SIZE rcvd: 91
dig -x 192.168.57.25 @127.0.0.1
; <<>> DiG 9.11.5-P4-5.1+deb10u6-Debian <<>> -x 192.168.57.25 @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10942
;; 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:
;25.57.168.192.in-addr.arpa. IN PTR
;; ANSWER SECTION:
25.57.168.192.in-addr.arpa. 120 IN PTR mail.kifarunix-demo.com.
;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri Nov 26 14:00:30 EST 2021
;; MSG SIZE rcvd: 92
Magnificent!!!
Note that all this can be easily done from the web but, that is tutorial for another day.
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.58.22" > /etc/resolv.conf
Verify Client Forward DNS Resolution
Next, perform DNS resolution using any DNS utilities.
dig news.kifarunix-demo.com
; <<>> DiG 9.16.22-Debian <<>> news.kifarunix-demo.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27385
;; 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.59.12
;; Query time: 4 msec
;; SERVER: 192.168.58.22#53(192.168.58.22)
;; WHEN: Fri Nov 26 00:39:56 EAT 2021
;; MSG SIZE rcvd: 68
Verify Client Reverse DNS Resolution
dig -x 192.168.58.22 +short
ns1.kifarunix-demo.com.
nslookup 192.168.58.22
22.58.168.192.in-addr.arpa name = ns1.kifarunix-demo.com.
host 192.168.58.22
22.58.168.192.in-addr.arpa domain name pointer ns1.kifarunix-demo.com.
For now, that is how simple it is to install and confugure PowerDNS on Debian.
Learn how to manage PowerDNS using a web tool called PowerDNS Admin by following the link below;
Easily Install PowerDNS Admin on Debian 11/Debian 10
Other Tutorials
Configure OpenVPN Clients to use specific DNS Server