]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/README-dnsdist.md
dnsdist: Add TCP management options from rfc7766 section 10
[thirdparty/pdns.git] / pdns / README-dnsdist.md
index 6b74c42a358460d15a5a63b4e85ca0209cbba093..f90459ea36870fd5c903368360c16afe9288a6f4 100644 (file)
@@ -167,6 +167,17 @@ be 192.0.2.0. This can be changed with:
 > setECSSourcePrefixV6(56)
 ```
 
+In addition to the global settings, rules and Lua bindings can alter this behavior per query:
+
+* calling `DisableECSAction()` or setting `dq.useECS` to false prevent the sending of the ECS option
+* calling `ECSOverrideAction(bool)` or setting `dq.ecsOverride` will override the global `setECSOverride()` value
+* calling `ECSPrefixLengthAction(v4, v6)` or setting `dq.ecsPrefixLength` will override the global
+`setECSSourcePrefixV4()` and `setECSSourcePrefixV6()` values
+
+In effect this means that for the EDNS Client Subnet option to be added to the request, `useClientSubnet`
+should be set to true for the backend used (default to false) and ECS should not have been disabled by calling
+`DisableECSAction()` or setting `dq.useECS` to false (default to true).
+
 TCP timeouts
 ------------
 
@@ -359,9 +370,10 @@ Current actions are:
  * Send out a crafted response (NXDOMAIN or "real" data)
  * Delay a response by n milliseconds (DelayAction), over UDP only
  * Modify query to clear the RD or CD bit
- * Add the source MAC address to the query (MacAddrAction)
+ * Add the source MAC address to the query (MacAddrAction, only supported on Linux)
  * Skip the cache, if any
  * Log query content to a remote server (RemoteLogAction)
+ * Alter the EDNS Client Subnet parameters (DisableECSAction, ECSOverrideAction, ECSPrefixLengthAction)
 
 Current response actions are:
 
@@ -415,14 +427,17 @@ A DNS rule can be:
 Some specific actions do not stop the processing when they match, contrary to all other actions:
 
  * Delay
+ * DisableECS
  * Disable Validation
+ * ECSOverride
+ * ECSPrefixLength
  * Log
  * MacAddr
  * No Recurse
  * and of course None
 
 A convenience function `makeRule()` is supplied which will make a NetmaskGroupRule for you or a SuffixMatchNodeRule
-depending on how you call it. `makeRule("0.0.0.0/0")` will for example match all IPv4 traffic, `makeRule{"be","nl","lu"}` will
+depending on how you call it. `makeRule("0.0.0.0/0")` will for example match all IPv4 traffic, `makeRule({"be","nl","lu"})` will
 match all Benelux DNS traffic.
 
 All the current rules can be removed at once with:
@@ -682,7 +697,7 @@ This will delay responses for questions to the mentioned domain, or coming
 from the configured subnet, by half a second.
 
 Like the QPSLimits and other rules, the delaying instructions can be
-inspected or edited using showRule(), rmRule(), topRule(), mvRule() etc.
+inspected or edited using `showRules()`, `rmRule()`, `topRule()`, `mvRule()` etc.
 
 Dynamic load balancing
 ----------------------
@@ -760,6 +775,13 @@ Dynamic blocks in force are displayed with `showDynBlocks()` and can be cleared
 with `clearDynBlocks()`. Full set of `exceed` functions is listed in the table of
 all functions below.
 
+Dynamic blocks drop matched queries by default, but this behavior can be changed
+with `setDynBlocksAction()`. For example, to send a REFUSED code instead of droppping
+the query:
+
+```
+setDynBlocksAction(DNSAction.Refused)
+```
 
 Running it for real
 -------------------
@@ -771,7 +793,7 @@ First run on the command line, and generate a key:
 setKey("sepuCcHcQnSAZgNbNPCCpDWbujZ5esZJmrt/wh6ldkQ=")
 ```
 
