PowerDNS + PowerDNS-Admin + Recursor On Debian10/11

  1. Install the required tools

sudo apt update && sudo apt upgrade
sudo apt install curl vim git -y

2. Install PowerDNS Databases

sudo apt install software-properties-common gnupg2 -y
curl -LsS -O https://downloads.mariadb.com/MariaDB/mariadb_repo_setup
sudo bash mariadb_repo_setup
sudo apt update
sudo apt install mariadb-server mariadb-client
sudo systemctl start mariadb
sudo systemctl enable mariadb

Create a PowerDNS database

*Remember the password set for the user should not contain special characters*

mysql -u root
CREATE DATABASE powerdns;
GRANT ALL ON powerdns.* TO 'powerdns_user'@'%' IDENTIFIED BY 'Strongpassword';
FLUSH PRIVILEGES;
EXIT

3. Install PowerDNS on Debian 11 / Debian 10

sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
unlink /etc/resolv.conf

Update the resolv.conf file.

echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf

Install the latest release of PowerDNS

sudo vim /etc/apt/sources.list.d/pdns.list

For Debian 11

deb [arch=amd64] http://repo.powerdns.com/debian bullseye-auth-46 main

For Debian 10

deb [arch=amd64] http://repo.powerdns.com/debian buster-auth-46 main

Import the GPG key signing for the repository.

curl -fsSL https://repo.powerdns.com/FD380FBB-pub.asc | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/pdns.gpg

Set the APT preferences.

$ sudo vim /etc/apt/preferences.d/pdns
Package: pdns-*
Pin: origin repo.powerdns.com
Pin-Priority: 600

Update your APT package index.

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

4. Configure the PowerDNS Database

$ mysql -u powerdns_user -p powerdns < /usr/share/pdns-backend-mysql/schema/schema.mysql.sql

You can then verify import as below.

sudo mysql -u root
use powerdns;
show tables;

5. Configure the PowerDNS connection details to the database

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

launch+=gmysql
gmysql-host=127.0.0.1
gmysql-port=3306
gmysql-dbname=powerdns
gmysql-user=powerdns_user
gmysql-password=Strongpassword
gmysql-dnssec=yes

Set the appropriate permissions for the file.

sudo chown pdns: /etc/powerdns/pdns.d/pdns.local.gmysql.conf
sudo chmod 640 /etc/powerdns/pdns.d/pdns.local.gmysql.conf

verify the database connection.

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

output:

ctrl+c for exit

sudo systemctl restart pdns
sudo systemctl enable pdns

Verify the port 53 is open for DNS.

sudo ss -alnp4 | grep pdns

6. Install PowerDNS Admin on Debian 11 / Debian 10

Install the required build tools.

$ sudo apt install python3-dev -y

$ sudo apt install libsasl2-dev libldap2-dev libssl-dev libxml2-dev libxslt1-dev libxmlsec1-dev libffi-dev pkg-config apt-transport-https virtualenv python3-venv build-essential libmariadb-dev git python3-flask -y

$ curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
$ sudo apt install -y nodejs

$ curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null

$ echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list

$ sudo apt update
$ sudo apt install yarn -y

7. clone the PowerDNS admin

$ sudo su -
$ git clone https://github.com/ngoduykhanh/PowerDNS-Admin.git /var/www/html/pdns

8. Create a virtual environment

$ cd /var/www/html/pdns/
$ virtualenv -p python3 flask
$ source ./flask/bin/activate
$ pip install --upgrade pip
$ pip install -r requirements.txt
$ deactivate

9. configure the PowerDNS admin database

$ vim /var/www/html/pdns/powerdnsadmin/default_config.py

SQLA_DB_USER = 'powerdns_user'
SQLA_DB_PASSWORD = 'Strongpassword'
SQLA_DB_HOST = '127.0.0.1'
SQLA_DB_NAME = 'powerdns'
SQLALCHEMY_TRACK_MODIFICATIONS = True

create a database schema.

