PowerDNS Recursor 5.4.7 with dnsdist 2.1.3 on AWS User Guide
Overview
This guide covers launching and verifying PowerDNS Recursor 5.4.7 with dnsdist 2.1.3 on Ubuntu 24.04 from cloudimg on Amazon EC2. It is one version of the cloudimg Hardened Pi-hole, AdGuard Home & DNS Server AMIs listing on AWS Marketplace; you pick it as the software version when you subscribe and launch. The other DNS and time servers in the listing are described on the listing's guide hub.
The image is a two-daemon DNS appliance built from two open source projects by PowerDNS.COM BV:
- PowerDNS Recursor 5.4.7 is the recursive resolver. It resolves names for your clients by walking the DNS from the root servers, validates DNSSEC signatures and caches the results.
- dnsdist 2.1.3 is the DNS load balancer in front of it. It serves your clients over plain DNS, DNS-over-TLS and DNS-over-HTTPS, enforces the client access list and shows live traffic in a web dashboard.
Both are installed from the official PowerDNS repositories (repo.powerdns.com, release lines rec-54 and dnsdist-21). The repository signing key is pinned by its full fingerprint, and unattended upgrades keep the operating system and both release lines patched on your instance.
How the two daemons fit together
clients --> plain DNS :53 (udp + tcp) --+
clients --> DNS-over-TLS :853 --+--> dnsdist 2.1.3 --> PowerDNS Recursor 5.4.7
clients --> DNS-over-HTTPS :443/dns-query --+ 0.0.0.0 127.0.0.1:5300 (loopback only)
dnsdist is the only daemon on a routable address. The Recursor listens on loopback and answers 127.0.0.0/8 only, so it cannot be reached from the network even if the dnsdist access list is later widened by mistake.
What is on the image:
- PowerDNS Recursor 5.4.7 (
pdns-recursor.service, userpdns) and dnsdist 2.1.3 (dnsdist.service, user_dnsdist) - DNSSEC validation on: bogus answers get
SERVFAIL - Three client transports from one instance: plain DNS on 53 (UDP and TCP), DNS-over-TLS on 853 and DNS-over-HTTPS on 443 at
/dns-query, both TLS 1.2 or newer with a certificate created on your instance's first boot - A not an open resolver access list: loopback, the RFC 1918 private ranges,
100.64.0.0/10and IPv6 ULA/link-local only - The dnsdist web dashboard and REST API, the dnsdist console and the Recursor REST API, all on
127.0.0.1with per-instance credentials digandkdigfor testing all three transports, and a self-test,/usr/local/sbin/powerdns-dnsdist-selftest.sh
Default user: ubuntu · Architecture: x86_64 · Root volume: 8 GiB gp3
Security posture
- Not an open resolver. dnsdist listens on every interface so clients in your VPC can reach it, but its access list admits only
127.0.0.0/8,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10,fd00::/8andfe80::/10. Queries from any other source are dropped without an answer, over plain DNS, DNS-over-TLS and DNS-over-HTTPS alike. Open resolvers are abused for DNS amplification attacks, so this one answers private networks only. - The listing security group opens SSH only. DNS (53, UDP and TCP), DNS-over-TLS (853/tcp) and DNS-over-HTTPS (443/tcp) stay closed until you open them to your own VPC or VPN ranges. Clients use the instance's private IP.
- No default credentials. The image ships no key, password or certificate. On first boot each instance generates its own dnsdist console key, dashboard password and REST API key, Recursor REST API key and webserver password, and DNS-over-TLS/HTTPS key and certificate. They are stored in root-only files.
- Fails closed. Both daemons are gated on those per-instance files, and a start-time guard refuses to start them if a secret is missing, too short or a published example, if the access list admits the world, or if a management interface is not on loopback. If first boot cannot finish, it stops both daemons and tries again on the next boot.
- Management on loopback only. The dnsdist console (5199), the dnsdist dashboard and API (8083) and the Recursor API (8082) listen on
127.0.0.1. Reach the dashboards through an SSH tunnel. - No metadata access for the daemons. The Recursor can fetch zones from URLs and dnsdist can forward to remote servers, so both
pdns-recursor.serviceanddnsdist.serviceare blocked from reaching the instance metadata service (169.254.169.254 and fd00:ec2::254). Amazon Time Sync (169.254.169.123) still works. - IMDSv2 required. The AMI is registered with
ImdsSupport v2.0, so instances launched from it refuse token-less (IMDSv1) metadata requests. - Per-instance identity. SSH host keys and the machine ID are generated fresh on every instance.
Prerequisites
- An AWS account and permission to launch EC2 instances
- An EC2 key pair in the Region you launch in
- A VPC subnet for the resolver, and the CIDR ranges of the clients that will use it
Recommended instance type: m5.large. A resolver for a small network runs comfortably on t3.small or larger.
Connecting to your instance
| Version | Operating system | SSH user |
|---|---|---|
| PowerDNS Recursor 5.4.7 + dnsdist on Ubuntu 24.04 | Ubuntu 24.04 LTS | ubuntu |
Step 1: Launch the instance
Option A: AWS Marketplace console
- Open the cloudimg Hardened Pi-hole, AdGuard Home & DNS Server AMIs listing on AWS Marketplace and choose View purchase options, then Subscribe. One subscription covers every version in the listing.
- Once the subscription is active, choose Launch your software.
- Choose One-click launch from AWS Marketplace (or Launch from EC2 Console for the full launch wizard). In Version, choose PowerDNS Recursor 5.4.7 + dnsdist on Ubuntu 24.04, then choose your Region.
- Pick an instance type (
m5.largerecommended; the software charge is $0.04 per vCPU per hour) and your key pair. - Security group: the listing's default group allows SSH (22) only. Restrict it to your own IP address. You open the DNS ports to your clients in Step 4.
- Choose your VPC and subnet, leave the metadata defaults (the image already requires IMDSv2), then choose Launch.
Option B: AWS CLI
Run this on your own workstation. It creates a security group that allows SSH from your management address and the three DNS transports from your VPC, then launches the instance. Replace the AMI ID with the one shown for your Region on the Marketplace launch page, and the VPC, subnet, key pair and CIDR ranges with your own:
SG=$(aws ec2 create-security-group --group-name powerdns-resolver \
--description "PowerDNS Recursor + dnsdist" --vpc-id vpc-0123456789abcdef0 \
--query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 22 --cidr <your-mgmt-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol udp --port 53 --cidr 10.0.0.0/16
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 53 --cidr 10.0.0.0/16
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 853 --cidr 10.0.0.0/16
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 443 --cidr 10.0.0.0/16
aws ec2 run-instances \
--image-id ami-0123456789abcdef0 \
--instance-type m5.large \
--key-name my-key-pair \
--security-group-ids "$SG" \
--subnet-id subnet-0123456789abcdef0 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=powerdns-resolver}]'
You do not need --metadata-options: the AMI already makes IMDSv2 required.
Step 2: Connect and find your credentials
Connect as ubuntu with the key pair you chose:
ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>
First boot finishes within a minute of launch. It creates this instance's secrets and certificate, starts both daemons, proves all three transports answer, and writes /root/powerdns-recursor-dnsdist-credentials.txt (mode 0600, root only). Read it with sudo cat; the listing below hides the secret values so they do not appear in this guide:
sudo stat -c '%a %U:%G %n' /root/powerdns-recursor-dnsdist-credentials.txt
sudo sed -E 's/^([a-z.]+\.(key|password))=.*/\1=<hidden>/' /root/powerdns-recursor-dnsdist-credentials.txt | grep -E '^[a-z]'
600 root:root /root/powerdns-recursor-dnsdist-credentials.txt
dnsdist.console.key=<hidden>
dnsdist.webserver.password=<hidden>
dnsdist.api.key=<hidden>
dnsdist.webserver.url=http://127.0.0.1:8083/
dnsdist.tls.certificate=/etc/dnsdist/tls/dnsdist.crt
dnsdist.tls.fingerprint.sha256=F0:B5:F7:ED:D8:61:AE:04:A7:16:9C:0D:8E:3F:62:B4:5E:EE:C6:48:6A:F3:59:D5:3D:4E:26:70:DA:75:86:BE
dnsdist.tls.spki.pin.sha256=CqUUqZtNtZneO4qnawfQ8uFgE7pNAhxP576A+VMJxrQ=
powerdns.recursor.api.key=<hidden>
powerdns.recursor.webserver.password=<hidden>
powerdns.recursor.api.url=http://127.0.0.1:8082/api/v1/servers/localhost
appliance.private.ip=172.31.85.217
appliance.public.ip=3.83.157.82
| Entry | Used for |
|---|---|
dnsdist.console.key |
the dnsdist console, sudo dnsdist -c (read automatically from the configuration) |
dnsdist.webserver.password |
the dnsdist web dashboard (Step 8) |
dnsdist.api.key |
the dnsdist REST API (X-API-Key header) |
powerdns.recursor.api.key |
the Recursor REST API (X-API-Key header) |
powerdns.recursor.webserver.password |
the Recursor web dashboard (Step 8) |
dnsdist.tls.fingerprint.sha256, dnsdist.tls.spki.pin.sha256 |
identifying this instance's DNS-over-TLS/HTTPS certificate (Step 7) |
Step 3: Confirm both daemons are running
Both daemons and the first-boot unit are active, and the self-test checks the versions, every per-instance credential (a wrong key gets 401, the right one 200), all three transports with this instance's certificate verified, the access list, and the exact set of listening ports:
systemctl is-active pdns-recursor.service dnsdist.service powerdns-recursor-dnsdist-firstboot.service
pdns_recursor --version 2>&1 | head -1
dnsdist --version | head -1
sudo /usr/local/sbin/powerdns-dnsdist-selftest.sh
active
active
active
PowerDNS Recursor 5.4.7 (C) PowerDNS.COM BV
dnsdist 2.1.3 (Lua 5.1.4 [LuaJIT 2.1.1703358377])
[pdns-dnsdist-selftest] versions: PowerDNS Recursor 5.4.7, dnsdist 2.1.3
[pdns-dnsdist-selftest] per-instance API keys and dashboard password authenticate; wrong ones get 401
[pdns-dnsdist-selftest] plain DNS, DoT and DoH (certificate verified) answer on 127.0.0.1 and 172.31.85.217; recursion resolves example.com
[pdns-dnsdist-selftest] not an open resolver: 192.0.2.53 got no answer on udp/53, tcp/53, DoT and DoH (HTTP 000); acl-drops 12 -> 16
[pdns-dnsdist-selftest] listening set OK (tcp: 22 53 443 853 ; udp: 53 68 ); recursor + management on 127.0.0.1 only
PDNS_DNSDIST_SELFTEST_OK

