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