Deployment guide

PowerDNS Recursor

Overview

PowerDNS Recursor is a high-performance, standards-compliant, open-source recursive DNS resolver developed by PowerDNS.COM BV. An authoritative server publishes the zones that you own. A recursor resolves names on behalf of your clients instead. It walks the DNS hierarchy from the root servers down, follows delegations, validates DNSSEC-signed answers, and caches results so that repeat lookups are answered instantly.

This guide covers the deployment and configuration of PowerDNS Recursor on Ubuntu 24.04 on Azure, using the SecureAnyCloud Azure Marketplace image.

The image installs PowerDNS Recursor 5.3 from the official PowerDNS packages (the repo.powerdns.com rec 53 stable branch), pinned above the distribution package. Unattended security upgrades keep the resolver patched on your running VM.

Recursive, not authoritative. This server resolves names for your clients and does not publish zones. Point your workloads, containers and office networks at it instead of a public resolver, to keep your DNS traffic private and under your control.

Never an open resolver. An internet-facing resolver that answers anyone is a DNS amplification hazard. This image ships with recursion restricted to loopback and the RFC1918 private ranges only (incoming.allow_from). Queries from arbitrary internet sources are refused, so this instance can never be abused as a reflector. Opening the resolver to your own client subnets is a single documented change (Step 8).

No default credentials. The REST API key is the equivalent of an administrator password for the resolver, so this image never ships a fixed key. On the first boot of every VM, the image generates a fresh per-instance REST API key and a fresh webserver password. It writes the details to /root/powerdns-recursor-credentials.txt (mode 0600, root only). The REST API and status webserver are bound to 127.0.0.1 only, so the management surface is never exposed to the network, while DNS resolution answers on port 53 for your allowed clients.

What you get:

  • PowerDNS Recursor 5.3 from the official PowerDNS packages, run under systemd as the unprivileged pdns user (pdns-recursor.service)
  • Recursion restricted to loopback and RFC1918 private ranges by default (incoming.allow_from), so the instance is never an open resolver
  • DNSSEC validation of signed answers, and the systemd-resolved stub listener disabled so that the Recursor owns port 53 cleanly
  • The REST API enabled and bound to loopback (127.0.0.1:8082), authenticated with a per-instance X-API-Key, plus the status webserver
  • A per-instance REST API key and webserver password, generated on first boot and documented in /root/powerdns-recursor-credentials.txt (0600)
  • YAML settings (the native PowerDNS Recursor 5.x format), with the SecureAnyCloud configuration split into a base drop-in and a per-VM secrets drop-in under /etc/powerdns/recursor.d/

Prerequisites

You need the following:

  • An active Azure subscription, an SSH public key, and a virtual network and subnet in the target region
  • A subscription to the PowerDNS Recursor listing on Azure Marketplace
  • Network security group rules that allow TCP 22 (admin) and both UDP and TCP 53 (DNS) from the client networks that will use the resolver
  • Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) for a small resolver. A resolver that serves heavy query volumes needs Standard_D2s_v5 or larger.
1

Deploy from the Azure Portal

Search for PowerDNS Recursor in the Marketplace, select the SecureAnyCloud publisher, and choose Create. Configure the network security group to allow UDP 53 and TCP 53 (DNS) from your client networks, and TCP 22 for administration. DNS uses UDP 53 for most queries and falls back to TCP 53 for large responses, so open both. The REST API stays on loopback and is never exposed.

2

Deploy from the Azure CLI

Create the resource group, accept the Marketplace terms, create the VM and open the ports:

RG="dns-prod"; LOCATION="eastus"; VM_NAME="resolver1" IMAGE_URN="sac1647283583153:powerdns-recursor-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION"
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:powerdns-recursor-ubuntu-24-04:default:latest
az vm create \
  --resource-group "$RG" --name "$VM_NAME" \
  --image "$IMAGE_URN" \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values "$SSH_KEY" \
  --public-ip-sku Standard
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 53 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1002
3

First boot

On first boot, the image generates a fresh per-instance REST API key and webserver password and starts pdns-recursor. It verifies that the API key round-trips and that a real recursive query resolves. It then writes /root/powerdns-recursor-credentials.txt. First boot completes within a minute. Connect over SSH as azureuser and read the details:

sudo cat /root/powerdns-recursor-credentials.txt
4

Confirm the service is running

Confirm that pdns-recursor.service (the resolver daemon) is active. ss confirms that DNS listens on :53 (UDP and TCP, all interfaces) while the REST API is bound to 127.0.0.1:8082 only.

systemctl is-active pdns-recursor.service pdns_recursor --version 2>&1 | head -1 ss -tlnup | grep -E ':53 |:8082 '
5

Resolve a name

The resolver answers recursive queries for allowed clients. Loopback is allowed by default, so a lookup works immediately on the VM. The Recursor caches answers, so it serves a repeated query instantly from the cache.

dig @127.0.0.1 A example.com +noall +answer dig @127.0.0.1 AAAA cloudflare.com +short dig @127.0.0.1 MX gmail.com +short
6

Use the REST API

The REST API exposes metrics and cache management, and automation tools use the same interface. Read your per-instance API key from the credentials file into a shell variable, then call the server info endpoint. The API is bound to loopback, so run these commands on the VM, or tunnel port 8082 over SSH.

