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.