PowerDNS Authoritative Server stores DNS zones in a database and exposes an HTTP API, which makes it easy to manage many domains automatically. This guide installs PowerDNS with a MariaDB backend, creates a first zone and enables the API.
Before you start
- A Linux VPS with a static IP, root access and UDP/TCP 53 open.
- Nothing else listening on port 53. On Ubuntu,
systemd-resolvedruns a stub resolver on 127.0.0.53, which is fine, but make PowerDNS listen on the public IP.
Install MariaDB and PowerDNS
- Ubuntu/Debian:
sudo apt install -y mariadb-server pdns-server pdns-backend-mysql - AlmaLinux/Rocky (EPEL):
sudo dnf install -y epel-release && sudo dnf install -y mariadb-server pdns pdns-backend-mysql && sudo systemctl enable --now mariadb
For the newest release you can use the official PowerDNS repositories instead.
Create the database
- Open the MariaDB shell with
sudo mariadband run:CREATE DATABASE pdns; CREATE USER 'pdns'@'localhost' IDENTIFIED BY 'a-long-random-password'; GRANT ALL PRIVILEGES ON pdns.* TO 'pdns'@'localhost'; FLUSH PRIVILEGES; - Load the schema shipped with the backend package (path varies by version):
sudo mariadb pdns < /usr/share/pdns-backend-mysql/schema/schema.mysql.sqlOn AlmaLinux look for
schema.mysql.sqlunder/usr/share/doc/pdns*/.
Configure PowerDNS
- Edit
/etc/powerdns/pdns.conf(AlmaLinux:/etc/pdns/pdns.conf):launch=gmysql gmysql-host=127.0.0.1 gmysql-dbname=pdns gmysql-user=pdns gmysql-password=a-long-random-password local-address=203.0.113.10 api=yes api-key=change-this-long-random-key webserver=yes webserver-address=127.0.0.1 webserver-port=8081 webserver-allow-from=127.0.0.1On Debian/Ubuntu remove or comment out the default
launch=bindline or file inpdns.d/if present. - Restart:
sudo systemctl restart pdnsand checkjournalctl -u pdns.
The authoritative server never recurses, so it cannot become an open resolver.
Create a zone
sudo pdnsutil create-zone example.com ns1.example.com
sudo pdnsutil add-record example.com @ A 3600 203.0.113.50
sudo pdnsutil add-record example.com www CNAME 3600 example.com.
sudo pdnsutil add-record example.com @ MX 3600 "10 mail.example.com."
sudo pdnsutil add-record example.com ns1 A 3600 203.0.113.10
sudo pdnsutil check-zone example.comUse the API
List zones from the server itself:
curl -s -H 'X-API-Key: change-this-long-random-key' http://127.0.0.1:8081/api/v1/servers/localhost/zonesTools like PowerDNS-Admin or your own scripts can create and edit records through this API. Keep it bound to localhost or behind a VPN.
Enable DNSSEC (optional)
sudo pdnsutil secure-zone example.com
sudo pdnsutil show-zone example.comPublish the DS record shown at your registrar.
Test
dig @203.0.113.10 example.com A +norecurse– answer with theaaflag.dig @203.0.113.10 google.com– should returnREFUSED.
Troubleshooting
- "Unable to bind to port 53": another service uses the address; check
ss -ulpn | grep :53. - Database connection errors: wrong credentials or schema not loaded.
- Zone returns SERVFAIL: run
pdnsutil check-zoneand check DNSSEC status.
FAQ: PowerDNS
Do I need the PowerDNS Recursor too?
Only if you want a resolver for your own servers. Never expose a recursor to the public internet.
How do I add a secondary server?
Either replicate the database to a second PowerDNS server or use native DNS zone transfers (primary/secondary mode).
Can cPanel use PowerDNS?
Yes, cPanel supports PowerDNS as its nameserver, configured in WHM rather than by hand.
