Power DNS

Install

Install power DNS with SQL server support.

apt update
apt full-upgrade
apt install pdns-backend-sqlite3 pdns-backend-mysql pdns-server

Stop

systemctl stop pdns

MySQL

Now setup MySQL for power DNS.

Install mariadb
apt install mariadb-server mariadb-client
rehash
mariadb-secure-installation
Create database and user
mysql
CREATE DATABASE pdns CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;
CREATE USER 'pdns'@'localhost' IDENTIFIED BY 'pdns';
GRANT ALL PRIVILEGES ON pdns.* TO 'pdns'@'localhost';
FLUSH PRIVILEGES;
SELECT User,Host FROM mysql.user;
+-------------+-----------+
| User        | Host      |
+-------------+-----------+
| mariadb.sys | localhost |
| mysql       | localhost |
| pdns        | localhost |
| root        | localhost |
+-------------+-----------+
4 rows in set (0.002 sec)
exit
Create tables
mysql -updns -ppdns pdns < /usr/share/doc/pdns-backend-mysql/schema.mysql.sql
Show tables
mysql -updns -ppdns pdns
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 22
Server version: 11.8.2-MariaDB-1 from Debian -- Please help get to 10k stars at https://github.com/MariaDB/Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [pdns]> show tables;
+----------------+
| Tables_in_pdns |
+----------------+
| comments       |
| cryptokeys     |
| domainmetadata |
| domains        |
| records        |
| supermasters   |
| tsigkeys       |
+----------------+
7 rows in set (0.001 sec)

Example

Domains

Example domain.

INSERT INTO domains (id,name,type) values (1,'example.com','MASTER');

Domain type can be MASTER, SLAVE or NATIVE (NATIVE does not automatically sync with slaves).

Records

Example records.

You may replace “999” with a serial number generated like this:

php -r 'print time() . "\n";'
INSERT INTO records (domain_id,name,type,prio,content,ttl) VALUES (1,'example.com','SOA',0,'ns1.example.com hostmaster.example.com 999 10800 10800 108000 1800',1800);
INSERT INTO records (domain_id,name,type,prio,content,ttl) VALUES (1,'example.com','NS',0,'ns1.example.com',10800);

Configuration

local-address=127.0.0.1,::1

#### MYSQL CONFIG
launch=gmysql
gmysql-host=localhost
gmysql-port=3306
gmysql-dbname=pdns
gmysql-user=pdns
gmysql-password=pdns
gmysql-dnssec=no

#### AXFR CONFIG
disable-axfr=no
allow-axfr-ips=127.0.0.1,::1

#### SECURITY
setuid=pdns
setgid=pdns

#### MASTER
primary=yes

#### SLAVE
secondary=no

#### LOGGING
loglevel=4
query-logging=no
log-dns-details=no

#### TTL
default-ttl=900

Run

systemctl start pdns

Test

dig ANY example.com @::1

; <<>> DiG 9.20.11-4-Debian <<>> ANY example.com @::1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7985
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;example.com.                   IN      ANY

;; ANSWER SECTION:
example.com.            10800   IN      NS      ns1.example.com.
example.com.            1800    IN      SOA     ns1.example.com. hostmaster.example.com. 999 10800 10800 108000 1800

;; Query time: 0 msec
;; SERVER: ::1#53(::1) (TCP)
;; WHEN: Wed Sep 03 20:42:25 BST 2025
;; MSG SIZE  rcvd: 113
dig AXFR example.com @::1

; <<>> DiG 9.20.11-4-Debian <<>> AXFR example.com @::1
;; global options: +cmd
example.com.            1800    IN      SOA     ns1.example.com. hostmaster.example.com. 999 10800 10800 108000 1800
example.com.            10800   IN      NS      ns1.example.com.
example.com.            1800    IN      SOA     ns1.example.com. hostmaster.example.com. 999 10800 10800 108000 1800
;; Query time: 4 msec
;; SERVER: ::1#53(::1) (TCP)
;; WHEN: Wed Sep 03 20:40:31 BST 2025
;; XFR size: 3 records (messages 3, bytes 264)

Sync

Update serial in SOA and then send notify to slave.

Update method 1

eg. with serial 1688651644

update records set content='ns1.example.com hostmaster.example.com 1688651644 10800 10800 108000 1800' where type='SOA' and domain_id=1;
Update method 2
pdnsutil increase-serial example.com
Notify

When the domain type is set to NATIVE or MASTER (not SLAVE) a notify can be sent manually.

pdns_control notify-host example.com X.X.X.X

NB If the domain type is MASTER a notify will be sent automatically by Power DNS but it may be delayed.

Resources

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies