PowerDNS on OpenBSD

Page content

Run PowerDNS on OpenBSD

I’m mostly happy with NSD as Authoritative Nameserver. But why not look over the fence and have a look at PowerDNS ? At least the API looks promising to me …

Install Package

doas pkg_add powerdns--

Create Folder, DB and set Permission

doas mkdir /var/db/pdns
doas sqlite3 /var/db/pdns/pdns.sql < /usr/local/share/doc/pdns/schema.sqlite3.sql
doas chown -R _powerdns:wheel /var/db/pdns/

Update Config File /etc/pdns/pdns.conf

# DB
gsqlite3-database=/var/db/pdns/pdns.sql
launch=gsqlite3
setuid=_powerdns

# Tuning & Protection
max-queue-length=5000
overload-queue-length=2500

# Webserver
webserver=yes
webserver-address=ip-of-your-nameserver
webserver-allow-from=127.0.0.1,::1,my-remote-ip-address

Enable and Start Service

doas rcctl enable pdns_server
doas rcctl restart pdns_server

Import Data from NSD

If you have an existing NSD Setup, you can easily import the zones into the sqlite db.

cd /var/nsd/zones/slave
for i in `ls`; do pdnsutil load-zone $i /var/nsd/zones/slave/$i; done

Check PowerDNS Page

goto http://ip-of-your-nameserver:8081/

Enable API and Restart Service

https://doc.powerdns.com/authoritative/http-api/index.html

Update Config File /etc/pdns/pdns.conf

api=yes
api-key=xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX

doas rcctl restart pdns_server

Check API

$ curl -s -H 'X-API-Key:xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX' http://ip-of-my-host:8081/api/v1/servers/localhost |jq . 
{
  "config_url": "/api/v1/servers/localhost/config{/config_setting}",
  "daemon_type": "authoritative",
  "id": "localhost",
  "type": "Server",
  "url": "/api/v1/servers/localhost",
  "version": "4.4.1",
  "zones_url": "/api/v1/servers/localhost/zones{/zone}"
}

Get Zone

$ curl -s -H 'X-API-Key:xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX' http://ip-of-my-host:8081/api/v1/servers/localhost/zones |jq .[0]
{
  "account": "",
  "dnssec": false,
  "edited_serial": 2021040103,
  "id": "stoege.net.",
  "kind": "Native",
  "last_check": 0,
  "masters": [],
  "name": "stoege.net.",
  "notified_serial": 0,
  "serial": 2021040103,
  "url": "/api/v1/servers/localhost/zones/stoege.net."
}

Python CLI

https://github.com/pbertera/PowerDNS-CLI

./pdns.py --apikey xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX --apihost ip-of-my-host --apiport 8081 --zone example.com. --zoneType MASTER --nameserver ns.example.com. --debug add_zone
2021-07-31 08:31:06,162 pdns         DEBUG    sending GET request to http://xx.xx.xx.xx.xx:8081/api/v1/servers/localhost/zones/example.com.
2021-07-31 08:31:06,180 pdns         DEBUG    returned 404 Not Found
2021-07-31 08:31:06,181 pdns         DEBUG    sending POST request to http://xx.xx.xx.xx:8081/api/v1/servers/localhost/zones
2021-07-31 08:31:06,181 pdns         DEBUG    POST data: {"name": "example.com.", "kind": "MASTER", "masters": [], "soa_edit_api": "INCEPTION-INCREMENT", "nameservers": ["ns.example.com."]}
2021-07-31 08:31:06,201 pdns         DEBUG    returned 201 {"account": "", "api_rectify": false, "dnssec": false, "edited_serial": 0, "id": "example.com.", "kind": "Master", "last_check": 0, "master_tsig_key_ids": [], "masters": [], "name": "example.com.", "notified_serial": 0, "nsec3narrow": false, "nsec3param": "", "rrsets": [{"comments": [], "name": "example.com.", "records": [{"content": "a.misconfigured.dns.server.invalid. hostmaster.example.com. 0 10800 3600 604800 3600", "disabled": false}], "ttl": 3600, "type": "SOA"}, {"comments": [], "name": "example.com.", "records": [{"content": "ns.example.com.", "disabled": false}], "ttl": 3600, "type": "NS"}], "serial": 0, "slave_tsig_key_ids": [], "soa_edit": "", "soa_edit_api": "INCEPTION-INCREMENT", "url": "/api/v1/servers/localhost/zones/example.com."}
2021-07-31 08:31:06,202 pdns         INFO     DNS Zone 'example.com.' Successfully Added...

Migrate Szenario from NSD to PowerDNS

assuming you have three NSD instances running. ns1 as master, ns2 and ns3 as slave.