Step 4: Open the resolver to your clients
The listing's security group allows SSH only. To serve DNS, add inbound rules to the instance's security group from your own VPC or VPN CIDR ranges only, never from 0.0.0.0/0:
| Protocol | Port | Source | Purpose |
|---|---|---|---|
| UDP | 53 | your VPC / VPN CIDRs | DNS |
| TCP | 53 | your VPC / VPN CIDRs | DNS (large answers) |
| TCP | 853 | your VPC / VPN CIDRs | DNS-over-TLS |
| TCP | 443 | your VPC / VPN CIDRs | DNS-over-HTTPS |
In the EC2 console choose the instance, open Security, choose the security group, then Edit inbound rules. Point clients at the instance's private IP (appliance.private.ip in Step 2). These are the only ports the instance listens on; everything except SSH and the three DNS transports is on 127.0.0.1:
sudo ss -Hltnu | awk '{print $1, $5}' | sort -u
tcp 0.0.0.0:22
tcp 0.0.0.0:443
tcp 0.0.0.0:53
tcp 0.0.0.0:853
tcp 127.0.0.1:5199
tcp 127.0.0.1:5300
tcp 127.0.0.1:8082
tcp 127.0.0.1:8083
tcp [::]:22
tcp [::]:53
udp 0.0.0.0:53
udp 127.0.0.1:323
udp 127.0.0.1:5300
udp 172.31.85.217%ens5:68
udp [::1]:323
udp [::]:53
Port 5300 is the Recursor (dnsdist is its only client), 5199 the dnsdist console, 8083 the dnsdist dashboard and API, 8082 the Recursor API, 323 chrony's local control socket and 68 the DHCP client.
From a client inside your VPC, test the resolver against its private IP:
dig @<private-ip> +dnssec example.com
To make clients use the resolver permanently, set its private IP as the DNS server in a DHCP options set for the VPC, or on each client's network configuration.
Step 5: Query over plain DNS, DNS-over-TLS and DNS-over-HTTPS
The same signed name over all three transports. The ad (Authenticated Data) flag shows the Recursor validated the DNSSEC signatures. kdig verifies the server certificate against this instance's certificate file (+tls-ca); it runs with sudo only because the certificate sits in the root-only /etc/dnsdist/tls/ directory next to the private key:
dig @127.0.0.1 +dnssec nlnetlabs.nl A | grep -E "status|flags:|^nlnetlabs.*IN.A|SERVER"
sudo kdig +tls +tls-ca=/etc/dnsdist/tls/dnsdist.crt +tls-hostname=127.0.0.1 @127.0.0.1 -p 853 +dnssec nlnetlabs.nl A | grep -E "TLS session|status|Flags|IN.A|From"
sudo kdig +https +tls-ca=/etc/dnsdist/tls/dnsdist.crt +tls-hostname=127.0.0.1 @127.0.0.1 +dnssec nlnetlabs.nl A | grep -E "TLS session|HTTP session|status|Flags|IN.A|From"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26770
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
; EDNS: version: 0, flags: do; udp: 512
nlnetlabs.nl. 54 IN A 128.140.76.106
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; TLS session (TLS1.3)-(ECDHE-SECP256R1)-(ECDSA-SECP256R1-SHA256)-(AES-256-GCM)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 8965
;; Flags: qr rd ra ad; QUERY: 1; ANSWER: 2; AUTHORITY: 0; ADDITIONAL: 1
;; nlnetlabs.nl. IN A
nlnetlabs.nl. 54 IN A 128.140.76.106
;; From 127.0.0.1@853(TLS) in 2.5 ms
;; TLS session (TLS1.3)-(ECDHE-SECP256R1)-(ECDSA-SECP256R1-SHA256)-(AES-256-GCM)
;; HTTP session (HTTP/2-POST)-(127.0.0.1/dns-query)-(status: 200)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 0
;; Flags: qr rd ra ad; QUERY: 1; ANSWER: 2; AUTHORITY: 0; ADDITIONAL: 1
;; nlnetlabs.nl. IN A
nlnetlabs.nl. 54 IN A 128.140.76.106
;; From 127.0.0.1@443(HTTPS) in 2.6 ms
From a client in your VPC, copy the certificate (/etc/dnsdist/tls/dnsdist.crt, which is public) to the client and use the private IP, for example kdig +tls +tls-ca=dnsdist.crt +tls-hostname=<private-ip> @<private-ip> -p 853 example.com. DNS-over-HTTPS clients use the URL https://<private-ip>/dns-query.
Step 6: Confirm DNSSEC rejects bad data
dnssec-failed.org is a public test domain whose signatures are deliberately broken. A validating resolver must answer SERVFAIL rather than pass the data on. Validation is set to validate in the Recursor configuration:
dig @127.0.0.1 dnssec-failed.org A | grep -E "status"
grep -A3 '^dnssec:' /etc/powerdns/recursor.d/cloudimg-recursor.yml
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 16022
dnssec:
# Validate DNSSEC-signed answers (bogus answers get SERVFAIL).
validation: validate
recursor:

Step 7: The DNS-over-TLS and DNS-over-HTTPS certificate
The certificate is self-signed and was created on this instance's first boot, with the instance's private IP, private DNS name, public IP and public DNS name in its Subject Alternative Names. The private key is readable only by root and the _dnsdist group:
sudo openssl x509 -in /etc/dnsdist/tls/dnsdist.crt -noout -subject -dates -ext subjectAltName -fingerprint -sha256
sudo stat -c '%a %U:%G %n' /etc/dnsdist/tls/dnsdist.key /etc/dnsdist/tls/dnsdist.crt
subject=CN = 172.31.85.217, O = cloudimg PowerDNS Recursor with dnsdist
notBefore=Oct 20 21:17:39 2026 GMT
notAfter=Oct 17 21:17:39 2036 GMT
X509v3 Subject Alternative Name:
DNS:localhost, IP Address:127.0.0.1, IP Address:172.31.85.217, DNS:ip-172-31-85-217.ec2.internal, IP Address:3.83.157.82, DNS:ec2-3-83-157-82.compute-1.amazonaws.com
sha256 Fingerprint=F0:B5:F7:ED:D8:61:AE:04:A7:16:9C:0D:8E:3F:62:B4:5E:EE:C6:48:6A:F3:59:D5:3D:4E:26:70:DA:75:86:BE
640 root:_dnsdist /etc/dnsdist/tls/dnsdist.key
644 root:_dnsdist /etc/dnsdist/tls/dnsdist.crt
Configure clients to trust it explicitly:
- Pin the public key. Clients such as Stubby accept an SPKI pin. Use
dnsdist.tls.spki.pin.sha256from the credentials file, with the private IP as the authentication name. - Or trust the certificate. Copy
/etc/dnsdist/tls/dnsdist.crtto the client and add it to the client's trust store or pass it as the CA file.
To use a certificate from your own certificate authority instead, replace the two files (keep the key 0640 root:_dnsdist) and restart dnsdist:
sudo cp my-server.crt /etc/dnsdist/tls/dnsdist.crt
sudo cp my-server.key /etc/dnsdist/tls/dnsdist.key
sudo chown root:_dnsdist /etc/dnsdist/tls/dnsdist.crt /etc/dnsdist/tls/dnsdist.key
sudo chmod 0640 /etc/dnsdist/tls/dnsdist.key
sudo systemctl restart dnsdist
Step 8: Open the dashboards
dnsdist and the Recursor each serve a web dashboard on 127.0.0.1. Open an SSH tunnel from your workstation, then browse to the forwarded ports:
ssh -i ~/.ssh/my-key-pair.pem -L 8083:127.0.0.1:8083 -L 8082:127.0.0.1:8082 ubuntu@<public-ip>
- dnsdist:
http://127.0.0.1:8083/, useradmin, passworddnsdist.webserver.passwordfrom Step 2. It shows the query rate, latency per transport, the listeners and access list, the Recursor backend and its health, and the active rules, including the per-client rate limit.