API_KEY=$(sudo grep '^powerdns.api.key=' /root/powerdns-recursor-credentials.txt | cut -d= -f2-)
curl -s -H "X-API-Key: $API_KEY" http://127.0.0.1:8082/api/v1/servers/localhost | jq '{daemon_type, version}'
sudo rec_control get-all | grep -E '^(questions|cache-hits|cache-misses|cache-entries|all-outqueries)\b'

A request without the key is rejected with HTTP 401, and a request with the key returns HTTP 200:

API_KEY=$(sudo grep '^powerdns.api.key=' /root/powerdns-recursor-credentials.txt | cut -d= -f2-)
echo -n 'with key : HTTP '; curl -s -o /dev/null -w '%{http_code}\n' -H "X-API-Key: $API_KEY" http://127.0.0.1:8082/api/v1/servers/localhost
echo -n 'wrong key : HTTP '; curl -s -o /dev/null -w '%{http_code}\n' -H 'X-API-Key: wrong-key' http://127.0.0.1:8082/api/v1/servers/localhost
7

Review the secure-by-default configuration

No default or shared credentials ship in the image. The credentials file is 0600 root:root, and the API key and webserver password are unique to this VM. The resolver is not an open resolver, because incoming.allow_from is restricted to loopback and RFC1918 private ranges. The REST API is bound to loopback only.

sudo stat -c '%n perms: %a owner: %U:%G' /root/powerdns-recursor-credentials.txt
sudo grep -vE '^\s*#|^\s*$' /etc/powerdns/recursor.d/sac-recursor.yml
sudo stat -c '%n perms: %a owner: %U:%G' /etc/powerdns/recursor.d/sac-secrets.yml
8

Allow your own clients to resolve

By default, only loopback and RFC1918 ranges may query the resolver. To let a specific client subnet resolve, add the subnet as a new list item under incoming.allow_from in the base config and reload. Never add 0.0.0.0/0, because that would make this an open resolver that attackers can abuse for DNS amplification.

sudoedit /etc/powerdns/recursor.d/sac-recursor.yml
# under the allow_from: list, add a line for your client subnet, for example:
# - <your-mgmt-cidr>
sudo systemctl reload pdns-recursor

Then, from a client inside that subnet, point its resolver at the IP address of this VM and test:

dig @<public-ip> A example.com +short
9

DNSSEC validation

The Recursor validates DNSSEC-signed zones. A query for a correctly signed name returns the ad (authenticated data) flag. A deliberately broken signature fails to resolve, which shows that the resolver protects your clients from tampered answers.

dig @127.0.0.1 A cloudflare.com +dnssec +multiline | grep -E 'flags:|status:' dig @127.0.0.1 A example.com +dnssec | grep -E 'flags:|status:'
10

Forwarding and RPZ threat filtering

For split-horizon DNS or private domains, forward specific zones to a private authoritative server by adding a recursor.forward_zones entry (YAML). For DNS firewalling, load a Response Policy Zone (RPZ) so that the resolver blocks known malicious domains. Configure both as YAML drop-ins in /etc/powerdns/recursor.d/. See the PowerDNS Recursor documentation for the full schema. Here is an example forward zone drop-in:

recursor: forward_zones: - zone: internal.example forwarders: - 10.0.0.53
11

Security recommendations

  • Keep the resolver closed to the internet. Add to incoming.allow_from only the specific client subnets that need resolution. Never add 0.0.0.0/0. The network security group should also allow UDP and TCP 53 only from those networks.
  • Keep the REST API on loopback. The image binds the API and status webserver to 127.0.0.1 and sets webservice.allow_from to loopback. Do not expose the API directly. If you need it remotely, tunnel port 8082 over SSH.
  • Enable RPZ (Step 10) to block malicious and unwanted domains at the resolver.
  • Restrict administration. Allow TCP 22 for administration only, from your management network.
  • Keep the OS and PowerDNS patched. Unattended security upgrades remain enabled on the running VM, including the official PowerDNS repository for the rec 53 branch.
  • Monitor cache and query rates. Use rec_control get-all or the REST API metrics to watch query volume, cache hit ratio and servfail rates.
12

Support and Licensing

PowerDNS Recursor is developed by PowerDNS.COM BV and distributed under the GNU General Public License version 2 (GPL-2.0) with an OpenSSL linking exception (see the upstream NOTICE file). This SecureAnyCloud image bundles the unmodified official PowerDNS packages. SecureAnyCloud provides the packaging, the secure-by-default configuration, the per-instance credential automation, and 24/7 support with a 24-hour response SLA.

SecureAnyCloud is not affiliated with or endorsed by PowerDNS.COM BV. PowerDNS is a mark of its respective owner and is used here only to identify the software.

Deploy on Azure

Find PowerDNS Recursor on Ubuntu 24.04 LTS on the Azure Marketplace, published by SecureAnyCloud. Deploy from the portal or the Azure CLI as shown above.

Need Help?

Email sales@secureanycloud.com for deployment help, configuration questions, or licensing enquiries.

Deploy on Azure

Launch PowerDNS Recursor 5.3 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure