dnz forwarding … and dnz settings …, or through
PUT /api/settings/resolver. Changes apply right away, without a restart.
Until an option is saved in the dashboard or with dnz, its value comes from the
config file or the environment:
/etc/dnz/dnz.toml
Serve-stale
On by default (RFC 8767). When every upstream fails (times out, is unreachable, or answers SERVFAIL or REFUSED), DNZ answers from the expired cache entry instead of SERVFAIL, as long as it expired less than the stale window ago (default 1 day, at most 7 days).- Stale answers carry a TTL of 30 seconds, so clients ask again soon, and the extended DNS error Stale Answer (RFC 8914) for clients that send EDNS.
- After the upstreams failed for a name, the next 30 seconds of queries for it get the stale answer straight away instead of each waiting for the upstreams to time out again.
- ALIAS records whose target is outside your zones are served stale the same way.
- They show up in the query log with the source stale.
- Expired entries count toward
dns.cache_size; a full cache drops them before live ones.
- Dashboard
- CLI
In DNS → Forwarding, turn Serve stale answers on or off and pick how long after expiry,
then Save.
Prefetch
On by default. A name asked at least N times (default 3) since it was cached is refreshed in the background when a client asks for it in the last tenth of its TTL: the client gets the cached answer right away, and the cache gets a fresh copy before the old one expires. There is one refresh per name at a time, answers with a TTL under 10 seconds are left alone, and the count starts over with every fresh copy.EDNS Client Subnet
Off by default (RFC 7871). Without it, upstreams only see DNZ’s address, so CDNs pick servers near DNZ rather than near the client. When DNZ serves clients in other places (branch offices over a VPN, several regions), turn it on: upstreams then get the first 24 bits of an IPv4 client’s address or the first 56 bits of an IPv6 one, never the whole address.- Private and loopback clients are left out unless you ask for them: their addresses mean nothing on the internet. A network whose clients all sit behind NAT gains nothing from ECS.
- A client that sends its own ECS option (another resolver in front of DNZ) is honored, cut to the lengths above; a source prefix of 0 opts out. Its reply carries the option back with the scope.
- Answers are cached by the scope the upstream returns: an answer for
198.51.0.0/16is reused for every client in it, one with scope 0 for every client. - An upstream that rejects the option (FORMERR) is asked again without it.
- It applies to the default upstreams and every forwarding rule. Changing it empties the cache.
Privacy-focused resolvers such as Cloudflare
1.1.1.1 ignore ECS on purpose; Google Public DNS
uses it.- Dashboard
- CLI
In DNS → Forwarding, turn Client subnet (ECS) on, set the prefix lengths, and Save.
dig @dns.example.com www.google.com +subnet=198.51.100.0/24: the CLIENT-SUBNET
line of the reply shows the scope.
DNS64
Off by default (RFC 6147). For IPv6-only networks whose way to the IPv4 internet is a NAT64 gateway (Jool, Tayga, a router or firewall with NAT64): when a client asks for the AAAA of a name that only has IPv4 addresses, DNZ answers with IPv6 addresses made from them under the NAT64 prefix, and the gateway turns connections to them into IPv4.- Prefix: the one your gateway translates, by default the well-known
64:ff9b::/96. Lengths 32, 40, 48, 56, 64 and 96 are allowed (RFC 6052). The well-known prefix only stands for public IPv4 addresses, so give the gateway a prefix of your own (e.g.2001:db8:64::/96) to reach private ones. - Client networks: only these clients get synthesized answers; empty means every client.
- It works for names in your zones and forwarded names. Names with a real AAAA record are left alone; synthesized records keep the A record’s TTL, capped by the negative answer’s SOA minimum.
- Reverse lookups of a synthesized address are answered with a CNAME to the IPv4 address’s
in-addr.arpaname and its PTR, sodig -xworks. - Clients that check DNSSEC themselves (DO and CD set) get the real answer.
- Dashboard
- CLI
In Settings → General, turn DNS64 on, enter the prefix and the client networks, and
Save.
dig AAAA ipv4only.arpa returns 64:ff9b::c000:aa and
64:ff9b::c000:ab with the well-known prefix.
DNS cookies
On by default (RFC 7873, RFC 9018). A client that sends a cookie (BIND’sdig, Unbound, Knot
Resolver and recent stub resolvers do) gets a server cookie back, made with a secret that changes
every hour.
- A query that returns a valid server cookie has proven its address, so the per-client UDP
rate limit (
dns.rate_limit) never slows or drops it. - When the rate limit would send a truncated reply to a client with a cookie, it gets BADCOOKIE with a fresh server cookie instead, and its retry goes through.
- DNZ doesn’t send cookies to its upstreams; use encrypted upstreams to protect that side.
NSID
Off by default (RFC 5001). With NSID on, a client that asks learns which server answered, which helps behind anycast, a load balancer, or with several DNZ servers sharing a name. The default text is the hostname; any text up to 128 bytes works.API
GET /api/settings/resolver returns every group; PUT takes the groups to change, each replaced
whole. A superadmin sign-in is needed, and every change is in the audit log as
settings.resolver.