-Now add this setKey line to `dnsdistconf.lua`, and also add:
+Now add this setKey line to `dnsdist.conf`, and also add:
 
 ```
 controlSocket("0.0.0.0") -- or add portnumber too
@@ -858,7 +880,7 @@ getPool("poolname"):getCache():printStats()
 ```
 
 Expired cached entries can be removed from a cache using the `purgeExpired(n)`
-method, which will remove expired entries from the cache until at least `n`
+method, which will remove expired entries from the cache until at most `n`
 entries remain in the cache. For example, to remove all expired entries:
 
 ```
@@ -900,9 +922,9 @@ The maximum number of threads in the TCP pool is controlled by the
 increased to handle a large number of simultaneous TCP connections.
 If all the TCP threads are busy, new TCP connections are queued while
 they wait to be picked up. The maximum number of queued connections
-can be configured with `setMaxTCPQueuedConnections()`, and any value other
-than 0 (the default) will cause new connections to be dropped if there
-are already too many queued.
+can be configured with `setMaxTCPQueuedConnections()` and defaults to 1000.
+Any value larger than 0 will cause new connections to be dropped if there are
+already too many queued.
 
 When dispatching UDP queries to backend servers, `dnsdist` keeps track of at
 most `n` outstanding queries for each backend. This number `n` can be tuned by
@@ -1201,6 +1223,8 @@ Here are all functions:
     * `shutdown()`: shut down `dnsdist`
     * quit or ^D: exit the console
     * `webserver(address:port, password [, apiKey [, customHeaders ]])`: launch a webserver with stats on that address with that password
+    * `includeDirectory(dir)`: all files ending in `.conf` in the directory `dir` are loaded into the configuration
+    * `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
  * ACL related:
     * `addACL(netmask)`: add to the ACL set who can use this server
     * `setACL({netmask, netmask})`: replace the ACL set with these netmasks. Use `setACL({})` to reset the list, meaning no one can use us
@@ -1230,6 +1254,7 @@ Here are all functions:
     * `controlSocket(addr)`: open a control socket on this address / connect to this address in client mode
  * Diagnostics and statistics
     * `dumpStats()`: print all statistics we gather
+    * `getStatisticsCounters()`: return the statistics counters as a Lua table
     * `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
     * `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
     * `topQueries(n[, labels])`: show top 'n' queries, as grouped when optionally cut down to 'labels' labels
@@ -1312,17 +1337,21 @@ instantiate a server with additional parameters
     * `AllowResponseAction()`: let these packets go through
     * `DelayAction(milliseconds)`: delay the response by the specified amount of milliseconds (UDP-only)
     * `DelayResponseAction(milliseconds)`: delay the response by the specified amount of milliseconds (UDP-only)
+    * `DisableECSAction()`: disable the sending of ECS to the backend
     * `DisableValidationAction()`: set the CD bit in the question, let it go through
     * `DropAction()`: drop these packets
     * `DropResponseAction()`: drop these packets
+    * `ECSOverrideAction(bool)`: whether an existing ECS value should be overriden (true) or not (false)
+    * `ECSPrefixLengthAction(v4, v6)`: set the ECS prefix length
     * `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.
+    * `MacAddrAction(option code)`: add the source MAC address to the query as EDNS0 option `option code`. This action is currently only supported on Linux
     * `NoRecurseAction()`: strip RD bit from the question, let it go through
     * `PoolAction(poolname)`: set the packet into the specified pool
     * `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
     * `QPSAction(rule, maxqps)`: drop these packets if the QPS limits are exceeded
     * `RCodeAction(rcode)`: reply immediatly by turning the query into a response with the specified rcode
-    * `RemoteLogAction(RemoteLogger)`: send the content of this query to a remote logger via Protocol Buffer
-    * `RemoteLogResponseAction(RemoteLogger)`: send the content of this response to a remote logger via Protocol Buffer
+    * `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
+    * `RemoteLogResponseAction(RemoteLogger [,alterFunction])`: send the content of this response to a remote logger via Protocol Buffer. `alterFunction` is the same callback than the one in `RemoteLogAction`
     * `SkipCacheAction()`: don't lookup the cache for this query, don't store the answer
     * `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
     * `SpoofCNAMEAction(cname)`: forge a response with the specified CNAME value
