PowerDNS seems pretty flexible. I’m just looking for a way to serve my own DNS since my registrar doesn’t support SSHFP records among other things. Oh, also I wanted to be able to get a wildcard cert from LetsEncrypt, so I’d need to do a DNS-01 challenge.
I’m just playing around with PowerDNS for now, since I’m actually pretty bad in terms of understanding how DNS works.
Links
- Homepage
- https://www.powerdns.com/powerdns-authoritative-server
- Source
- https://github.com/PowerDNS/pdns/
- Documentation
- https://doc.powerdns.com/authoritative/indexTOC.html
The Nix package is powerdns
, so you can try:
$ nix-shell -p powerdns $ pdns_server --help syntax: --8bit-dns | --8bit-dns=yes | --8bit-dns=no Allow 8bit dns queries --allow-axfr-ips=... Allow zonetransfers only to these subnets --allow-dnsupdate-from=... A global setting to allow DNS updates from these IP ranges. --allow-notify-from=... Allow AXFR NOTIFY from these IP ranges. If empty, drop all incoming notifies. --allow-unsigned-autoprimary=... Allow autoprimaries to create zones without TSIG signed NOTIFY --allow-unsigned-notify=... Allow unsigned notifications for TSIG secured zones
Configuration
I wanted to set up a pretty simple example to play around with PowerDNS without being root.
By default PowerDNS is going to try to load stuff from /etc/pdns/pdns.conf
, and I don’t really want to edit a file there.
Instead, I want to try modifying some stuff in some directory I control.
So, to do this, I load configuration from the current directrory like so:
pdns_server "--socket-dir=$(pwd)" "--config-dir=$(pwd)/"
Then you’ll need to have a pdns.conf
in this directory.
Here’s a basic one that tries to load a BIND
configuration:
# A super basic and bad PowerDNS config
launch=bind
bind-config=named.conf
local-address=127.0.0.1
local-port=5300
webserver=yes
webserver-port=8989
webserver-address=127.0.0.1
webserver-allow-from=127.0.0.1,::1
log-dns-details
log-dns-queries
loglevel=5
# This is just so I filter out timestamps when posting stuff online
log-timestamp=no
Logging here was pretty helpful for figuring out what’s going wrong.
I struggled for 20 minutes because it turned out that the bind backend wasn’t loading my config and just silently failing.
This caused pdns
to think it wasn’t authoritative for some jmm.example
domain I was trying.
Here’s the named.conf
:
zone "jmm.example" IN {
type master;
file "jmm.example.zone";
allow-update { none; };
};
And here’s jmm.example.zone
:
$TTL 86400
@ IN SOA ns1.jmm.example. admin.jmm.example. (
2024071110 ; serial number
3600 ; refresh
1800 ; retry
604800 ; expire
86400 ) ; minimum
; Name servers
jmm.example. IN NS ns1.jmm.example.
jmm.example. IN NS ns2.jmm.example.
ns1 IN A 192.0.2.1
ns2 IN A 192.0.2.2
@ IN NS jmm.example.
@ IN A 127.0.0.1
@ IN AAAA ::1
www IN A 127.0.0.5
www IN TXT jmm=Josh Moller-Mara
www IN TXT hello=World
Now, to actually start running pdns_server
here, I do:
[nix-shell]$ pdns_server "--socket-dir=$(pwd)" "--config-dir=$(pwd)/" Loading '/nix/store/lf8642l65iigdjr57lm8kv1cjb59ir2h-pdns-4.8.4/lib/pdns/libbindbackend.so' This is a standalone pdns Listening on controlsocket in '/░░░░░░░░░░░░░░░░░░░░░/powerdns/pdns.controlsocket' UDP server bound to 127.0.0.1:5300 TCP server bound to 127.0.0.1:5300 PowerDNS Authoritative Server 4.8.4 (C) 2001-2022 PowerDNS.COM BV Using 64-bits mode. Built using gcc 12.3.0. PowerDNS comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it according to the terms of the GPL version 2. [webserver] Listening for HTTP requests on 127.0.0.1:8989 Polled security status of version 4.8.4 at startup, no known issues reported: OK [bindbackend] Parsing 1 domain(s), will report when done [bindbackend] Done parsing domains, 0 rejected, 1 new, 0 removed Creating backend connection for TCP About to create 3 backend threads for UDP Done launching threads, ready to distribute questions
Then, to query pdns
, I do:
$ dig +norecurse ANY www.jmm.example @127.0.0.1 -p 5300 ; <<>> DiG 9.18.24 <<>> +norecurse ANY www.jmm.example @127.0.0.1 -p 5300 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20717 ;; flags: qr aa; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 1232 ;; QUESTION SECTION: ;www.jmm.example. IN ANY ;; ANSWER SECTION: www.jmm.example. 86400 IN TXT "hello=World" www.jmm.example. 86400 IN TXT "jmm=Josh Moller-Mara" www.jmm.example. 86400 IN A 127.0.0.5 ;; Query time: 1 msec ;; SERVER: 127.0.0.1#5300(127.0.0.1) (TCP) ;; WHEN: Thu Jul 11 ░░░░░░░░ PDT 2024 ;; MSG SIZE rcvd: 117