- PowerDNS Recursor:
http://127.0.0.1:8082/, useradmin, passwordpowerdns.recursor.webserver.password. It shows the resolver's query rate, cache hit rate and the most-queried names.

Further down, the Recursor lists the names whose DNSSEC validation failed, such as dnssec-failed.org from Step 6:

Step 9: Confirm it is not an open resolver
The access list is the setACL block in /etc/dnsdist/dnsdist.conf:
sed -n '/^setACL/,/^})/p' /etc/dnsdist/dnsdist.conf
setACL({
'127.0.0.0/8',
'::1/128',
'10.0.0.0/8',
'172.16.0.0/12',
'192.168.0.0/16',
'100.64.0.0/10',
'fd00::/8',
'fe80::/10',
})
You can prove the policy from the instance itself. This adds a temporary public test address (192.0.2.53, from the TEST-NET-1 documentation range) to the loopback interface, sends a query from it to the private IP over DNS and over DNS-over-TLS, sends the same query from the private IP itself, removes the test address and reads dnsdist's acl-drops counter. The public source gets no answer at all; the private one is answered:
PRIV=$(hostname -I | awk '{print $1}')
sudo ip addr add 192.0.2.53/32 dev lo
dig +time=2 +tries=1 -b 192.0.2.53 @"$PRIV" nlnetlabs.nl A | grep -E "status|timed out" || true
sudo kdig +tls +tls-ca=/etc/dnsdist/tls/dnsdist.crt +tls-hostname="$PRIV" +timeout=2 +retry=0 -b 192.0.2.53 @"$PRIV" -p 853 nlnetlabs.nl A 2>&1 | grep -E "status|WARNING|ERROR" || true
dig +time=2 +tries=1 -b "$PRIV" @"$PRIV" nlnetlabs.nl A | grep -oE "status: [A-Z]+"
sudo ip addr del 192.0.2.53/32 dev lo
sudo dnsdist -c -e 'dumpStats()' | grep -oE 'acl-drops[[:space:]]+[0-9]+'
;; communications error to 172.31.85.217#53: timed out
;; WARNING: TLS, handshake failed (Error in the pull function.)
;; ERROR: failed to query server 172.31.85.217@853(TCP)
status: NOERROR
acl-drops 19