@@ -1356,6 +1385,7 @@ instantiate a server with additional parameters
     * `setServerPolicyLua(name, function)`: set server selection policy to one named 'name' and provided by 'function'
     * `showServerPolicy()`: show name of currently operational server selection policy
     * `newServerPolicy(name, function)`: create a policy object from a Lua function
+    * `setServFailWhenNoServer(bool)`: if set, return a ServFail when no servers are available, instead of the default behaviour of dropping the query
  * Available policies:
     * `firstAvailable`: Pick first server that has not exceeded its QPS limit, ordered by the server 'order' parameter
     * `whashed`: Weighted hashed ('sticky') distribution over available servers, based on the server 'weight' parameter
@@ -1380,6 +1410,7 @@ instantiate a server with additional parameters
     * `clearDynBlocks()`: clear all dynamic blocks
     * `showDynBlocks()`: show dynamic blocks in force
     * `addDynBlocks(addresses, message[, seconds])`: block the set of addresses with message `msg`, for `seconds` seconds (10 by default)
+    * `setDynBlocksAction(DNSAction)`: set which action is performed when a query is blocked. Only DNSAction.Drop (the default) and DNSAction.Refused are supported
     * `addBPFFilterDynBlocks(addresses, DynBPFFilter[, seconds])`: block the set of addresses using the supplied BPF Filter, for `seconds` seconds (10 by default)
     * `exceedServFails(rate, seconds)`: get set of addresses that exceed `rate` servails/s over `seconds` seconds
     * `exceedNXDOMAINs(rate, seconds)`: get set of addresses that exceed `rate` NXDOMAIN/s over `seconds` seconds
@@ -1394,7 +1425,7 @@ instantiate a server with additional parameters
     * `expunge(n)`: remove entries from the cache, leaving at most `n` entries
     * `expungeByName(DNSName [, qtype=ANY])`: remove entries matching the supplied DNSName and type from the cache
     * `isFull()`: return true if the cache has reached the maximum number of entries
-    * `newPacketCache(maxEntries[, maxTTL=86400, minTTL=0, servFailTTL=60, stateTTL=60])`: return a new PacketCache
+    * `newPacketCache(maxEntries[, maxTTL=86400, minTTL=0, servFailTTL=60, staleTTL=60])`: return a new PacketCache
     * `printStats()`: print the cache stats (hits, misses, deferred lookups and deferred inserts)
     * `purgeExpired(n)`: remove expired entries from the cache until there is at most `n` entries remaining in the cache
     * `toString()`: return the number of entries in the Packet Cache, and the maximum number of entries
@@ -1402,10 +1433,15 @@ instantiate a server with additional parameters
     * ComboAddress related:
         * `newCA(address)`: return a new ComboAddress
         * `getPort()`: return the port number
+        * `isIPv4()`: return true if the address is an IPv4, false otherwise
+        * `isIPv6()`: return true if the address is an IPv6, false otherwise
+        * `isMappedIPv4()`: return true if the address is an IPv4 mapped into an IPv6, false otherwise
+        * `mapToIPv4()`: convert an IPv4 address mapped in a v6 one into an IPv4
         * `tostring()`: return in human-friendly format
         * `toString()`: alias for `tostring()`
         * `tostringWithPort()`: return in human-friendly format, with port number
         * `toStringWithPort()`: alias for `tostringWithPort()`
+        * `truncate(bits)`: truncate the address to the specified number of bits
     * DNSName related:
         * `newDNSName(name)`: make a DNSName based on this .-terminated name
         * member `countLabels()`: return the number of labels
@@ -1415,6 +1451,9 @@ instantiate a server with additional parameters
         * member `wirelength()`: return the length on the wire
     * DNSQuestion related:
         * member `dh`: DNSHeader
