A split-horizon home resolver.
dnscrypt-proxy is the client-facing resolver: it
forwards the local zone (and reverse lookups) to pdns, and sends everything
else out over DNSCrypt/DoH to public resolvers.
PowerDNS is the authoritative server for that local zone, backed by MariaDB here.
PowerDNS-Admin is a web interface for managing its zones and records.
The files for this example are on Github.
| Service | Role | Static IP |
|---|---|---|
mariadb |
Backing database for pdns and pdns-admin. |
- |
dnscrypt-proxy |
Resolver clients point at; forwards the zone to pdns. |
10.1.2.2 |
pdns |
PowerDNS authoritative server for the ${ZONE} zone. |
10.1.2.5 |
pdns-admin |
Web UI for managing pdns zones and records. |
10.1.2.6 |
flowchart TD
C[a client on your network] --> DP["dnscrypt-proxy<br/>10.1.2.2"]
DP -->|the local zone| P["pdns<br/>10.1.2.5"]
DP -->|everything else| PUB["public resolvers<br/>over DNSCrypt / DoH"]
P --> DB[(mariadb)]
ADM["pdns-admin<br/>10.1.2.6"] --> DB
The three addressable services attach to the pre-existing incusbr0:
compose.incus.yaml marks the default network external: true and names it,
so incus-compose never creates or deletes it. The addresses, netmask and gateway
all come from .env.
compose.incus.yaml also clears the published ports of pdns and pdns-admin
with ports: !reset []. On Incus each service has an address of its own, so
nothing needs to be forwarded from the host.
Database credentials are passed as Compose secrets sourced from environment
variables; all values come from .env.
Copy .env.sample to .env and update it for your needs, in particular the
passwords and API_KEY - the placeholder values are rejected by install.sh -
and the *_IPV4_ADDRESS settings for your network.
cp .env.sample .env
$EDITOR .env
./install.sh
install.sh is a one-shot setup script, not meant to be re-run: it renders
pdns/pdns.conf and dnscrypt-proxy/forwarding-rules.txt from their templates,
pulls the PowerDNS schema out of the pdns image, imports it into MariaDB,
creates the pdns-admin database, creates the DNS zone, and finally brings up
the full project.
After that, use incus-compose down and incus-compose up normally.
10.1.2.2 (dnscrypt-proxy)./admin/setting/authentication#local right after creating your account.https://10.1.2.5:8081 with the
API_KEY from .env. That endpoint is what pdns.conf turns on with
api=yes and webserver-port=8081.ZONE in .env (lan by default) and is baked into
dnscrypt-proxy/forwarding-rules.txt by install.sh, so changing it means
re-rendering that file.pdns starts only once mariadb reports healthy, and dnscrypt-proxy and
pdns-admin only once pdns does. Those depends_on: service_healthy waits
and the restart: unless-stopped policies are enforced by the
ic-healthd sidecar.pdns/pdns.conf and dnscrypt-proxy/forwarding-rules.txt are generated from
their .template files by install.sh and are gitignored, along with .env
and work/.