PowerDNS is easily installed and run on most servers, whether you’re using it as an authoritative server or a recursor. To better understand the difference, check out this blog.
Basically your authoritative server has the actual DNS info you’re looking for or providing (usually an IP), and your recursive server is the one finding the path to the right server and caching any previously checked information.
Checking out PowerDNS
While most other nameservers combine recursive and authoritative functions, PowerDNS or pdns comes in two flavours (pdns-auth and pdns-recursor). Trying it out by installing the binaries is easy enough with the installation docs. The default comes with a bind backend, but in this example we’re using sqlite3 instead.
So for the containerized version, all we need is a server with:
- docker
- docker-compose
- port 53 (and potentially 8081/8082 if you want to contact pdns via API) open
We start with the docker-compose.yaml file:
# based on https://github.com/PowerDNS/pdns
---
version: '2.0'
services:
recursor:
image: powerdns/pdns-recursor-45:4.5.5 # the latest pdns-recursor from dockerhub
# the forward-zones are used to make sure the recursor asks the local authoritative server
# about our own domains
command: --forward-zones=<domain>=172.25.0.2:5300 --local-address=0.0.0.0 --local-port=53
environment:
- PDNS_RECURSOR_API_KEY
ports:
- "53:53"
- "53:53/udp"
- "8082:8082" # HTTP API for the recursor
auth:
image: powerdns/pdns-auth-45:4.5.1 # latest pdns-authoritative nameserver image
command: --local-address=0.0.0.0 --local-port=5300
user: root
environment:
- PDNS_AUTH_API_KEY
ports:
- "5300:5300" # this is the port we redirect queries to above
- "5300:5300/udp"
- "8081:8081" # HTTP API of the server
volumes:
- /var/lib/powerdns/pdns.sqlite3:/var/lib/powerdns/pdns.sqlite3
networks:
default:
ipv4_address: 172.25.0.2
networks:
default:
driver: bridge
ipam:
config:
# defining the network range and IP for the authoritative server is only necessary in
# specific cases (e.g. to avoid breaking networking on some servers, most do fine without)
- subnet: 172.25.0.0/16
Initializing the database
Before running pdns, the sqlite database needs to be created.
mkdir /var/lib/powerdns
sqlite3 -init schema.sql /var/lib/powerdns/pdns.sqlite3
Where schema.sql is taken from here.
Environment variables for API access
To enable the API access to pdns, make sure you have the following environment variables set:
export PDNS_RECURSOR_API_KEY=changeme
export PDNS_AUTH_API_KEY=changeme
Starting the containers is as simple as running docker-compose up -d
in the folder where the above YAML file is.
Testing
Check if your containers are successfully running with docker-compose ps -a
.
If they’re up, you can test the service using
curl -v -H 'X-API-Key: changeme' http://<serverIP>:8081/api/v1/servers/localhost/ | jq
To add zones to the authoritative server you can use pdnsutil
or the API.
To check if you’ve successfully added a zone or record, you can check with either
nslookup <domain> <serverIP>
or
dig <domain> @serverIP
Adding a --port 5300
to the dig command, let’s you test the authoritative server directly.