+        * member `ecsOverride`: whether an existing ECS value should be overriden (settable)
+        * member `ecsPrefixLength`: the ECS prefix length to use (settable)
+        * member `getDO()`: return true if the DNSSEC OK (DO) bit is set
         * member `len`: the question length
         * member `localaddr`: ComboAddress of the local bind this question was received on
         * member `opcode`: the question opcode
@@ -1426,6 +1465,7 @@ instantiate a server with additional parameters
         * member `size`: the total size of the buffer starting at `dh`
         * member `skipCache`: whether to skip cache lookup / storing the answer for this question (settable)
         * member `tcp`: whether this question was received over a TCP socket
+        * member `useECS`: whether to send ECS to the backend (settable)
     * DNSHeader related
         * member `getRD()`: get recursion desired flag
         * member `setRD(bool)`: set recursion desired flag
@@ -1447,13 +1487,18 @@ instantiate a server with additional parameters
         * member `check(DNSName)`: returns true if DNSName is matched by this group
         * member `add(DNSName)`: add this DNSName to the node
  * Tuning related:
-    * `setTCPRecvTimeout(n)`: set the read timeout on TCP connections from the client, in seconds
-    * `setTCPSendTimeout(n)`: set the write timeout on TCP connections from the client, in seconds
     * `setMaxTCPClientThreads(n)`: set the maximum of TCP client threads, handling TCP connections
-    * `setMaxTCPQueuedConnections(n)`: set the maximum number of TCP connections queued (waiting to be picked up by a client thread)
+    * `setMaxTCPConnectionDuration(n)`: set the maximum duration of an incoming TCP connection, in seconds. 0 (the default) means unlimited
+    * `setMaxTCPConnectionsPerClient(n)`: set the maximum number of TCP connections per client. 0 (the default) means unlimited
+    * `setMaxTCPQueriesPerConnection(n)`: set the maximum number of queries in an incoming TCP connection. 0 (the default) means unlimited
+    * `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
     * `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
     * `setCacheCleaningDelay(n)`: set the interval in seconds between two runs of the cache cleaning algorithm, removing expired entries
+    * `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
     * `setStaleCacheEntriesTTL(n)`: allows using cache entries expired for at most `n` seconds when no backend available to answer for a query
+    * `setTCPRecvTimeout(n)`: set the read timeout on TCP connections from the client, in seconds
+    * `setTCPSendTimeout(n)`: set the write timeout on TCP connections from the client, in seconds
+    * `setUDPTimeout(n)`: set the maximum time dnsdist will wait for a response from a backend over UDP, in seconds. Defaults to 2
  * DNSCrypt related:
     * `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.
     * `generateDNSCryptProviderKeys("/path/to/providerPublic.key", "/path/to/providerPrivate.key"):` generate a new provider keypair
@@ -1469,6 +1514,18 @@ instantiate a server with additional parameters
     * member `getStats()`: print the block tables
     * member `unblock(ComboAddress)`: unblock this address
     * member `unblockQName(DNSName [, qtype=255])`: remove this qname from the block list
+ * DNSDistProtoBufMessage related:
+    * member `setBytes(bytes)`: set the size of the query
+    * member `setEDNSSubnet(Netmask)`: set the EDNS Subnet
+    * member `setQueryTime(sec, usec)`: in a response message, set the time at which the query has been received
+    * member `setQuestion(DNSName, qtype, qclass)`: set the question
+    * member `setRequestor(ComboAddress)`: set the requestor
+    * member `setRequestorFromString(string)`: set the requestor
+    * member `setResponder(ComboAddress)`: set the responder
+    * member `setResponderFromString(string)`: set the responder
+    * member `setResponseCode(rcode)`: set the response code
+    * member `setTime(sec, usec)`: set the time at which the query or response has been received
+    * member `toDebugString()`: return an string containing the content of the message
  * DynBPFFilter related:
     * function `newDynBPFFilter(BPFFilter)`: return a new DynBPFFilter object using this BPF Filter
     * member `block(ComboAddress[, seconds]): add this address to the underlying BPF Filter for `seconds` seconds (default to 10 seconds)