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