NS1 (Master)

disable authentication key (if enabled)

pattern:
  name:                 "toslave"
  notify:               ip-of-ns2 NOKEY
  provide-xfr:          ip-of-ns2 NOKEY
  notify:               ip-of-ns3 NOKEY
  provide-xfr:          ip-of-ns3 NOKEY

NS2 and NS3

update /etc/pdns/pdns.conf, enable slave, allow xfr and notify

allow-axfr-ips=127.0.0.0/8,::1,ip-of-ns1-server/32
allow-notify-from=ip-of-ns1-server/32
axfr-lower-serial=yes
slave=yes

Create Slave Zones

cd /var/nsd/zones/slave
for i in `ls`; do pdnsutil create-slave-zone $i ip-of-your-master-ns-server; done

Restart Service

rcctl restart pdns_server

Change Slave to Master

finally, you can switch a NS to Master if needed

https://doc.powerdns.com/authoritative/migration.html

UPDATE domains set type='MASTER' where type='SLAVE';

rcctl restart pdns_server

DNSSEC

Assuming you have DNSSEC Running on your Primary Nameserver for certain Zones, you have to do some additional Steps.

Enable DNSSEC

add the following to /etc/pdns/pdns.conf

# DNSSEC
gsqlite3-dnssec=yes

and restart the service

doas rcctl restart pdns_server

Check Zone

Check the Zone(s) which are DNSSEC Enabled

$ doas pdnsutil show-zone stockersolutions.com
This is a Slave zone
Master: 45.15.80.202:53 
Last time we got update from master: Wed 2021-10-06 13:56:28
SOA serial in database: 2021100601
Refresh interval: 3600 seconds
Zone is not actively secured
Metadata items: None
No keys for zone 'stockersolutions.com'.

Enable Zone

Set the Zone to “presigned”. That mean, you learn the signed as well from master and you don’t have to sign/update on your own.

$ doas pdnsutil set-presigned stoege.com

Check Zone again

now, you should see the Zone signed and the appropriate records

$ doas pdnsutil show-zone stockersolutions.com
This is a Slave zone
Master: 45.15.80.202:53 
Last time we got update from master: Wed 2021-10-06 13:56:28
SOA serial in database: 2021100601
Refresh interval: 3600 seconds
Metadata items: 
  PRESIGNED 1
Zone is presigned
Zone has NSEC semantics
keys: 
KSK, tag = 6387, algo = 13, bits = 256
DNSKEY = stockersolutions.com. IN DNSKEY 257 3 13 32kJcxJWLYivrgtk1/+KY9LI11SjyFSY/D5rUDB3N6Q/8j847qIj46ABDGPvXANLidMJDZInh1cYmDIbv2h1UQ==; ( ECDSAP256SHA256 ) 
DS = stockersolutions.com. IN DS 6387 13 1 1e9ed986beb80a8c56d2b0facfb48f6f1dbb180c ; ( SHA1 digest )
DS = stockersolutions.com. IN DS 6387 13 2 73f93848e41292011221f6cf346f2539ce83bebb3a8892ebeea1d2e3eab4ab1d ; ( SHA256 digest )
DS = stockersolutions.com. IN DS 6387 13 4 db810cb1dca33adc23b7f75cc985f5b6072cb86a3372c8b1dc8410979f1fe5361ed96dd4f858a0f693b02e0d30a1a0c3 ; ( SHA-384 digest )
ZSK, tag = 15670, algo = 13, bits = 256
DNSKEY = stockersolutions.com. IN DNSKEY 256 3 13 vgCMYWTjF6IkoVm5qrMwKNNu6glQUbhT8amcT1IjFpzgn0mH4iOv9Ahyb7mQTCO8A+6bVQSAIOzeLdUZPb++CQ==; ( ECDSAP256SHA256 ) 
DS = stockersolutions.com. IN DS 15670 13 1 89c85c9287c5d6f3c01c6d56737505b2e39e841d ; ( SHA1 digest )
DS = stockersolutions.com. IN DS 15670 13 2 8d0dfc7386156c66370bedab8b574e93da7ace5172819e5fb26b99353699a22b ; ( SHA256 digest )
DS = stockersolutions.com. IN DS 15670 13 4 62f65c563345e230852710c5f4c7ea602e7c07559fa66ea3039db9840f1cb42771fcb1d14622119d0d52f90999c15f73 ; ( SHA-384 digest )

Online Tests

there are many ressource for checking if your DNSSEC Setup is working. here are a few:

Happy DNS / PowerDNS / DNSSEC !

sha256: afd2d0b06e418c72dbde1cd95b337366166cf6ef1911233070477bd96cc597b1