Step 10: Allow another of your own networks (optional)
To serve a network outside the private ranges, for example a VPN range that uses public addresses, add it inside the setACL({ ... }) block of /etc/dnsdist/dnsdist.conf, check the configuration and restart dnsdist. Replace 198.51.100.0/24 with your own range:
sudoedit /etc/dnsdist/dnsdist.conf # add '198.51.100.0/24', inside setACL({ ... })
sudo dnsdist --check-config
sudo systemctl restart dnsdist
Never add 0.0.0.0/0 or ::/0: that turns the instance into an open resolver, and the start-time guard refuses to start dnsdist with it. Remember to allow the same range in the security group (Step 4).
Step 11: Metadata access is blocked for both daemons
pdns-recursor.service and dnsdist.service each carry a systemd IPAddressDeny rule for the instance metadata addresses. Each entry is a single address, so the Amazon Time Sync Service at 169.254.169.123 and the Amazon VPC resolver keep working, as chrony shows:
systemctl show -p IPAddressDeny pdns-recursor.service dnsdist.service
chronyc -n sources | grep 169.254
IPAddressDeny=169.254.169.254/32 168.63.129.16/32 fd00:ec2::254/128
IPAddressDeny=169.254.169.254/32 168.63.129.16/32 fd00:ec2::254/128
^* 169.254.169.123 3 4 377 9 -1782ns[-2585ns] +/- 390us
The Recursor sends its own queries over IPv4 (outgoing.source_address: 0.0.0.0 in /etc/powerdns/recursor.d/cloudimg-recursor.yml), which suits the many EC2 subnets that have no IPv6 route. On a dual-stack subnet, add - '::' under source_address and restart the Recursor to also query over IPv6.
Step 12: Day-to-day operations
sudo dnsdist -c opens the dnsdist console (it reads the console key from the configuration), and rec_control talks to the Recursor over its local control socket:
sudo dnsdist -c -e 'showServers()'
sudo rec_control get-all | grep -E '^(questions|cache-hits|packetcache-hits|cache-entries)'
# Name Address State Qps Qlim Ord Wt Queries Drops Drate Lat TCP Outstanding Pools
0 powerdns-recursor 127.0.0.1:5300 up 0.0 0 1 1 48 0 0.0 2.8 0.0 0
All 0.0 48 0
cache-entries 135
cache-hits 10
packetcache-hits 233
questions 247
Other common commands:
sudo rec_control wipe-cache example.com$ # drop one name (and everything under it) from the cache
sudo rec_control reload-zones # re-read forward zones after editing them
sudo dnsdist -c -e 'topQueries(10)' # the ten most-queried names in dnsdist's ring buffer
sudo systemctl restart dnsdist pdns-recursor # after a configuration change
The Recursor's configuration lives in /etc/powerdns/recursor.d/ (YAML) and dnsdist's in /etc/dnsdist/dnsdist.conf (Lua). The per-instance secrets are in separate root-only files next to them (cloudimg-secrets.yml and cloudimg-secrets.conf); leave those in place.
Step 13: Security recommendations
- Keep the security group tight. Open 53, 853 and 443 only to the networks that need the resolver, and SSH only to your management address.
- Keep the access list scoped. Only add networks you trust (Step 10), never
0.0.0.0/0. The access list is a second layer of defence behind the security group. - Leave DNSSEC validation on. It protects your clients from spoofed or tampered answers.
- Prefer DNS-over-TLS or DNS-over-HTTPS for clients that support them, so queries cannot be read or altered on the network.
- Keep the dashboards on loopback. Reach them through an SSH tunnel; the credentials file is root-only for a reason.
- Keep the software patched. Unattended upgrades apply Ubuntu security updates and the PowerDNS 5.4.x and dnsdist 2.1.x releases from
repo.powerdns.com.
Support and licensing
PowerDNS Recursor and dnsdist are developed by PowerDNS.COM BV and distributed under the GNU General Public License version 2. This image ships the unmodified packages from repo.powerdns.com. cloudimg provides the packaging, the not an open resolver defaults, DNSSEC validation, per-instance credentials and DNS-over-TLS/HTTPS certificate, the metadata block, and 24/7 support.
cloudimg is not affiliated with or endorsed by PowerDNS.COM BV. PowerDNS and dnsdist are marks of their owner and are used here only to identify the software.
For help with deployment or configuration, email support@cloudimg.co.uk or visit cloudimg support.