cd /var/www/html/pdns/
source ./flask/bin/activate
export FLASK_APP=powerdnsadmin/init.py
flask db upgrade

Sample output:

Generate the asset files using Yarn.

$ yarn install --pure-lockfile
$ flask assets build
$ deactivate

Enable PowerDNS API access

$ sudo vim /etc/powerdns/pdns.conf
api=yes
api-key= #You can generate one from https://codepen.io/corenominal/pen/rxOmMJ

$ sudo systemctl restart pdns

10. Create a System service file for PowerDNS Admin

$ vim /etc/systemd/system/pdnsadmin.service

[Unit]
Description=PowerDNS-Admin
Requires=pdnsadmin.socket
After=network.target

[Service]
PIDFile=/run/pdnsadmin/pid
User=pdns
Group=pdns
WorkingDirectory=/var/www/html/pdns
ExecStart=/var/www/html/pdns/flask/bin/gunicorn --pid /run/pdnsadmin/pid --bind unix:/run/pdnsadmin/socket 'powerdnsadmin:create_app()'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

vim /etc/systemd/system/pdnsadmin.socket

[Unit]
Description=PowerDNS-Admin socket

[Socket]
ListenStream=/run/pdnsadmin/socket

[Install]
WantedBy=sockets.target

mkdir /run/pdnsadmin/
echo "d /run/pdnsadmin 0755 pdns pdns -" >> /etc/tmpfiles.d/pdnsadmin.conf
chown -R pdns: /run/pdnsadmin/
chown -R pdns: /var/www/html/pdns/powerdnsadmin/

systemctl daemon-reload
systemctl enable --now pdnsadmin.service pdnsadmin.socket
systemctl status pdnsadmin.service pdnsadmin.socket

output:

11. Create a PowerDNS Virtual Host file.

sudo apt install nginx

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

server {
listen *:80;
server_name ip-or-domain;

index index.html index.htm index.php;
root /var/www/html/pdns;
access_log /var/log/nginx/pdnsadmin_access.log combined;
error_log /var/log/nginx/pdnsadmin_error.log;

client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_redirect off;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
proxy_buffer_size 8k;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_headers_hash_bucket_size 64;

location ~ ^/static/ {
include /etc/nginx/mime.types;
root /var/www/html/pdns/powerdnsadmin;

location ~*  \.(jpg|jpeg|png|gif)$ {
  expires 365d;
}

location ~* ^.+.(css|js)$ {
  expires 7d;
}

}

location / {
proxy_pass http://unix:/run/pdnsadmin/socket;
proxy_read_timeout 120;
proxy_connect_timeout 120;
proxy_redirect off;
}

}

$ mv /etc/nginx/sites-enabled/default{,.old}
$ nginx -t
chown -R www-data: /var/www/html/pdns
chown -R pdns:pdns /var/www/html/pdns/powerdnsadmin
systemctl restart nginx

Select Create an account

after create account login to powerdns

Fill ip-powerdns and apikey

API URL : http://127.0.0.1:8081

Disable create account

  1. setting > authentication > disable allow user to sign up

PowerDNS Recursor

  1. apt install pdns-recursor

2. Config recursor

vim /etc/powerdns/recursor.d/public.conf

config-dir=/etc/powerdns
forward-zones-recurse=myzone.local=127.0.0.1:53
hint-file=/usr/share/dns/root.hints
include-dir=/etc/powerdns/recursor.d
local-address=0.0.0.0
local-port=54
lua-config-file=/etc/powerdns/recursor.lua
quiet=yes
security-poll-suffix=
setgid=pdns
setuid=pdns

change myzone.local to your private zone

systemctl restart pdns.service

check port powerdns and powerdns-recursor

ss -alnp4 | grep pdns


Ref

Install PowerDNS and PowerDNS Admin on Debian 11/10 | ComputingForGeeks
PowerDNS is a DNS server written in C++ language providing both Authoritative Server and Recursor DNS products. An Authoritative Server answers questions