PowerDNS is a DNS server written in C++ language providing both Authoritative Server and Recursor DNS products. An Authoritative Server answers questions about domains it knows about and doesn’t resolve queries about domains it doesn’t know about whereas a Recursor DNS has no knowledge of domains and consults other authoritative servers to provide answers to questions directed to it. Though these two products are offered separately, in most setups, they are combined and work seamlessly.
PowerDNS was developed in 1999 as a commercial product and became an open-source product in 2002 licensed under the GPL v2 license. Ever since that period, this product has gained popularity with several feature improvements. Some of the amazing features offered by PowerDNS are:
- Supports innumerable backends ranging from simple zonefiles to relational databases and load balancing/failover algorithms.
- It offers very high domain resolution performance.
- Has improved security features.
- It provides a lot of statistics during its operation which not only helps to determine the scalability of an installation but also spotting problems.
The PowerDNS Admin is a web admin interface that allows one to create and manage DNS zones using PowerDNS. It offers the below features:
- Provides a domain template
- Multiple domain management
- User activity logging
- User management
- Offers limited API for manipulating zones and records
- Support Google / Github / Azure / OpenID OAuth
- Supports a Two-factor authentication (TOTP) protocol
- Support Local DB / SAML / LDAP / Active Directory user authentication
- Dashboard and pdns service statistics
- Supports DynDNS 2 protocol
This guide offers the required knowledge on how to install PowerDNS and manage it using PowerDNS Admin on Debian 11 / Debian 10.
Update the System
It is always safe to work with a system that is up-to-date. Updating your Debian 11 / Debian 10 system can be done using the simple command:
sudo apt update && sudo apt upgrade
Install the required tools:
sudo apt install curl vim git libpq-dev -y
Once all the packages have been updated to their latest stable versions, proceed with the below steps.
Step 1 – Install the PowerDNS Relational Database
PowerDNS supports innumerable database backends such as MySQL, PostgreSQL, Oracle e.t.c. Here, we will use the MariaDB as backend storage for PowerDNS zone files.
Install MariaDB on Debian 11 / Debian 10 using the below steps:
First, install the required tools:
sudo apt install software-properties-common gnupg2 -y
Then proceed and the MariaDB 10.6 repository on the system.
curl -LsS -O https://downloads.mariadb.com/MariaDB/mariadb_repo_setup
sudo bash mariadb_repo_setup
Update your package index and install MariaDB.
sudo apt update
sudo apt install mariadb-server mariadb-client
Once the installation is complete, start and enable MariaDB.
sudo systemctl start mariadb
sudo systemctl enable mariadb
Login to the shell using the root user
sudo mysql -u root
Now create a PowerDNS database.
CREATE DATABASE powerdns;
GRANT ALL ON powerdns.* TO 'powerdns_user'@'%' IDENTIFIED BY 'Strongpassword';
FLUSH PRIVILEGES;
EXIT
Remember the password set for the user should not contain special characters since PowerDNS doesn’t like this and will cause the error “Access denied for user ‘powerdns_user’@’localhost’ (using password: YES)“
Step 2 – Install PowerDNS on Debian
We will begin by disabling the systemd-resolved service. This service runs on port 53 providing network name resolution used to load applications but now we want to use PowerDNS.
Stop and disable systemd-resolved using the commands:
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
Proceed and remove the symbolic link for the file.
$ ls -lh /etc/resolv.conf
-rw-r--r-- 1 root root 49 Feb 23 04:53 /etc/resolv.conf
$ sudo unlink /etc/resolv.conf
Update the resolv.conf file.
$ sudo vim /etc/resolv.conf
nameserver 8.8.8.8
After the above adjustments, you can install PowerDNS from the default APT repositories using the command:
sudo apt install pdns-server pdns-backend-mysql
Install the latest release of PowerDNS available on the official PowerDNS release page. As of this guide, the stable release was at 4.6. The repository for this release can be added to the system as below.
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
Now install the PowerDNS server and the MySQL backend as below.
sudo apt install pdns-server pdns-backend-mysql
Step 3 – Configure the PowerDNS Database
Now that we have the PowerDNS database already created on MariaDB, we will proceed and import the database schemas to it. This normally saved under the /usr/share/pdns-backend-mysql/schema/ as a schema.mysql.sql file.
Now import this schema to the created database(powerdns) in step 1.
mysql -u powerdns_user -p powerdns < /usr/share/pdns-backend-mysql/schema/schema.mysql.sql
You can then verify schema import as below.
sudo mysql -u root
use powerdns;
show tables;
Sample output:
After the schema has been imported, we will now configure the PowerDNS connection details to the database.
This can be done by creating the file below.
sudo vim /etc/powerdns/pdns.d/pdns.local.gmysql.conf
In the opened file, edit the lines:
# MySQL Configuration
# Launch gmysql backend
launch+=gmysql
# gmysql parameters
gmysql-host=127.0.0.1
gmysql-port=3306
gmysql-dbname=powerdns
gmysql-user=powerdns_user
gmysql-password=Strongpassword
gmysql-dnssec=yes
# gmysql-socket=
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
You can now verify the database connection.
sudo systemctl stop pdns.service
sudo pdns_server --daemon=no --guardian=no --loglevel=9
Execution output:
With the above output, the database connection is successful. Restart and enable the PowerDNS service.
sudo systemctl restart pdns
sudo systemctl enable pdns
Verify the port 53 is open for DNS.
sudo ss -alnp4 | grep pdns
Output:
udp UNCONN 0 0 0.0.0.0:53 0.0.0.0:* users:(("pdns_server",pid=18530,fd=5))
tcp LISTEN 0 128 0.0.0.0:53 0.0.0.0:* users:(("pdns_server",pid=18530,fd=7))
You can also check if PowerDNS is responding to requests.
$ dig @127.0.0.1
; <<>> DiG 9.16.22-Debian <<>> @127.0.0.1
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 4882
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;. IN NS
;; Query time: 4 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Feb 23 06:03:49 EST 2022
;; MSG SIZE rcvd: 28
Step 4 – Install PowerDNS Admin on Debian
With this Web-based admin tool, we can easily manage the PowerDNS server. To install PowerDNS admin, begin by installing the Python development package.
sudo apt install python3-dev
Install the required build tools.
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
Install Node.js on Debian. First, add the repository
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
Then install Nodejs with the command;
sudo apt install -y nodejs
You also need the yarn package. Add its repository and GPG key as below.
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
Install Yarn with the command below.
sudo apt update
sudo apt install yarn -y
Now clone the PowerDNS admin source code.
sudo su -
git clone https://github.com/ngoduykhanh/PowerDNS-Admin.git /var/www/html/pdns
Create a virtual environment.
cd /var/www/html/pdns/
virtualenv -p python3 flask
Activate the environment and install the libraries specified in the requirements.txt.
source ./flask/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
Now configure the PowerDNS admin connectivity to our database. First, deactivate the virtual environment.
deactivate
Edit the file below.
vim /var/www/html/pdns/powerdnsadmin/default_config.py
In the file, edit the below lines.
### DATABASE CONFIG
SQLA_DB_USER = 'powerdns_user'
SQLA_DB_PASSWORD = 'Strongpassword'
SQLA_DB_HOST = '127.0.0.1'
SQLA_DB_NAME = 'powerdns'
SQLALCHEMY_TRACK_MODIFICATIONS = True
....
Now create a database schema.
cd /var/www/html/pdns/
source ./flask/bin/activate
export FLASK_APP=powerdnsadmin/__init__.py
flask db upgrade
If you find the error “ImportError: cannot import name ‘json’ from ‘itsdangerous’” proceed as below.
pip uninstall itsdangerous
pip install itsdangerous==2.0.1
flask db upgrade
Sample output:
.....
Add view column to setting table
INFO [alembic.runtime.migration] Running upgrade 59729e468045 -> 1274ed462010, Change setting.value data type
INFO [alembic.runtime.migration] Running upgrade 1274ed462010 -> 4a666113c7bb, Adding Operator Role
INFO [alembic.runtime.migration] Running upgrade 4a666113c7bb -> 31a4ed468b18, Remove all setting in the DB
INFO [alembic.runtime.migration] Running upgrade 31a4ed468b18 -> 654298797277, Upgrade DB Schema
INFO [alembic.runtime.migration] Running upgrade 654298797277 -> 0fb6d23a4863, Remove user avatar
INFO [alembic.runtime.migration] Running upgrade 0fb6d23a4863 -> 856bb94b7040, Add comment column in domain template record table
INFO [alembic.runtime.migration] Running upgrade 856bb94b7040 -> b0fea72a3f20, Update domain serial columns type
INFO [alembic.runtime.migration] Running upgrade b0fea72a3f20 -> 3f76448bb6de, Add user.confirmed column
INFO [alembic.runtime.migration] Running upgrade 3f76448bb6de -> 0d3d93f1c2e0, Add domain_id to history table
INFO [alembic.runtime.migration] Running upgrade 0d3d93f1c2e0 -> 0967658d9c0d, add apikey account mapping table
Once successful, generate the asset files using Yarn.
yarn install --pure-lockfile
flask assets build
Deactivate the virtual environment.
deactivate
Enable PowerDNS API access
With the REST API exposed, one is able to control several activities, read statistics, modify zone content e.t.c. Enable it by editing the config file below.
sudo vim /etc/powerdns/pdns.conf
In the opened file, make the below changes.
# api Enable/disable the REST API (including HTTP listener)
#
# api=no
api=yes
#################################
# api-key Static pre-shared authentication key for access to the REST API
#
# api-key=
api-key=3ce1af6c-981d-4190-a559-1e691d89b90e #You can generate one from https://codepen.io/corenominal/pen/rxOmMJ
Save the file and restart PowerDNS.
sudo systemctl restart pdns
Create a PowerDNS Virtual Host file.
First, install the Nginx web server.
sudo apt install nginx
Create a virtual host file
vim /etc/nginx/conf.d/powerdns-admin.conf
Add the content below.
server {
listen *:80;
server_name pdnsadmin.geeksforgeeks.org;
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;
}
}
Rename the default Nginx file.
mv /etc/nginx/sites-enabled/default{,.old}
Check the syntax of the created file above.
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Set the right ownership of the file.
chown -R www-data: /var/www/html/pdns
Restart Nginx for the changes to apply.
systemctl restart nginx
Create a System service file for PowerDNS Admin
To be able to manage PowerDNS Admin just like other system services, we need to create a service file for it.
Create the file as below.
vim /etc/systemd/system/pdnsadmin.service
Add the below content to it.
[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
Also, create a socket file.
sudo vim /etc/systemd/system/pdnsadmin.socket
Add the lines:
[Unit]
Description=PowerDNS-Admin socket
[Socket]
ListenStream=/run/pdnsadmin/socket
[Install]
WantedBy=sockets.target
Create an environment file.
mkdir /run/pdnsadmin/
echo "d /run/pdnsadmin 0755 pdns pdns -" >> /etc/tmpfiles.d/pdnsadmin.conf
Set the required permissions.
chown -R pdns: /run/pdnsadmin/
chown -R pdns: /var/www/html/pdns/powerdnsadmin/
Reload the system daemon.
systemctl daemon-reload
Start and enable the PowerDNS Admin service.
systemctl enable --now pdnsadmin.service pdnsadmin.socket
Check the status of the service.
systemctl status pdnsadmin.service pdnsadmin.socket
Output:
Step 5 – Access the PowerDNS Admin Web UI
AT this point, the PowerDNS web UI should be accessible using the URL http://domain_name or http://IP_address.
Begin by creating the admin user account.
With the required details provides, click register to create the account. Now login to the PowerDNS Admin interface using the created user credentials.
Now to be able to manage the PowerDNS server, provide the API key URL http://127.0.0.1:8081 and the API Key defined in the PowerDNS config file(/etc/powerdns/pdns.conf)
Click Update for the error to disappear. Now you can manage the PowerDNS. The dashboard will be as below.
Create a new domain under the +New Domain tab
Enter the domain name, select the template to use from the templates list, and submit. Now you will have your domain added as below.
Add records to the domain by clicking on it. Provide the name of the record, save and apply changes.
There are many other configurations you can make to your server using the PowerDNS admin web UI such as editing the domain templates, removing domains, managing user accounts e.t.c. You can view the history of activities performed as well.
Closing Thoughts.
That is it! You have successfully installed PowerDNS and PowerDNS Admin on Debian 11 / Debian 10. I hope this was helpful.
See more:
- Install PowerDNS on CentOS 8 with MariaDB & PowerDNS-Admin
- Bind vs dnsmasq vs PowerDNS vs Unbound
- Install PowerDNS and PowerDNS-Admin on Ubuntu
- Configure Slave BIND DNS Server on Ubuntu