Access control and blocking
Who may query, how fast, and which names never resolve.
Who may query
accesslist = ["127.0.0.1/32", "::1/128", "192.168.0.0/16"]
CIDR ranges allowed to query this resolver. Queries from anywhere else are refused before any resolution work happens — the access list runs near the front of the middleware chain, ahead of the cache and the resolver.
The shipped default is ["0.0.0.0/0", "::0/0"], which allows everyone. That is
right for a resolver on loopback and wrong for one on a public address. An open
recursive resolver on the internet will be found and used for reflection
attacks, so narrow this before you bind to a reachable address.
Watch dns_accesslist_denied_total to see whether anything is being refused.
Rate limits
ratelimit = 0 # queries per second, whole server; 0 disables
clientratelimit = 0 # queries per minute, per client IP; 0 disables
Both are off by default. clientratelimit is the more useful of the two on a
resolver serving known clients — it contains one misbehaving host without
capping the server. ratelimit is a blunt ceiling on everything.
Refusals increment dns_ratelimit_exceeded_total.
Reflection and amplification defence
reflexenabled = false
reflexblockmode = true
reflexlearningmode = false
# reflexthreshold = 0.7
Tracks per-IP behaviour to identify spoofed sources being used for reflection. Off by default.
The two modes matter. With reflexlearningmode = true detections are logged and
nothing is blocked, which is how you calibrate the threshold against your own
traffic. reflexblockmode = false also only logs. Turn on blocking after you
have watched the detections for a while and are satisfied they are not your own
clients — the threshold is a score between 0 and 1, and lower is more aggressive.
Blocking names
blocklists = [
"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
]
blocklist = ["ads.example.com"]
whitelist = ["important.example.com"]
nullroute = "0.0.0.0"
nullroutev6 = "::0"
blocklists are URLs downloaded and refreshed periodically; blocklist is a
manual list in the configuration file; whitelist bypasses all blocking and
wins over both. A blocked A query answers nullroute and a blocked AAAA answers
nullroutev6.
Entries can also be managed at runtime through the API without a restart:
curl http://127.0.0.1:8080/api/v1/block/set/ads.example.com
curl http://127.0.0.1:8080/api/v1/block/exists/ads.example.com
curl http://127.0.0.1:8080/api/v1/block/remove/ads.example.com
For policy that goes beyond a name list — rewriting to a CNAME, matching on the client’s address or on the address in the answer, vendor feeds over AXFR, or a shadow mode that counts what enforcement would do — use Response Policy Zones instead. RPZ runs after the blocklist in the chain and is the richer of the two.
blocklistdir is deprecated; the directory is created under directory
automatically.
Local answers from a hosts file
hostsfile = "/etc/hosts"
Serves entries from a hosts file directly. Empty disables it. For answers scoped to particular client networks rather than served to everyone, use views.
Per-domain metrics
domainmetrics = false
domainmetricslimit = 1000
Tracks query counts per domain, exported as dns_domain_queries_total. Off by
default because the cardinality is unbounded on a public resolver — that is
what the limit is for. 0 means unlimited, which on a busy resolver will
consume memory until something gives.