PowerDNS

Installation

Debian

For the autoriative server install this package
# apt install pdns-server
This is the PowerDNS resolver package
# apt install pdns-recursor

PowerDNS offers different backends, which are packaged separately on Debian.

Mysql Backend

sudo apt install pdns-backend-mysql mariadb-server

PostgreSQL Backend

sudo apt install pdns-backend-pgsql postgresql

Authoritative Server

List of all available backends

PostgreSQL Backend

Edit the configuration file in /etc/powerdns/pdns.conf

...
launch=gpgsql
...
gpgsql-host=127.0.0.1
gpgsql-port=5432
gpgsql-dbname=pdns
gpgsql-user=<user>
gpgsql-password=<password>
gpgsql-dnssec=yes

Prepare database

sudo -u postgres psql
CREATE DATABASE pdns;
CREATE USER <user> WITH ENCRYPTED PASSWORD '<password>';
GRANT ALL PRIVILEGES ON DATABASE pdns TO powerdns;

Import the schema utilised by PowerDNS. This can be done with the user you just created
Do note the -h parameter is required unless pg_hba.conf has been modified to password based authentication locally as well.

psql -U <user> -d <database> -h 127.0.0.1 -f /usr/share/pdns-backend-pgsql/schema/schema.pgsql.sql
systemctl restart pdns

MySQL Backend

Set the backend you chose in the launch= option of PowerDNS' configuration file.
The config can be found under /etc/powerdns/pdns.conf

For MySQL I chose launch=gmysql

A list of backends can be found here

Add the following parameters below launch=gmysql

gmysql-host=127.0.0.1
gmysql-socket=/run/mysqld/mysqld.sock
gmysql-user=(user)
gmysql-password=(password)
gmysql-dbname=pdns
# Add this for dnssec support
gmysql-dnssec=yes

Prepare database

mariadb -u root -p
CREATE DATABASE pdns;
GRANT ALL ON pdns.* TO 'pdns'@'localhost' IDENTIFIED BY '<password>';

Import the schema utilised by PowerDNS. This can be done with the user you just created

mysql -u pdns -p pdns < /usr/share/doc/pdns-backend-mysql/schema.mysql.sql
systemctl restart pdns

PowerDNS CLI

Create Zone and add a name server
# pdnsutil create-zone (domain) ns1.(domain)

Add "A"-Record. Mind the (.) after the domain
"Name" is the hostname you wish to assign.
# pdnsutil add-record (domain). (name) A (ip address)

Dynamic DNS

# apt install bind9utils

Generate key
# dnssec-keygen -a hmac-md5 -b 128 -n USER (keyname)

Edit the configuration file and change dnsupdate=no to dnsupdate=yes and set allow-dnsupdate-from= to empty.

Allow updates from your DHCP server
# pdnsutil set-meta (domain) ALLOW-DNSUPDATE-FROM (dhcp server ip)
If you set up a reverse-zone, also allow that
# pdnsutil set-meta (reverse ip).in-addr.arpa ALLOW-DNSUPDATE-FROM (dhcp server ip)

Import the key
# pdnsutil import-tsig-key (keyname) hmac-md5 (key)
Enable for domain
# pdnsutil set-meta (domain) TSIG-ALLOW-DNSUPDATE (keyname)
And for reverse-zone
# pdnsutil set-meta (reverse ip).in-addr.arpa TSIG-ALLOW-DNSUPDATE (keyname)

You also have to configure the DHCP server to provide updates, see the DHCP article

Testing with nsupdate

# nsupdate -k Kdhcpdupdate.+157+12673.key

> server 127.0.0.1 5300
> zone testpdns
> update add test.testpdns 3600 A 192.168.7.10
> send

Configuration Recursive Resolver

The config file can be found under /etc/powerdns/recursor.conf
In /etc/powerdns/pdns.conf set local-address=127.0.0.1 and local-port=5300 to allow the recursor to run on port 53
In /etc/powerdns/recursor.conf set forward-zones=(domain)=127.0.0.1:5300 to forward queries for that domain to the authoritative DNS
Also set local-address and allow-from
To bind to all interfaces, use local-address=::,0.0.0.0

Wipe Cache

# rec_control wipe-cache $

DNSSEC

Authoritative Server

https://doc.powerdns.com/authoritative/dnssec/index.html

Recursor Server

To fully enable DNSSEC, set dnssec=process-no-validate to dnssec=validate

To allow a domain without DNSSEC, modify /etc/powerdns/recursor.lua
Add addNTA('(domain)') to disable DNSSEC for the selected domain.

Show domains with disabled DNSSEC
# rec_control get-ntas

DNSSEC Testing

WebGUI

PowerDNS-Admin

sudo mkdir /etc/powerdns-admin
sudo podman run -d \
    --name powerdns-admin \
    -e SECRET_KEY='<key>' \
    -v /etc/powerdns-admin:/data \
    -p 9191:80 \
    docker.io/powerdnsadmin/pda-legacy:latest

Enabling API

A few settings in /etc/powerdns/pdns.conf need to be changed.

api=yes
api-key=<key>
webserver=yes

Following this, the API access can be configured in the webgui
Configuration options in PowerDNS Admin

Now you should see all your configured Domains and be able to modify records