]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/README-dnsdist.md
Merge pull request #4346 from mind04/anytotcp
[thirdparty/pdns.git] / pdns / README-dnsdist.md
1 dnsdist
2 -------
3 `dnsdist` is a highly DNS-, DoS- and abuse-aware loadbalancer. Its goal in
4 life is to route traffic to the best server, delivering top performance
5 to legitimate users while shunting or blocking abusive traffic.
6
7 `dnsdist` is dynamic, in the sense that its configuration can be changed at
8 runtime, and that its statistics can be queried from a console-like
9 interface.
10
11 Compiling
12 ---------
13 `dnsdist` depends on boost, Lua or LuaJIT and a pretty recent C++
14 compiler (g++ 4.8 or higher, clang 3.5 or higher). It can optionally use libsodium
15 for encrypted communications with its client, protobuf for remote logging and re2
16 for regular expression matching.
17
18 Should `dnsdist` be run on a system with systemd, it is highly recommended to have
19 the systemd header files (`libsystemd-dev` on debian and `systemd-devel` on CentOS)
20 installed to have `dnsdist` support systemd-notify.
21
22 To compile on CentOS 6 / RHEL6, use this script to install a working compiler:
23
24 ```
25 wget -O /etc/yum.repos.d/slc6-devtoolset.repo http://linuxsoft.cern.ch/cern/devtoolset/slc6-devtoolset.repo
26 yum install devtoolset-2
27 scl enable devtoolset-2 bash
28 ./configure
29 make
30 ```
31
32 To build on OS X, `./configure LIBEDIT_LIBS='-L/usr/lib -ledit' LIBEDIT_CFLAGS=-I/usr/include/editline`
33
34 To build on OpenBSD, `./configure CXX=eg++ CPP=ecpp LIBEDIT_LIBS='-ledit -lcurses' LIBEDIT_CFLAGS=' '`
35
36 On other recent platforms, installing a Lua and the system C++ compiler should be enough.
37
38 `dnsdist` can drop privileges using the `--uid` and `--gid` commandline-switches
39 to ensure it does not run with root privileges after binding its listen-sockets.
40 It is highly recommended to create a system user and group for `dnsdist`. Note that
41 most packaged versions of `dnsdist` already create this user.
42
43 Packaged
44 --------
45 We build packages for `dnsdist` on our [repositories](https://repo.powerdns.com). In addition
46 `dnsdist` has been packaged for FreeBSD and can be found on https://freshports.org/dns/dnsdist
47
48 Examples
49 --------
50
51 The absolute minimum configuration:
52
53 ```
54 # dnsdist 2001:4860:4860::8888 8.8.8.8
55 ```
56
57 This will listen on 0.0.0.0:53 and forward queries to the two listed IP
58 addresses, with a sensible load balancing policy.
59
60 Here is a more complete configuration:
61
62 ```
63 $ cat /etc/dnsdist.conf
64 newServer({address="2001:4860:4860::8888", qps=1})
65 newServer({address="2001:4860:4860::8844", qps=1})
66 newServer({address="2620:0:ccc::2", qps=10})
67 newServer({address="2620:0:ccd::2", name="dns1", qps=10})
68 newServer("192.168.1.2")
69 setServerPolicy(firstAvailable) -- first server within its QPS limit
70
71 $ dnsdist --local=0.0.0.0:5200
72 Marking downstream [2001:4860:4860::8888]:53 as 'up'
73 Marking downstream [2001:4860:4860::8844]:53 as 'up'
74 Marking downstream [2620:0:ccc::2]:53 as 'up'
75 Marking downstream [2620:0:ccd::2]:53 as 'up'
76 Marking downstream 192.168.1.2:53 as 'up'
77 Listening on 0.0.0.0:5200
78 >
79 ```
80
81 We can now send queries to port 5200, and get answers:
82
83 ```
84 $ dig -t aaaa powerdns.com @127.0.0.1 -p 5200 +short
85 2001:888:2000:1d::2
86 ```
87
88 Note that `dnsdist` offered us a prompt above, and on it we can get some
89 statistics:
90
91 ```
92 > showServers()
93 # Address State Qps Qlim Ord Wt Queries Drops Drate Lat Pools
94 0 [2001:4860:4860::8888]:53 up 0.0 1 1 1 1 0 0.0 0.0
95 1 [2001:4860:4860::8844]:53 up 0.0 1 1 1 0 0 0.0 0.0
96 2 [2620:0:ccc::2]:53 up 0.0 10 1 1 0 0 0.0 0.0
97 3 [2620:0:ccd::2]:53 up 0.0 10 1 1 0 0 0.0 0.0
98 4 192.168.1.2:53 up 0.0 0 1 1 0 0 0.0 0.0
99 All 0.0 1 0
100 ```
101
102 Here we also see our configuration. 5 downstream servers have been configured, of
103 which the first 4 have a QPS limit (of 1, 1, 10 and 10 queries per second,
104 respectively). The final server has no limit, which we can easily test:
105
106 ```
107 $ for a in {0..1000}; do dig powerdns.com @127.0.0.1 -p 5200 +noall > /dev/null; done
108 > showServers()
109 # Address State Qps Qlim Ord Wt Queries Drops Drate Lat Pools
110 0 [2001:4860:4860::8888]:53 up 1.0 1 1 1 7 0 0.0 1.6
111 1 [2001:4860:4860::8844]:53 up 1.0 1 1 1 6 0 0.0 0.6
112 2 [2620:0:ccc::2]:53 up 10.3 10 1 1 64 0 0.0 2.4
113 3 [2620:0:ccd::2]:53 up 10.3 10 1 1 63 0 0.0 2.4
114 4 192.168.1.2:53 up 125.8 0 1 1 671 0 0.0 0.4
115 All 145.0 811 0
116 ```
117
118 Note that the first 4 servers were all limited to near their configured QPS,
119 and that our final server was taking up most of the traffic. No queries were
120 dropped, and all servers remain up.
121
122 To force a server down, try:
123
124 ```
125 > getServer(0):setDown()
126 > showServers()
127 # Address State Qps Qlim Ord Wt Queries Drops Drate Lat Pools
128 0 [2001:4860:4860::8888]:53 DOWN 0.0 1 1 1 8 0 0.0 0.0
129 ...
130 ```
131
132 The 'DOWN' in all caps means it was forced down. A lower case 'down'
133 would've meant that `dnsdist` itself had concluded the server was down.
134 Similarly, setUp() forces a server to be up, and setAuto() returns it to the
135 default availability-probing.
136
137 To change the QPS for a server:
138 ```
139 > getServer(0):setQPS(1000)
140 ```
141
142 By default, the availability of a downstream server is checked by regularly
143 sending an A query for "a.root-servers.net.". A different query type and target
144 can be specified by passing, respectively, the `checkType` and `checkName`
145 parameters to `newServer`. The default behavior is to consider any valid response
146 with a RCODE different from ServFail as valid. If the `mustResolve` parameter
147 of `newServer` is set to true, a response will only be considered valid if
148 its RCODE differs from NXDomain, ServFail and Refused.
149 The number of health check failures before a server is considered down is
150 configurable via the`maxCheckFailures` parameter, defaulting to 1.
151 The `CD` flag can be set on the query by setting `setCD` to true.
152
153 ```
154 newServer({address="192.0.2.1", checkType="AAAA", checkName="a.root-servers.net.", mustResolve=true})
155 ```
156
157 In order to provide the downstream server with the address of the real client,
158 or at least the one talking to `dnsdist`, the `useClientSubnet` parameter can be used
159 when declaring a new server. This parameter indicates whether an EDNS Client Subnet option
160 should be added to the request. If the incoming request already contains an EDNS Client Subnet value,
161 it will not be overriden unless `setECSOverride()` is set to true.
162 The default source prefix-length is 24 for IPv4 and 56 for IPv6, meaning that for a query
163 received from 192.0.2.42, the EDNS Client Subnet value sent to the backend will
164 be 192.0.2.0. This can be changed with:
165 ```
166 > setECSSourcePrefixV4(24)
167 > setECSSourcePrefixV6(56)
168 ```
169
170 TCP timeouts
171 ------------
172
173 By default, a 2 seconds timeout is enforced on the TCP connection from the client,
174 meaning that a connection will be closed if the query can't be read in less than 2s
175 or if the answer can't be sent in less than 2s. This can be configured with:
176 ```
177 > setTCPRecvTimeout(5)
178 > setTCPSendTimeout(5)
179 ```
180
181 The same kind of timeouts is enforced on the TCP connections to the downstream servers.
182 The default value of 30s can be modified by passing the `tcpRecvTimeout` and `tcpSendTimeout`
183 parameters to `newServer`. If the TCP connection to a downstream server fails, `dnsdist`
184 will try to establish a new one up to `retries` times before giving up.
185 ```
186 newServer({address="192.0.2.1", tcpRecvTimeout=10, tcpSendTimeout=10, retries=5})
187 ```
188
189 Source address
190 --------------
191
192 In multi-homed setups, it can be useful to be able to select the source address or the outgoing
193 interface used by `dnsdist` to contact a downstream server.
194 This can be done by using the `source` parameter:
195 ```
196 newServer({address="192.0.2.1", source="192.0.2.127"})
197 newServer({address="192.0.2.1", source="eth1"})
198 newServer({address="192.0.2.1", source="192.0.2.127@eth1"})
199 ```
200
201 The supported values for `source` are:
202
203 * an IPv4 or IPv6 address, which must exist on the system
204 * an interface name
205 * an IPv4 or IPv6 address followed by '@' then an interface name
206
207 Specifying the interface name is only supported on system having IP_PKTINFO.
208
209
210 Configuration management
211 ------------------------
212 At startup, configuration is read from the command line and the
213 configuration file. The config can also be inspected and changed from the
214 console. Sadly, our architecture does not allow us to serialize the running
215 configuration for you. However, we do try to offer the next best thing:
216 `delta()`.
217
218 `delta()` shows all commands entered that changed the configuration. So
219 adding a new downstream server with `newServer()` would show up, but
220 `showServers()` or even `delta()` itself would not.
221
222 It is suggested to study the output of `delta()` carefully before appending
223 it to your configuration file.
224
225 ```
226 > setACL("192.0.2.0/24")
227 > showACL()
228 192.0.2.0/24
229 > delta()
230 -- Wed Dec 23 2015 15:15:35 CET
231 setACL("192.0.2.0/24")
232 > addACL("127.0.0.1/8")
233 > showACL()
234 192.0.2.0/24
235 127.0.0.1/8
236 > delta()
237 -- Wed Dec 23 2015 15:15:35 CET
238 setACL("192.0.2.0/24")
239 -- Wed Dec 23 2015 15:15:44 CET
240 addACL("127.0.0.1/8")
241 >
242 ```
243
244
245 Webserver
246 ---------
247 To visually interact with `dnsdist`, try adding:
248 ```
249 webserver("127.0.0.1:8083", "supersecretpassword", "supersecretAPIkey")
250 ```
251
252 to the configuration, and point your browser at http://127.0.0.1:8083 and
253 log in with any username, and that password. Enjoy!
254
255 By default, our web server sends some security-related headers:
256
257 * X-Content-Type-Options: nosniff
258 * X-Frame-Options: deny
259 * X-Permitted-Cross-Domain-Policies: none
260 * X-XSS-Protection: 1; mode=block
261 * Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'
262
263 You can override those headers, or add custom headers by using the last parameter to
264 `webserver()`. For example, to remove the `X-Frame-Options` header and add a
265 `X-Custom` one:
266 ```
267 webserver("127.0.0.1:8080", "supersecret", "apikey", {["X-Frame-Options"]= "", ["X-Custom"]="custom"})
268 ```
269
270
271 Server pools
272 ------------
273 Now for some cool stuff. Let's say we know we're getting a whole bunch of
274 traffic for a domain used in DoS attacks, for example 'sh43354.cn'. We can
275 do two things with this kind of traffic. Either we block it outright, like
276 this:
277
278 ```
279 > addDomainBlock("sh43354.cn.")
280 ```
281
282 Or we configure a server pool dedicated to receiving the nasty stuff:
283
284 ```
285 > newServer({address="192.168.1.3", pool="abuse"})
286 > addPoolRule({"sh43353.cn.", "ezdns.it."}, "abuse")
287 ```
288
289 The wonderful thing about this last solution is that it can also be used for
290 things where a domain might possibly be legit, but it is still causing load
291 on the system and slowing down the internet for everyone. With such an abuse
292 server, 'bad traffic' still gets a chance of an answer, but without
293 impacting the rest of the world (too much).
294
295 We can similarly add clients to the abuse server:
296
297 ```
298 > addPoolRule({"192.168.12.0/24", "192.168.13.14"}, "abuse")
299 ```
300
301 To define a pool that should receive only a QPS-limited amount of traffic, do:
302
303 ```
304 > addQPSPoolRule("com.", 10000, "gtld-cluster")
305 ```
306
307 Traffic exceeding the QPS limit will not match that rule, and subsequent
308 rules will apply normally.
309
310 Both `addDomainBlock` and `addPoolRule` end up the list of Rules
311 and Actions (for which see below).
312
313 Servers can be added or removed to pools with:
314 ```
315 > getServer(7):addPool("abuse")
316 > getServer(4):rmPool("abuse")
317 ```
318
319
320 Rules
321 -----
322 Rules can be inspected with `showRules()`, and can be deleted with
323 `rmRule()`. Rules are evaluated in order, and this order can be changed
324 with `mvRule(from, to)` (see below for exact semantics).
325
326 Rules have selectors and actions. Current selectors are:
327
328 * Source address
329 * Query type
330 * Query domain
331 * QPS Limit total
332 * QPS Limit per IP address or subnet
333 * QClass (QClassRule)
334 * QType (QTypeRule)
335 * RegexRule on query name
336 * RE2Rule on query name (optional)
337 * Response code
338 * Packet requests DNSSEC processing
339 * Query received over UDP or TCP
340 * Opcode (OpcodeRule)
341 * Number of entries in a given section (RecordsCountRule)
342 * Number of entries of a specific type in a given section (RecordsTypeCountRule)
343 * Presence of trailing data (TrailingDataRule)
344 * Number of labels in the qname (QNameLabelsCountRule)
345 * Wire length of the qname (QNameWireLengthRule)
346
347 Special rules are:
348
349 * `AndRule{rule1, rule2}`, which only matches if all of its subrules match
350 * `OrRule{rule1, rule2}`, which matches if at least one of its subrules match
351 * `NotRule(rule)`, which matches if its subrule does not match
352
353 Current actions are:
354
355 * Drop (DropAction)
356 * Route to a pool (PoolAction)
357 * Return with TC=1 (truncated, ie, instruction to retry with TCP)
358 * Force a ServFail, NotImp or Refused answer
359 * Send out a crafted response (NXDOMAIN or "real" data)
360 * Delay a response by n milliseconds (DelayAction), over UDP only
361 * Modify query to clear the RD or CD bit
362 * Add the source MAC address to the query (MacAddrAction)
363 * Skip the cache, if any
364 * Log query content to a remote server (RemoteLogAction)
365
366 Current response actions are:
367
368 * Allow (AllowResponseAction)
369 * Delay a response by n milliseconds (DelayResponseAction), over UDP only
370 * Drop (DropResponseAction)
371 * Log response content to a remote server (RemoteLogResponseAction)
372
373 Rules can be added via:
374
375 * addAction(DNS rule, DNS Action)
376 * addAnyTCRule()
377 * addDelay(DNS rule, delay in milliseconds)
378 * addDisableValidationRule(DNS rule)
379 * addDomainBlock(domain)
380 * addDomainSpoof(domain, IPv4[, IPv6]) or addDomainSpoof(domain, {IP, IP, IP..})
381 * addDomainCNAMESpoof(domain, CNAME)
382 * addLuaAction(DNS rule, lua function)
383 * addNoRecurseRule(DNS rule)
384 * addPoolRule(DNS rule, destination pool)
385 * addQPSLimit(DNS rule, qps limit)
386 * addQPSPoolRule(DNS rule, qps limit, destination pool)
387
388 Response rules can be added via:
389
390 * addResponseAction(DNS rule, DNS Response Action)
391
392 A DNS rule can be:
393
394 * an AllRule
395 * an AndRule
396 * a MaxQPSIPRule
397 * a MaxQPSRule
398 * a NetmaskGroupRule
399 * a NotRule
400 * an OpcodeRule
401 * an OrRule
402 * a QClassRule
403 * a QNameLabelsCountRule
404 * a QNameWireLengthRule
405 * a QTypeRule
406 * a RCodeRule
407 * a RegexRule
408 * a RE2Rule
409 * a RecordsCountRule
410 * a RecordsTypeCountRule
411 * a SuffixMatchNodeRule
412 * a TCPRule
413 * a TrailingDataRule
414
415 Some specific actions do not stop the processing when they match, contrary to all other actions:
416
417 * Delay
418 * Disable Validation
419 * Log
420 * MacAddr
421 * No Recurse
422 * and of course None
423
424 A convenience function `makeRule()` is supplied which will make a NetmaskGroupRule for you or a SuffixMatchNodeRule
425 depending on how you call it. `makeRule("0.0.0.0/0")` will for example match all IPv4 traffic, `makeRule{"be","nl","lu"}` will
426 match all Benelux DNS traffic.
427
428 All the current rules can be removed at once with:
429
430 ```
431 > clearRules()
432 ```
433
434 It is also possible to replace the current rules by a list of new ones in a
435 single operation with `setRules()`:
436
437 ```
438 > setRules( { newRuleAction(TCPRule(), AllowAction()), newRuleAction(AllRule(), DropAction()) } )
439 ```
440
441
442 More power
443 ----------
444 More powerful things can be achieved by defining a function called
445 `blockFilter()` in the configuration file, which can decide to drop traffic
446 on any reason it wants. If you return 'true' from there, the query will get
447 blocked.
448
449 A demo on how to do this and many other things can be found on
450 https://github.com/powerdns/pdns/blob/master/pdns/dnsdistconf.lua and
451 the exact definition of `blockFilter()` is at the end of this document.
452
453 ANY or whatever to TC
454 ---------------------
455 The `blockFilter()` also gets passed read/writable copy of the DNS Header,
456 via `dq.dh`.
457 If you invoke setQR(1) on that, `dnsdist` knows you turned the packet into
458 a response, and will send the answer directly to the original client.
459
460 If you also called setTC(1), this will tell the remote client to move to
461 TCP, and in this way you can implement ANY-to-TCP even for downstream
462 servers that lack this feature.
463
464 Note that calling `addAnyTCRule()` achieves the same thing, without
465 involving Lua.
466
467 Rules for traffic exceeding QPS limits
468 --------------------------------------
469 Traffic that exceeds a QPS limit, in total or per IP (subnet) can be matched by a rule.
470
471 For example:
472
473 ```
474 addDelay(MaxQPSIPRule(5, 32, 48), 100)
475 ```
476
477 This measures traffic per IPv4 address and per /48 of IPv6, and if traffic for such
478 an address (range) exceeds 5 qps, it gets delayed by 100ms.
479
480 As another example:
481
482 ```
483 addAction(MaxQPSIPRule(5), NoRecurseAction())
484 ```
485
486 This strips the Recursion Desired (RD) bit from any traffic per IPv4 or IPv6 /64
487 that exceeds 5 qps. This means any those traffic bins is allowed to make a recursor do 'work'
488 for only 5 qps.
489
490 If this is not enough, try:
491
492 ```
493 addAction(MaxQPSIPRule(5), DropAction())
494 -- or
495 addAction(MaxQPSIPRule(5), TCAction())
496 ```
497
498 This will respectively drop traffic exceeding that 5 QPS limit per IP or range, or return it with TC=1, forcing
499 clients to fall back to TCP.
500
501 To turn this per IP or range limit into a global limit, use NotRule(MaxQPSRule(5000)) instead of MaxQPSIPRule.
502
503 TeeAction
504 ---------
505 This action sends off a copy of a UDP query to another server, and keeps statistics
506 on the responses received. Sample use:
507
508 ```
509 > addAction(AllRule(), TeeAction("192.168.1.54"))
510 > getAction(0):printStats()
511 refuseds 0
512 nxdomains 0
513 noerrors 0
514 servfails 0
515 recv-errors 0
516 tcp-drops 0
517 responses 0
518 other-rcode 0
519 send-errors 0
520 queries 0
521 ```
522
523 It is also possible to share a TeeAction between several rules. Statistics
524 will be combined in that case.
525
526 Lua actions in rules
527 --------------------
528 While we can pass every packet through the `blockFilter()` functions, it is also
529 possible to configure `dnsdist` to only hand off some packets for Lua inspection.
530 If you think Lua is too slow for your query load, or if you are doing heavy processing in Lua,
531 this may make sense.
532
533 To select specific packets for Lua attention, use `addLuaAction(x, func)`,
534 where x is either a netmask, or a domain suffix, or a table of netmasks or a
535 table of domain suffixes. This is identical to how `addPoolRule()` selects.
536
537 The function should look like this:
538 ```
539 function luarule(dq)
540 if(dq.qtype==35) -- NAPTR
541 then
542 return DNSAction.Pool, "abuse" -- send to abuse pool
543 else
544 return DNSAction.None, "" -- no action
545 end
546 end
547 ```
548
549 Valid return values for `LuaAction` functions are:
550
551 * DNSAction.Allow: let the query pass, skipping other rules
552 * DNSAction.Delay: delay the response for the specified milliseconds (UDP-only), continue to the next rule
553 * DNSAction.Drop: drop the query
554 * DNSAction.HeaderModify: indicate that the query has been turned into a response
555 * DNSAction.None: continue to the next rule
556 * DNSAction.Nxdomain: return a response with a NXDomain rcode
557 * DNSAction.Pool: use the specified pool to forward this query
558 * DNSAction.Spoof: spoof the response using the supplied IPv4 (A), IPv6 (AAAA) or string (CNAME) value
559
560 DNSSEC
561 ------
562 To provide DNSSEC service from a separate pool, try:
563 ```
564 newServer({address="2001:888:2000:1d::2", pool="dnssec"})
565 newServer({address="2a01:4f8:110:4389::2", pool="dnssec"})
566 setDNSSECPool("dnssec")
567 topRule()
568 ```
569
570 This routes all queries with a DNSSEC OK (DO) or CD bit set to on to the "dnssec" pool.
571 The final `topRule()` command moves this rule to the top, so it gets evaluated first.
572
573 Regular Expressions
574 -------------------
575 `RegexRule()` matches a regular expression on the query name, and it works like this:
576
577 ```
578 addAction(RegexRule("[0-9]{5,}"), DelayAction(750)) -- milliseconds
579 addAction(RegexRule("[0-9]{4,}\\.cn$"), DropAction())
580 ```
581
582 This delays any query for a domain name with 5 or more consecutive digits in it.
583 The second rule drops anything with more than 4 consecutive digits within a .CN domain.
584
585 Note that the query name is presented without a trailing dot to the regex.
586 The regex is applied case insensitively.
587
588 Alternatively, if compiled in, RE2Rule provides similar functionality, but against libre2.
589
590 Inspecting live traffic
591 -----------------------
592 This is still much in flux, but for now, try:
593
594 * `grepq(Netmask|DNS Name|100ms [, n])`: shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms
595 * `grepq({"::1", "powerdns.com", "100ms"} [, n])`: shows the last n queries and responses matching the specified client address AND range (Netmask) AND the specified DNS Name AND slower than 100ms
596 * `topBandwidth(top)`: show top-`top` clients that consume the most bandwidth over length of ringbuffer
597 * `topClients(n)`: show top-`n` clients sending the most queries over length of ringbuffer
598 * `topQueries(20)`: shows the top-20 queries
599 * `topQueries(20,2)`: shows the top-20 two-level domain queries (so `topQueries(20,1)` only shows TLDs)
600 * `topResponses(20, 2)`: top-20 servfail responses (use ,3 for NXDOMAIN)
601 * `topSlow([top][, limit][, labels])`: show `top` queries slower than `limit` milliseconds, grouped by last `labels` labels
602
603 For example:
604 ```
605 > grepq("127.0.0.1/24")
606 Time Client Server ID Name Type Lat. TC RD AA Rcode
607 -11.9 127.0.0.1:52599 16127 nxdomain.powerdns.com. A RD Question
608 -11.7 127.0.0.1:52599 127.0.0.1:53 16127 nxdomain.powerdns.com. A 175.6 RD Non-Existent domain
609 > grepq("powerdns.com")
610 Time Client Server ID Name Type Lat. TC RD AA Rcode
611 -38.7 127.0.0.1:52599 16127 nxdomain.powerdns.com. A RD Question
612 -38.6 127.0.0.1:52599 127.0.0.1:53 16127 nxdomain.powerdns.com. A 175.6 RD Non-Existent domain
613 ```
614
615 Live histogram of latency
616 -------------------------
617 ```
618 > showResponseLatency()
619 Average response latency: 78.84 msec
620 msec
621 0.10
622 0.20 .
623 0.40 **********************
624 0.80 ***********
625 1.60 .
626 3.20
627 6.40 .
628 12.80 *
629 25.60 *
630 51.20 *
631 102.40 **********************************************************************
632 204.80 *************************
633 409.60 **
634 819.20 :
635 1638.40 .
636 ```
637
638 Where : stands for 'half a star' and . for 'less than half a star, but
639 something was there'.
640
641 Per domain or subnet QPS limiting
642 ---------------------------------
643 If certain domains or source addresses are generating onerous amounts of
644 traffic, you can put ceilings on the amount of traffic you are willing to
645 forward:
646
647 ```
648 > addQPSLimit("h4xorbooter.xyz.", 10)
649 > addQPSLimit({"130.161.0.0/16", "145.14.0.0/16"} , 20)
650 > addQPSLimit({"nl.", "be."}, 1)
651 > showRules()
652 # Matches Rule Action
653 0 0 h4xorbooter.xyz. qps limit to 10
654 1 0 130.161.0.0/16, 145.14.0.0/16 qps limit to 20
655 2 0 nl., be. qps limit to 1
656 ```
657
658 To delete a limit (or a rule in general):
659 ```
660 > rmRule(1)
661 > showRules()
662 # Matches Rule Action
663 0 0 h4xorbooter.xyz. qps limit to 10
664 1 0 nl., be. qps limit to 1
665 ```
666
667 Delaying answers
668 ----------------
669 Sometimes, runaway scripts will hammer your servers with back-to-back
670 queries. While it is possible to drop such packets, this may paradoxically
671 lead to more traffic.
672
673 An attractive middleground is to delay answers to such back-to-back queries,
674 causing a slowdown on the side of the source of the traffic.
675
676 To do so, use:
677 ```
678 > addDelay("yourdomain.in.ua.", 500)
679 > addDelay({"65.55.37.0/24"}, 500)
680 ```
681 This will delay responses for questions to the mentioned domain, or coming
682 from the configured subnet, by half a second.
683
684 Like the QPSLimits and other rules, the delaying instructions can be
685 inspected or edited using showRule(), rmRule(), topRule(), mvRule() etc.
686
687 Dynamic load balancing
688 ----------------------
689 The default load balancing policy is called `leastOutstanding`, which means
690 we pick the server with the least queries 'in the air' (and within those,
691 the one with the lowest `order`, and within those, the one with the lowest latency).
692
693 Another policy, `firstAvailable`, picks the server with the lowest `order` that has not
694 exceeded its QPS limit. For now this is the only policy using the QPS limit.
695
696 A further policy, `wrandom` assigns queries randomly, but based on the
697 `weight` parameter passed to `newServer`. `whashed` is a similar weighted policy,
698 but assigns questions with identical hash to identical servers, allowing for
699 better cache concentration ('sticky queries').
700
701 If you don't like the default policies you can create your own, like this
702 for example:
703
704 ```
705 counter=0
706 function luaroundrobin(servers, dq)
707 counter=counter+1
708 return servers[1+(counter % #servers)]
709 end
710
711 setServerPolicyLua("luaroundrobin", luaroundrobin)
712 ```
713
714 Incidentally, this is similar to setting: `setServerPolicy(roundrobin)`
715 which uses the C++ based roundrobin policy.
716
717 Lua server policies
718 -------------------
719 If the built in rules do not suffice to pick a server pool, full flexibility is available from Lua. For example:
720
721 ```
722 newServer("192.168.1.2")
723 newServer({address="8.8.4.4", pool="numbered"})
724
725 function splitSetup(servers, dq)
726 if(string.match(dq.qname:toString(), "%d"))
727 then
728 print("numbered pool")
729 return leastOutstanding.policy(getPoolServers("numbered"), dq)
730 else
731 print("standard pool")
732 return leastOutstanding.policy(servers, dq)
733 end
734 end
735
736 setServerPolicyLua("splitsetup", splitSetup)
737 ```
738
739 This will forward queries containing a number to the pool of "numbered"
740 servers, and will apply the default load balancing policy to all other
741 queries.
742
743 Dynamic Rule Generation
744 -----------------------
745 To set dynamic rules, based on recent traffic, define a function called `maintenance()` in Lua. It will
746 get called every second, and from this function you can set rules to block traffic based on statistics.
747
748 As an example:
749
750 ```
751 function maintenance()
752 addDynBlocks(exceedQRate(20, 10), "Exceeded query rate", 60)
753 end
754 ```
755
756 This will dynamically block all hosts that exceeded 20 queries/s as measured
757 over the past 10 seconds, and the dynamic block will last for 60 seconds.
758
759 Dynamic blocks in force are displayed with `showDynBlocks()` and can be cleared
760 with `clearDynBlocks()`. Full set of `exceed` functions is listed in the table of
761 all functions below.
762
763
764 Running it for real
765 -------------------
766 First run on the command line, and generate a key:
767
768 ```
769 # dnsdist
770 > makeKey()
771 setKey("sepuCcHcQnSAZgNbNPCCpDWbujZ5esZJmrt/wh6ldkQ=")
772 ```
773
774 Now add this setKey line to `dnsdistconf.lua`, and also add:
775
776 ```
777 controlSocket("0.0.0.0") -- or add portnumber too
778 ```
779
780 Then start `dnsdist` as a daemon, and then connect to it:
781 ```
782 # dnsdist --daemon
783 # dnsdist --client
784 >
785 ```
786
787 Please note that, without libsodium support, 'makeKey()' will return
788 setKey("plaintext") and the communication between the client and the
789 server will not be encrypted.
790
791 Some versions of libedit, notably the CentOS 6 one, may require the following
792 addition to ~/.editrc in order to support searching through the history:
793
794 ```
795 bind "^R" em-inc-search-prev
796 ```
797
798 ACL, who can use dnsdist
799 ------------------------
800 For safety reasons, by default only private networks can use `dnsdist`, see below
801 how to query and change the ACL:
802
803 ```
804 > showACL()
805 127.0.0.0/8
806 10.0.0.0/8
807 (...)
808 ::1/128
809 fc00::/7
810 fe80::/10
811 > addACL("130.161.0.0/16")
812 > setACL({"::/0"}) -- resets the list to this array
813 > showACL()
814 ::/0
815 ```
816
817 Caching
818 -------
819 `dnsdist` implements a simple but effective packet cache, not enabled by default.
820 It is enabled per-pool, but the same cache can be shared between several pools.
821 The first step is to define a cache, then to assign that cache to the chosen pool,
822 the default one being represented by the empty string:
823
824 ```
825 pc = newPacketCache(10000, 86400, 0, 60, 60)
826 getPool(""):setCache(pc)
827 ```
828
829 The first parameter is the maximum number of entries stored in the cache, and is the
830 only one required. All the others parameters are optional and in seconds.
831 The second one is the maximum lifetime of an entry in the cache, the third one is
832 the minimum TTL an entry should have to be considered for insertion in the cache,
833 the fourth one is the TTL used for a Server Failure response. The last one is the
834 TTL that will be used when a stale cache entry is returned.
835
836 The `setStaleCacheEntriesTTL(n)` directive can be used to allow `dnsdist` to use
837 expired entries from the cache when no backend is available. Only entries that have
838 expired for less than `n` seconds will be used, and the returned TTL can be set
839 when creating a new cache with `newPacketCache()`.
840
841 A reference to the cache affected to a specific pool can be retrieved with:
842
843 ```
844 getPool("poolname"):getCache()
845 ```
846
847 And removed with:
848
849 ```
850 getPool("poolname"):unsetCache()
851 ```
852
853 Cache usage stats (hits, misses, deferred inserts and lookups, collisions)
854 can be displayed by using the `printStats()` method:
855
856 ```
857 getPool("poolname"):getCache():printStats()
858 ```
859
860 Expired cached entries can be removed from a cache using the `purgeExpired(n)`
861 method, which will remove expired entries from the cache until at least `n`
862 entries remain in the cache. For example, to remove all expired entries:
863
864 ```
865 getPool("poolname"):getCache():purgeExpired(0)
866 ```
867
868 Specific entries can also be removed using the `expungeByName(DNSName [, qtype=ANY])`
869 method.
870
871 ```
872 getPool("poolname"):getCache():expungeByName(newDNSName("powerdns.com"), dnsdist.A)
873 ```
874
875 Finally, the `expunge(n)` method will remove all entries until at most `n`
876 entries remain in the cache:
877
878 ```
879 getPool("poolname"):getCache():expunge(0)
880 ```
881
882
883 Performance tuning
884 ------------------
885 First, a few words about `dnsdist` architecture:
886
887 * Each local bind has its own thread listening for incoming UDP queries
888 * and its own thread listening for incoming TCP connections,
889 dispatching them right away to a pool of threads
890 * Each backend has its own thread listening for UDP responses
891 * A maintenance thread calls the `maintenance()` Lua function every second
892 if any, and is responsible for cleaning the cache
893 * A health check thread checks the backends availability
894 * A control thread handles console connections
895 * A carbon thread exports statistics to carbon servers if needed
896 * One or more webserver threads handle queries to the internal webserver
897
898 The maximum number of threads in the TCP pool is controlled by the
899 `setMaxTCPClientThreads()` directive, and defaults to 10. This number can be
900 increased to handle a large number of simultaneous TCP connections.
901 If all the TCP threads are busy, new TCP connections are queued while
902 they wait to be picked up. The maximum number of queued connections
903 can be configured with `setMaxTCPQueuedConnections()`, and any value other
904 than 0 (the default) will cause new connections to be dropped if there
905 are already too many queued.
906
907 When dispatching UDP queries to backend servers, `dnsdist` keeps track of at
908 most `n` outstanding queries for each backend. This number `n` can be tuned by
909 the `setMaxUDPOutstanding()` directive, defaulting to 10240, with a maximum
910 value of 65535. Large installations are advised to increase the default value
911 at the cost of a slightly increased memory usage.
912
913 Most of the query processing is done in C++ for maximum performance,
914 but some operations are executed in Lua for maximum flexibility:
915
916 * the `blockfilter()` function
917 * rules added by `addLuaAction()`
918 * server selection policies defined via `setServerPolicyLua()` or `newServerPolicy()`
919
920 While Lua is fast, its use should be restricted to the strict necessary in order
921 to achieve maximum performance, it might be worth considering using LuaJIT instead
922 of Lua. When Lua inspection is needed, the best course of action is to restrict
923 the queries sent to Lua inspection by using `addLuaAction()` instead of inspecting
924 all queries in the `blockfilter()` function.
925
926 `dnsdist` design choices mean that the processing of UDP queries is done by only
927 one thread per local bind. This is great to keep lock contention to a low level,
928 but might not be optimal for setups using a lot of processing power, caused for
929 example by a large number of complicated rules. To be able to use more CPU cores
930 for UDP queries processing, it is possible to use the `reuseport` parameter of
931 the `addLocal()` and `setLocal()` directives to be able to add several identical
932 local binds to `dnsdist`:
933
934 ```
935 addLocal("192.0.2.1:53", true, true)
936 addLocal("192.0.2.1:53", true, true)
937 addLocal("192.0.2.1:53", true, true)
938 addLocal("192.0.2.1:53", true, true)
939 ```
940
941 `dnsdist` will then add four identical local binds as if they were different IPs
942 or ports, start four threads to handle incoming queries and let the kernel load
943 balance those randomly to the threads, thus using four CPU cores for rules
944 processing. Note that this require SO_REUSEPORT support in the underlying
945 operating system (added for example in Linux 3.9).
946 Please also be aware that doing so will increase lock contention and might not
947 therefore scale linearly. This is especially true for Lua-intensive setups,
948 because Lua processing in `dnsdist` is serialized by an unique lock for all
949 threads.
950
951 Another possibility is to use the reuseport option to run several `dnsdist`
952 processes in parallel on the same host, thus avoiding the lock contention issue
953 at the cost of having to deal with the fact that the different processes will
954 not share informations, like statistics or DDoS offenders.
955
956 The UDP threads handling the responses from the backends do not use a lot of CPU,
957 but if needed it is also possible to add the same backend several times to the
958 `dnsdist` configuration to distribute the load over several responder threads.
959
960 ```
961 newServer({address="192.0.2.127:53", name="Backend1"})
962 newServer({address="192.0.2.127:53", name="Backend2"})
963 newServer({address="192.0.2.127:53", name="Backend3"})
964 newServer({address="192.0.2.127:53", name="Backend4"})
965 ```
966
967
968 Carbon/Graphite/Metronome
969 -------------------------
970 To emit metrics to Graphite, or any other software supporting the Carbon protocol, use:
971 ```
972 carbonServer('ip-address-of-carbon-server', 'ourname', 30)
973 ```
974
975 Where 'ourname' can be used to override your hostname, and '30' is the
976 reporting interval in seconds. The last two arguments can be omitted. The
977 latest version of [PowerDNS
978 Metronome](https://github.com/ahupowerdns/metronome) comes with attractive
979 graphs for `dnsdist` by default.
980
981 Query counters
982 -------------
983 When using `carbonServer`, it is also possible to send per-records statistics of
984 the amount of queries by using `setQueryCount(true)`. With query counting enabled,
985 `dnsdist` will increase a counter for every unique record or the behaviour you define
986 in a custom Lua function by setting `setQueryCountFilter(func)`. This filter can decide
987 whether to keep count on a query at all or rewrite for which query the counter will be
988 increased.
989 An example of a `QueryCountFilter` would be:
990
991 ```
992 function filter(dq)
993 qname = dq.qname:toString()
994
995 -- don't count PTRs at all
996 if(qname:match('in%-addr.arpa$')) then
997 return false, ""
998 end
999
1000 -- count these queries as if they were queried without leading www.
1001 if(qname:match('^www.')) then
1002 qname = qname:gsub('^www.', '')
1003 end
1004
1005 -- count queries by default
1006 return true, qname
1007 end
1008
1009 setQueryCountFilter(filter)
1010 ```
1011
1012 Valid return values for `QueryCountFilter` functions are:
1013
1014 * `true`: count the specified query
1015 * `false`: don't count the query
1016
1017 Note that the query counters are buffered and flushed each time statistics are
1018 sent to the carbon server. The current content of the buffer can be inspected
1019 with `getQueryCounters()`. If you decide to enable query counting without
1020 `carbonServer`, make sure you implement clearing the log from `maintenance()`
1021 by issuing `clearQueryCounters()`.
1022
1023 DNSCrypt
1024 --------
1025 `dnsdist`, when compiled with --enable-dnscrypt, can be used as a DNSCrypt server,
1026 uncurving queries before forwarding them to downstream servers and curving responses back.
1027 To make `dnsdist` listen to incoming DNSCrypt queries on 127.0.0.1 port 8443,
1028 with a provider name of "2.providername", using a resolver certificate and associated key
1029 stored respectively in the `resolver.cert` and `resolver.key` files, the `addDnsCryptBind()`
1030 directive can be used:
1031
1032 ```
1033 addDNSCryptBind("127.0.0.1:8443", "2.providername", "/path/to/resolver.cert", "/path/to/resolver.key")
1034 ```
1035
1036 To generate the provider and resolver certificates and keys, you can simply do:
1037
1038 ```
1039 > generateDNSCryptProviderKeys("/path/to/providerPublic.key", "/path/to/providerPrivate.key")
1040 Provider fingerprint is: E1D7:2108:9A59:BF8D:F101:16FA:ED5E:EA6A:9F6C:C78F:7F91:AF6B:027E:62F4:69C3:B1AA
1041 > generateDNSCryptCertificate("/path/to/providerPrivate.key", "/path/to/resolver.cert", "/path/to/resolver.key", serial, validFrom, validUntil)
1042 ```
1043
1044 Ideally, the certificates and keys should be generated on an offline dedicated hardware and not on the resolver.
1045 The resolver key should be regularly rotated and should never touch persistent storage, being stored in a tmpfs
1046 with no swap configured.
1047
1048 You can display the currently configured DNSCrypt binds with:
1049 ```
1050 > showDNSCryptBinds()
1051 # Address Provider Name Serial Validity P. Serial P. Validity
1052 0 127.0.0.1:8443 2.name 14 2016-04-10 08:14:15 0 -
1053 ```
1054
1055 If you forgot to write down the provider fingerprint value after generating the provider keys, you can use `printDNSCryptProviderFingerprint()` to retrieve it later:
1056 ```
1057 > printDNSCryptProviderFingerprint("/path/to/providerPublic.key")
1058 Provider fingerprint is: E1D7:2108:9A59:BF8D:F101:16FA:ED5E:EA6A:9F6C:C78F:7F91:AF6B:027E:62F4:69C3:B1AA
1059 ```
1060
1061 AXFR, IXFR and NOTIFY
1062 ---------------------
1063 When `dnsdist` is deployed in front of a master authoritative server, it might
1064 receive AXFR or IXFR queries destined to this master. There are two issues
1065 that can arise in this kind of setup:
1066
1067 * If the master is part of a pool of servers, the first SOA query can be directed
1068 by `dnsdist` to a different server than the following AXFR/IXFR one, which might
1069 fail if the servers are not perfectly synchronised.
1070 * If the master only allows AXFR/IXFR based on the source address of the requestor,
1071 it might be confused by the fact that the source address will be the one from
1072 the `dnsdist` server.
1073
1074 The first issue can be solved by routing SOA, AXFR and IXFR requests explicitely
1075 to the master:
1076
1077 ```
1078 > newServer({address="192.168.1.2", name="master", pool={"master", "otherpool"}})
1079 > addAction(OrRule({QTypeRule(dnsdist.SOA), QTypeRule(dnsdist.AXFR), QTypeRule(dnsdist.IXFR)}), PoolAction("master"))
1080 ```
1081
1082 The second one might require allowing AXFR/IXFR from the `dnsdist` source address
1083 and moving the source address check on `dnsdist`'s side:
1084
1085 ```
1086 > addAction(AndRule({OrRule({QTypeRule(dnsdist.AXFR), QTypeRule(dnsdist.IXFR)}), NotRule(makeRule("192.168.1.0/24"))}), RCodeAction(dnsdist.REFUSED))
1087 ```
1088
1089 When `dnsdist` is deployed in front of slaves, however, an issue might arise with NOTIFY
1090 queries, because the slave will receive a notification coming from the `dnsdist` address,
1091 and not the master's one. One way to fix this issue is to allow NOTIFY from the `dnsdist`
1092 address on the slave side (for example with PowerDNS's `trusted-notification-proxy`) and
1093 move the address check on `dnsdist`'s side:
1094
1095 ```
1096 > addAction(AndRule({OpcodeRule(DNSOpcode.Notify), NotRule(makeRule("192.168.1.0/24"))}), RCodeAction(dnsdist.REFUSED))
1097 ```
1098
1099 eBPF Socket Filtering
1100 ---------------------
1101 `dnsdist` can use eBPF socket filtering on recent Linux kernels (4.1+) built with eBPF
1102 support (`CONFIG_BPF`, `CONFIG_BPF_SYSCALL`, ideally `CONFIG_BPF_JIT`).
1103 This feature might require an increase of the memory limit associated to a socket, via
1104 the `sysctl` setting `net.core.optmem_max`. When attaching an eBPF program to a socket,
1105 the size of the program is checked against this limit, and the default value might not be
1106 enough. Large map sizes might also require an increase of `RLIMIT_MEMLOCK`.
1107
1108 This feature allows `dnsdist` to ask the kernel to discard incoming packets in kernel-space
1109 instead of them being copied to userspace just to be dropped, thus being a lot of faster.
1110
1111 The BPF filter can be used to block incoming queries manually:
1112
1113 ```
1114 > bpf = newBPFFilter(1024, 1024, 1024)
1115 > bpf:attachToAllBinds()
1116 > bpf:block(newCA("2001:DB8::42"))
1117 > bpf:blockQName(newDNSName("evildomain.com"), 255)
1118 > bpf:getStats()
1119 [2001:DB8::42]: 0
1120 evildomain.com. 255: 0
1121 > bpf:unblock(newCA("2001:DB8::42"))
1122 > bpf:unblockQName(newDNSName("evildomain.com"), 255)
1123 > bpf:getStats()
1124 >
1125 ```
1126
1127 The `blockQName()` method can be used to block queries based on the exact qname supplied,
1128 in a case-insensitive way, and an optional qtype. Using the 255 (ANY) qtype will block all
1129 queries for the qname, regardless of the qtype.
1130 Contrary to source address filtering, qname filtering only works over UDP. TCP qname
1131 filtering can be done the usual way:
1132
1133 ```
1134 > addAction(AndRule({TCPRule(true), makeRule("evildomain.com")}), DropAction())
1135 ```
1136
1137 The `attachToAllBinds()` method attaches the filter to every existing bind at runtime,
1138 but it's also possible to define a default BPF filter at configuration time, so
1139 it's automatically attached to every bind:
1140
1141 ```
1142 bpf = newBPFFilter(1024, 1024, 1024)
1143 setDefaultBPFFilter(bpf)
1144 ```
1145
1146 Finally, it's also possible to attach it to specific binds at runtime:
1147
1148 ```
1149 > bpf = newBPFFilter(1024, 1024, 1024)
1150 > showBinds()
1151 # Address Protocol Queries
1152 0 [::]:53 UDP 0
1153 1 [::]:53 TCP 0
1154 > bd = getBind(0)
1155 > bd:attachFilter(bpf)
1156 ```
1157
1158 `dnsdist` also supports adding dynamic, expiring blocks to a BPF filter:
1159
1160 ```
1161 bpf = newBPFFilter(1024, 1024, 1024)
1162 setDefaultBPFFilter(bpf)
1163 dbpf = newDynBPFFilter(bpf)
1164 function maintenance()
1165 addBPFFilterDynBlocks(exceedQRate(20, 10), dbpf, 60)
1166 dbpf:purgeExpired()
1167 end
1168 ```
1169
1170 This will dynamically block all hosts that exceeded 20 queries/s as measured
1171 over the past 10 seconds, and the dynamic block will last for 60 seconds.
1172
1173 This feature has been successfully tested on Arch Linux, Arch Linux ARM,
1174 Fedora Core 23 and Ubuntu Xenial.
1175
1176 All functions and types
1177 -----------------------
1178 Within `dnsdist` several core object types exist:
1179
1180 * Server: generated with newServer, represents a downstream server
1181 * ComboAddress: represents an IP address and port
1182 * DNSName: represents a domain name
1183 * NetmaskGroup: represents a group of netmasks
1184 * QPSLimiter: implements a QPS-based filter
1185 * SuffixMatchNode: represents a group of domain suffixes for rapid testing of membership
1186 * DNSHeader: represents the header of a DNS packet
1187
1188 The existence of most of these objects can mostly be ignored, unless you
1189 plan to write your own hooks and policies, but it helps to understand an
1190 expressions like:
1191
1192 ```
1193 > getServer(0).order=12 -- set order of server 0 to 12
1194 > getServer(0):addPool("abuse") -- add this server to the abuse pool
1195 ```
1196 The '.' means 'order' is a data member, while the ':' meand addPool is a member function.
1197
1198 Here are all functions:
1199
1200 * Practical
1201 * `shutdown()`: shut down `dnsdist`
1202 * quit or ^D: exit the console
1203 * `webserver(address:port, password [, apiKey [, customHeaders ]])`: launch a webserver with stats on that address with that password
1204 * ACL related:
1205 * `addACL(netmask)`: add to the ACL set who can use this server
1206 * `setACL({netmask, netmask})`: replace the ACL set with these netmasks. Use `setACL({})` to reset the list, meaning no one can use us
1207 * `showACL()`: show our ACL set
1208 * ClientState related:
1209 * function `showBinds()`: list every local bind
1210 * function `getBind(n)`: return the corresponding `ClientState` object
1211 * member `attachFilter(BPFFilter)`: attach a BPF Filter to this bind
1212 * member `detachFilter()`: detach the BPF Filter attached to this bind, if any
1213 * member `toString()`: print the address this bind listens to
1214 * Network related:
1215 * `addLocal(netmask, [true], [false], [TCP Fast Open queue size])`: add to addresses we listen on. Second optional parameter sets TCP or not. Third optional parameter sets SO_REUSEPORT when available. Last parameter sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0.
1216 * `setLocal(netmask, [true], [false], [TCP Fast Open queue size])`: reset list of addresses we listen on to this address. Second optional parameter sets TCP or not. Third optional parameter sets SO_REUSEPORT when available. Last parameter sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0.
1217 * Blocking related:
1218 * `addDomainBlock(domain)`: block queries within this domain
1219 * Carbon/Graphite/Metronome statistics related:
1220 * `carbonServer(serverIP, [ourname], [interval])`: report statistics to serverIP using our hostname, or 'ourname' if provided, every 'interval' seconds
1221 * Query counting related:
1222 * `clearQueryCounters()`: clears the query counter buffer.
1223 * `getQueryCounters([max])`: show current buffer of query counters, limited by `max` if provided.
1224 * `setQueryCount(bool)`: set whether queries should be counted.
1225 * `setQueryCountFilter(func)`: filter queries that would be counted, where `func` is a function with parameter `dq` which decides whether a query should and how it should be counted.
1226 * Control socket related:
1227 * `makeKey()`: generate a new server access key, emit configuration line ready for pasting
1228 * `setKey(key)`: set access key to that key.
1229 * `testCrypto()`: test of the crypto all works
1230 * `controlSocket(addr)`: open a control socket on this address / connect to this address in client mode
1231 * Diagnostics and statistics
1232 * `dumpStats()`: print all statistics we gather
1233 * `grepq(Netmask|DNS Name|100ms [, n])`: shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms
1234 * `grepq({"::1", "powerdns.com", "100ms"} [, n])`: shows the last n queries and responses matching the specified client address AND range (Netmask) AND the specified DNS Name AND slower than 100ms
1235 * `topQueries(n[, labels])`: show top 'n' queries, as grouped when optionally cut down to 'labels' labels
1236 * `topResponses(n, kind[, labels])`: show top 'n' responses with RCODE=kind (0=NO Error, 2=ServFail, 3=ServFail), as grouped when optionally cut down to 'labels' labels
1237 * `topSlow([top][, limit][, labels])`: show `top` queries slower than `limit` milliseconds, grouped by last `labels` labels
1238 * `topBandwidth(top)`: show top-`top` clients that consume the most bandwidth over length of ringbuffer
1239 * `topClients(n)`: show top-`n` clients sending the most queries over length of ringbuffer
1240 * `showResponseLatency()`: show a plot of the response time latency distribution
1241 * `showTCPStats()`: show some statistics regarding TCP
1242 * `showVersion()`: show the current version of dnsdist
1243 * Logging related
1244 * `infolog(string)`: log at level info
1245 * `warnlog(string)`: log at level warning
1246 * `errlog(string)`: log at level error
1247 * `setVerboseHealthChecks(bool)`: set whether health check errors will be logged
1248 * Server related:
1249 * `newServer("ip:port")`: instantiate a new downstream server with default settings
1250 * `newServer({address="ip:port", qps=1000, order=1, weight=10, pool="abuse", retries=5, tcpSendTimeout=30, tcpRecvTimeout=30, checkName="a.root-servers.net.", checkType="A", setCD=false, maxCheckFailures=1, mustResolve=false, useClientSubnet=true, source="address|interface name|address@interface"})`:
1251 instantiate a server with additional parameters
1252 * `showServers()`: output all servers
1253 * `getServer(n)`: returns server with index n
1254 * `getServers()`: returns a table with all defined servers
1255 * `rmServer(n)`: remove server with index n
1256 * `rmServer(server)`: remove this server object
1257 * Server member functions:
1258 * `addPool(pool)`: add this server to that pool
1259 * `getName()`: return the server name if any
1260 * `getNameWithAddr()`: return a string containing the server name if any plus the server address and port
1261 * `getOutstanding()`: this *returns* the number of outstanding queries (doesn't print it!)
1262 * `rmPool(pool)`: remove server from that pool
1263 * `setQPS(n)`: set the QPS setting to n
1264 * `setAuto()`: set this server to automatic availability testing
1265 * `setDown()`: force this server to be down
1266 * `setUp()`: force this server to be UP
1267 * `isUp()`: if this server is available
1268 * Server member data:
1269 * `upStatus`: if `dnsdist` considers this server available (overridden by `setDown()` and `setUp()`)
1270 * `name`: name of the server
1271 * `order`: order of this server in order-based server selection policies
1272 * `weight`: weight of this server in weighted server selection policies
1273 * Rule related:
1274 * `AllRule()`: matches all traffic
1275 * `AndRule()`: matches if all sub-rules matches
1276 * `DNSSECRule()`: matches queries with the DO flag set
1277 * `MaxQPSIPRule(qps, v4Mask=32, v6Mask=64)`: matches traffic exceeding the qps limit per subnet
1278 * `MaxQPSRule(qps)`: matches traffic **not** exceeding this qps limit
1279 * `NetmaskGroupRule(nmg, [src-bool])`: matches traffic from the specified network range. Pass `false` as second parameter to match NetmaskGroup against destination address instead of source address
1280 * `NotRule()`: matches if the sub-rule does not match
1281 * `OrRule()`: matches if at least one of the sub-rules matches
1282 * `OpcodeRule()`: matches queries with the specified opcode
1283 * `QClassRule(qclass)`: matches queries with the specified qclass (numeric)
1284 * `QNameLabelsCountRule(min, max)`: matches if the qname has less than `min` or more than `max` labels
1285 * `QNameWireLengthRule(min, max)`: matches if the qname's length on the wire is less than `min` or more than `max` bytes
1286 * `QTypeRule(qtype)`: matches queries with the specified qtype
1287 * `RCodeRule(rcode)`: matches queries or responses the specified rcode
1288 * `RegexRule(regex)`: matches the query name against the supplied regex
1289 * `RecordsCountRule(section, minCount, maxCount)`: matches if there is at least `minCount` and at most `maxCount` records in the `section` section
1290 * `RecordsTypeCountRule(section, type, minCount, maxCount)`: matches if there is at least `minCount` and at most `maxCount` records of type `type` in the `section` section
1291 * `RE2Rule(regex)`: matches the query name against the supplied regex using the RE2 engine
1292 * `SuffixMatchNodeRule(smn, [quiet-bool])`: matches based on a group of domain suffixes for rapid testing of membership. Pass `true` as second parameter to prevent listing of all domains matched.
1293 * `TCPRule(tcp)`: matches question received over TCP if `tcp` is true, over UDP otherwise
1294 * `TrailingDataRule()`: matches if the query has trailing data
1295 * Rule management related:
1296 * `clearRules()`: remove all current rules
1297 * `getAction(num)`: returns the Action associate with rule 'num'.
1298 * `mvResponseRule(from, to)`: move response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule,
1299 in which case the rule will be moved to the last position.
1300 * `mvRule(from, to)`: move rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule,
1301 in which case the rule will be moved to the last position.
1302 * `newRuleAction(DNS Rule, DNS Action)`: return a pair of DNS Rule and DNS Action, to be used with `setRules()`
1303 * `rmResponseRule(n)`: remove response rule n
1304 * `rmRule(n)`: remove rule n
1305 * `setRules(list)`: replace the current rules with the supplied list of pairs of DNS Rules and DNS Actions (see `newRuleAction()`)
1306 * `showResponseRules()`: show all defined response rules
1307 * `showRules()`: show all defined rules
1308 * `topResponseRule()`: move the last response rule to the first position
1309 * `topRule()`: move the last rule to the first position
1310 * Built-in Actions for Rules:
1311 * `AllowAction()`: let these packets go through
1312 * `AllowResponseAction()`: let these packets go through
1313 * `DelayAction(milliseconds)`: delay the response by the specified amount of milliseconds (UDP-only)
1314 * `DelayResponseAction(milliseconds)`: delay the response by the specified amount of milliseconds (UDP-only)
1315 * `DisableValidationAction()`: set the CD bit in the question, let it go through
1316 * `DropAction()`: drop these packets
1317 * `DropResponseAction()`: drop these packets
1318 * `LogAction([filename], [binary], [append], [buffered])`: Log a line for each query, to the specified file if any, to the console (require verbose) otherwise. When logging to a file, the `binary` optional parameter specifies whether we log in binary form (default) or in textual form, the `append` optional parameter specifies whether we open the file for appending or truncate each time (default), and the `buffered` optional parameter specifies whether writes to the file are buffered (default) or not.
1319 * `NoRecurseAction()`: strip RD bit from the question, let it go through
1320 * `PoolAction(poolname)`: set the packet into the specified pool
1321 * `QPSPoolAction(maxqps, poolname)`: set the packet into the specified pool only if it **does not** exceed the specified QPS limits, letting the subsequent rules apply otherwise
1322 * `QPSAction(rule, maxqps)`: drop these packets if the QPS limits are exceeded
1323 * `RCodeAction(rcode)`: reply immediatly by turning the query into a response with the specified rcode
1324 * `RemoteLogAction(RemoteLogger [, alterFunction])`: send the content of this query to a remote logger via Protocol Buffer. `alterFunction` is a callback, receiving a DNSQuestion and a DNSDistProtoBufMessage, that can be used to modify the Protocol Buffer content, for example for anonymization purposes
1325 * `RemoteLogResponseAction(RemoteLogger [,alterFunction])`: send the content of this response to a remote logger via Protocol Buffer. `alterFunction` is the same callback than the one in `RemoteLogAction`
1326 * `SkipCacheAction()`: don't lookup the cache for this query, don't store the answer
1327 * `SpoofAction(ip[, ip])` or `SpoofAction({ip, ip, ..}): forge a response with the specified IPv4 (for an A query) or IPv6 (for an AAAA). If you specify multiple addresses, all that match the query type (A, AAAA or ANY) will get spoofed in
1328 * `SpoofCNAMEAction(cname)`: forge a response with the specified CNAME value
1329 * `TCAction()`: create answer to query with TC and RD bits set, to move to TCP
1330 * `TeeAction(remote[, addECS])`: send copy of query to remote, keep stats on responses. If `addECS` is set to `true`, EDNS Client Subnet information will be added to the query
1331 * Specialist rule generators
1332 * `addAnyTCRule()`: generate TC=1 answers to ANY queries received over UDP, moving them to TCP
1333 * `addDomainSpoof(domain, ip[, ip6])` or `addDomainSpoof(domain, {IP, IP, IP..})`: generate answers for A/AAAA/ANY queries using the ip parameters
1334 * `addDomainCNAMESpoof(domain, cname)`: generate CNAME answers for queries using the specified value
1335 * `addDisableValidationRule(domain)`: set the CD flags to 1 for all queries matching the specified domain
1336 * `addNoRecurseRule(domain)`: clear the RD flag for all queries matching the specified domain
1337 * `setDNSSECPool(pool)`: move queries requesting DNSSEC processing to this pool
1338 * Policy member data:
1339 * `name`: the policy name
1340 * `policy`: the policy function
1341 * Pool related:
1342 * `addPoolRule(domain, pool)`: send queries to this domain to that pool
1343 * `addPoolRule({domain, domain}, pool)`: send queries to these domains to that pool
1344 * `addPoolRule(netmask, pool)`: send queries to this netmask to that pool
1345 * `addPoolRule({netmask, netmask}, pool)`: send queries to these netmasks to that pool
1346 * `addQPSPoolRule(x, limit, pool)`: like `addPoolRule`, but only select at most 'limit' queries/s for this pool, letting the subsequent rules apply otherwise
1347 * `getPool(poolname)`: return the ServerPool named `poolname`
1348 * `getPoolServers(pool)`: return servers part of this pool
1349 * `showPools()`: list the current server pools
1350 * Lua Action related:
1351 * `addLuaAction(x, func)`: where 'x' is all the combinations from `addPoolRule`, and func is a
1352 function with the parameter `dq`, which returns an action to be taken on this packet.
1353 Good for rare packets but where you want to do a lot of processing.
1354 * Server selection policy related:
1355 * `setServerPolicy(policy)`: set server selection policy to that policy
1356 * `setServerPolicyLua(name, function)`: set server selection policy to one named 'name' and provided by 'function'
1357 * `showServerPolicy()`: show name of currently operational server selection policy
1358 * `newServerPolicy(name, function)`: create a policy object from a Lua function
1359 * Available policies:
1360 * `firstAvailable`: Pick first server that has not exceeded its QPS limit, ordered by the server 'order' parameter
1361 * `whashed`: Weighted hashed ('sticky') distribution over available servers, based on the server 'weight' parameter
1362 * `wrandom`: Weighted random over available servers, based on the server 'weight' parameter
1363 * `roundrobin`: Simple round robin over available servers
1364 * `leastOutstanding`: Send traffic to downstream server with least outstanding queries, with the lowest 'order', and within that the lowest recent latency
1365 * Shaping related:
1366 * `addQPSLimit(domain, n)`: limit queries within that domain to n per second
1367 * `addQPSLimit({domain, domain}, n)`: limit queries within those domains (together) to n per second
1368 * `addQPSLimit(netmask, n)`: limit queries within that netmask to n per second
1369 * `addQPSLimit({netmask, netmask}, n)`: limit queries within those netmasks (together) to n per second
1370 * Delaying related:
1371 * `addDelay(domain, n)`: delay answers within that domain by n milliseconds
1372 * `addDelay({domain, domain}, n)`: delay answers within those domains (together) by n milliseconds
1373 * `addDelay(netmask, n)`: delay answers within that netmask by n milliseconds
1374 * `addDelay({netmask, netmask}, n)`: delay answers within those netmasks (together) by n milliseconds
1375 * Answer changing functions:
1376 * `truncateTC(bool)`: if set (default) truncate TC=1 answers so they are actually empty. Fixes an issue for PowerDNS Authoritative Server 2.9.22.
1377 * `fixupCase(bool)`: if set (default to no), rewrite the first qname of the question part of the answer to match the one from the query. It is only useful when you have a downstream server that messes up the case of the question qname in the answer
1378 * Dynamic Block related:
1379 * `maintenance()`: called every second by dnsdist if defined, call functions below from it
1380 * `clearDynBlocks()`: clear all dynamic blocks
1381 * `showDynBlocks()`: show dynamic blocks in force
1382 * `addDynBlocks(addresses, message[, seconds])`: block the set of addresses with message `msg`, for `seconds` seconds (10 by default)
1383 * `addBPFFilterDynBlocks(addresses, DynBPFFilter[, seconds])`: block the set of addresses using the supplied BPF Filter, for `seconds` seconds (10 by default)
1384 * `exceedServFails(rate, seconds)`: get set of addresses that exceed `rate` servails/s over `seconds` seconds
1385 * `exceedNXDOMAINs(rate, seconds)`: get set of addresses that exceed `rate` NXDOMAIN/s over `seconds` seconds
1386 * `exceedRespByterate(rate, seconds)`: get set of addresses that exeeded `rate` bytes/s answers over `seconds` seconds
1387 * `exceedQRate(rate, seconds)`: get set of address that exceed `rate` queries/s over `seconds` seconds
1388 * `exceedQTypeRate(type, rate, seconds)`: get set of address that exceed `rate` queries/s for queries of type `type` over `seconds` seconds
1389 * ServerPool related:
1390 * `getCache()`: return the current packet cache, if any
1391 * `setCache(PacketCache)`: set the cache for this pool
1392 * `unsetCache()`: remove the packet cache from this pool
1393 * PacketCache related:
1394 * `expunge(n)`: remove entries from the cache, leaving at most `n` entries
1395 * `expungeByName(DNSName [, qtype=ANY])`: remove entries matching the supplied DNSName and type from the cache
1396 * `isFull()`: return true if the cache has reached the maximum number of entries
1397 * `newPacketCache(maxEntries[, maxTTL=86400, minTTL=0, servFailTTL=60, stateTTL=60])`: return a new PacketCache
1398 * `printStats()`: print the cache stats (hits, misses, deferred lookups and deferred inserts)
1399 * `purgeExpired(n)`: remove expired entries from the cache until there is at most `n` entries remaining in the cache
1400 * `toString()`: return the number of entries in the Packet Cache, and the maximum number of entries
1401 * Advanced functions for writing your own policies and hooks
1402 * ComboAddress related:
1403 * `newCA(address)`: return a new ComboAddress
1404 * `getPort()`: return the port number
1405 * `isIPv4()`: return true if the address is an IPv4, false otherwise
1406 * `isIPv6()`: return true if the address is an IPv6, false otherwise
1407 * `isMappedIPv4()`: return true if the address is an IPv4 mapped into an IPv6, false otherwise
1408 * `mapToIPv4()`: convert an IPv4 address mapped in a v6 one into an IPv4
1409 * `tostring()`: return in human-friendly format
1410 * `toString()`: alias for `tostring()`
1411 * `tostringWithPort()`: return in human-friendly format, with port number
1412 * `toStringWithPort()`: alias for `tostringWithPort()`
1413 * `truncate(bits)`: truncate the address to the specified number of bits
1414 * DNSName related:
1415 * `newDNSName(name)`: make a DNSName based on this .-terminated name
1416 * member `countLabels()`: return the number of labels
1417 * member `isPartOf(dnsname)`: is this dnsname part of that dnsname
1418 * member `tostring()`: return as a human friendly . terminated string
1419 * member `toString()`: alias for `tostring()`
1420 * member `wirelength()`: return the length on the wire
1421 * DNSQuestion related:
1422 * member `dh`: DNSHeader
1423 * member `len`: the question length
1424 * member `localaddr`: ComboAddress of the local bind this question was received on
1425 * member `opcode`: the question opcode
1426 * member `qname`: DNSName of this question
1427 * member `qclass`: QClass (as an unsigned integer) of this question
1428 * member `qtype`: QType (as an unsigned integer) of this question
1429 * member `remoteaddr`: ComboAddress of the remote client
1430 * member `rcode`: RCode of this question
1431 * member `size`: the total size of the buffer starting at `dh`
1432 * member `skipCache`: whether to skip cache lookup / storing the answer for this question (settable)
1433 * member `tcp`: whether this question was received over a TCP socket
1434 * DNSHeader related
1435 * member `getRD()`: get recursion desired flag
1436 * member `setRD(bool)`: set recursion desired flag
1437 * member `setTC(bool)`: set truncation flag (TC)
1438 * member `setQR(bool)`: set Query Response flag (setQR(true) indicates an *answer* packet)
1439 * member `getCD()`: get checking disabled flag
1440 * member `setCD(bool)`: set checking disabled flag
1441 * NetmaskGroup related
1442 * function `newNMG()`: returns a NetmaskGroup
1443 * member `addMask(mask)`: adds `mask` to the NetmaskGroup
1444 * member `match(ComboAddress)`: checks if ComboAddress is matched by this NetmaskGroup
1445 * member `clear()`: clears the NetmaskGroup
1446 * member `size()`: returns number of netmasks in this NetmaskGroup
1447 * QPSLimiter related:
1448 * `newQPSLimiter(rate, burst)`: configure a QPS limiter with that rate and that burst capacity
1449 * member `check()`: check if this QPSLimiter has a token for us. If yes, you must use it.
1450 * SuffixMatchNode related:
1451 * `newSuffixMatchNode()`: returns a new SuffixMatchNode
1452 * member `check(DNSName)`: returns true if DNSName is matched by this group
1453 * member `add(DNSName)`: add this DNSName to the node
1454 * Tuning related:
1455 * `setTCPRecvTimeout(n)`: set the read timeout on TCP connections from the client, in seconds
1456 * `setTCPSendTimeout(n)`: set the write timeout on TCP connections from the client, in seconds
1457 * `setMaxTCPClientThreads(n)`: set the maximum of TCP client threads, handling TCP connections
1458 * `setMaxTCPQueuedConnections(n)`: set the maximum number of TCP connections queued (waiting to be picked up by a client thread)
1459 * `setMaxUDPOutstanding(n)`: set the maximum number of outstanding UDP queries to a given backend server. This can only be set at configuration time and defaults to 10240
1460 * `setCacheCleaningDelay(n)`: set the interval in seconds between two runs of the cache cleaning algorithm, removing expired entries
1461 * `setStaleCacheEntriesTTL(n)`: allows using cache entries expired for at most `n` seconds when no backend available to answer for a query
1462 * DNSCrypt related:
1463 * `addDNSCryptBind("127.0.0.1:8443", "provider name", "/path/to/resolver.cert", "/path/to/resolver.key", [false], [TCP Fast Open queue size]):` listen to incoming DNSCrypt queries on 127.0.0.1 port 8443, with a provider name of "provider name", using a resolver certificate and associated key stored respectively in the `resolver.cert` and `resolver.key` files. The fifth optional parameter sets SO_REUSEPORT when available. The last parameter sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0.
1464 * `generateDNSCryptProviderKeys("/path/to/providerPublic.key", "/path/to/providerPrivate.key"):` generate a new provider keypair
1465 * `generateDNSCryptCertificate("/path/to/providerPrivate.key", "/path/to/resolver.cert", "/path/to/resolver.key", serial, validFrom, validUntil):` generate a new resolver private key and related certificate, valid from the `validFrom` timestamp until the `validUntil` one, signed with the provider private key
1466 * `printDNSCryptProviderFingerprint("/path/to/providerPublic.key")`: display the fingerprint of the provided resolver public key
1467 * `showDNSCryptBinds():`: display the currently configured DNSCrypt binds
1468 * BPFFilter related:
1469 * function `newBPFFilter(maxV4, maxV6, maxQNames)`: return a new eBPF socket filter with a maximum of maxV4 IPv4, maxV6 IPv6 and maxQNames qname entries in the block tables
1470 * function `setDefaultBPFFilter(BPFFilter)`: when used at configuration time, the corresponding BPFFilter will be attached to every bind
1471 * member `attachToAllBinds()`: attach this filter to every bind already defined. This is the run-time equivalent of `setDefaultBPFFilter(bpf)`
1472 * member `block(ComboAddress)`: block this address
1473 * member `blockQName(DNSName [, qtype=255])`: block queries for this exact qname. An optional qtype can be used, default to 255
1474 * member `getStats()`: print the block tables
1475 * member `unblock(ComboAddress)`: unblock this address
1476 * member `unblockQName(DNSName [, qtype=255])`: remove this qname from the block list
1477 * DNSDistProtoBufMessage related:
1478 * member `setBytes(bytes)`: set the size of the query
1479 * member `setEDNSSubnet(Netmask)`: set the EDNS Subnet
1480 * member `setQueryTime(sec, usec)`: in a response message, set the time at which the query has been received
1481 * member `setQuestion(DNSName, qtype, qclass)`: set the question
1482 * member `setRequestor(ComboAddress)`: set the requestor
1483 * member `setRequestorFromString(string)`: set the requestor
1484 * member `setResponder(ComboAddress)`: set the responder
1485 * member `setResponderFromString(string)`: set the responder
1486 * member `setResponseCode(rcode)`: set the response code
1487 * member `setTime(sec, usec)`: set the time at which the query or response has been received
1488 * member `toDebugString()`: return an string containing the content of the message
1489 * DynBPFFilter related:
1490 * function `newDynBPFFilter(BPFFilter)`: return a new DynBPFFilter object using this BPF Filter
1491 * member `block(ComboAddress[, seconds]): add this address to the underlying BPF Filter for `seconds` seconds (default to 10 seconds)
1492 * member `purgeExpired()`: remove expired entries
1493 * function `registerDynBPFFilter(DynBPFFilter)`: register this dynamic BPF filter into the web interface so that its counters are displayed
1494 * function `unregisterDynBPFFilter(DynBPFFilter)`: unregister this dynamic BPF filter
1495 * RemoteLogger related:
1496 * `newRemoteLogger(address:port [, timeout=2, maxQueuedEntries=100, reconnectWaitTime=1])`: create a Remote Logger object, to use with `RemoteLogAction()` and `RemoteLogResponseAction()`
1497
1498 All hooks
1499 ---------
1500 `dnsdist` can call Lua per packet if so configured, and will do so with the following hooks:
1501
1502 * `bool blockFilter(dq)`: if defined, called for every packet. If this
1503 returns true, the packet is dropped. If false is returned, `dnsdist` will check if the DNSHeader indicates
1504 the packet is now a query response. If so, `dnsdist` will answer the client directly with the modified packet.
1505 * `server policy(candidates, DNSQuestion)`: if configured with `setServerPolicyLua()`
1506 gets called for every packet. Candidates is a table of potential servers to pick from, ComboAddress is the
1507 address of the requestor, DNSName and qtype describe name and type of query. DNSHeader meanwhile is available for
1508 your inspection.
1509
1510
1511