Skip to content

Configuration reference

Global

include_ranges

  • List of strings
  • Default: empty

A list of ranges for which dynamic rules will be inserted, which is useful in combination with global.exclude_ranges. When both this setting and global.exclude_ranges are used, the more specific entry wins. By default all ranges are subject to dynamic rules. Note that the behaviour is undefined if both lists contain identical ranges.

exclude_ranges

  • List of strings
  • Default: empty

A list of ranges for which dynamic rules will NOT be inserted. When both this setting and global.include_ranges are used, the more specific entry wins. By default all ranges are subject to dynamic rules. Note that the behaviour is undefined if both lists contain identical ranges.

ipv4_mask

  • Integer
  • Default: 32

The mask to apply to IPv4 address to identify a client. Default is 32 which is the whole address.

ipv6_mask

  • Integer
  • Default: 64

The mask to apply to IPv6 address to identify a client. Default is 64 which is usually the size of the subnet allocated to end users.

port_mask

  • Integer
  • Default: 0

The mask to apply to UDP and TCP ports to identify a client, for CGNAT deployments. Default is 0 which means the port is not taken into account. For example passing 2, which only makes sense if global.ipv4_mask and global.ipv6_mask are respectively 32 and 128, will split a given IP address into four port ranges: 0-16383, 16384-32767, 32768-49151 and 49152-65535.

quiet

  • Boolean
  • Default: true

Set whether newly blocked clients or domains should be logged.

PRSD

This module implements detection and mitigation for Pseudo Random Sub-Domain and enumeration attacks.

type

Should be set to prsd.

failures

  • List of strings. Accepted values are: other-rcodes, nxdomain, servfail and timeout
  • Default: other-rcodes, nxdomain, servfail, timeout

Responses, or lack of, that are considered as a failure and thus count towards considering a domain is under attack. Note that minimum_failure_ratio needs to be set for this setting to have an effect. other-rcodes contains all response codes that are not NoError, NXDomain or ServFail.

include_queries_to_domain

  • Boolean
  • Default: true

Whether to count queries for the domain itself when computing the failure and cache hit ratios. When set to false, only queries to the children of a given domain are considered when to determine whether this domain is under attack. It is usually to consider the queries to the domain itself as well, as blocking queries to a domain receiving a fair amount of legitimate traffic compared to the PRSD attack might not be wise. In some cases, however, the legitimate traffic can be entirely served from a cache while the traffic belonging to the PRSD attack cannot, so it might make sense to only consider the traffic going to children.

maximum_queries_per_child_ratio

  • Integer
  • Default: unset

The maximum number of queries per child for a domain to be considered under attack. The logic is that PRSD and enumeration attacks generate very few queries per leaf name, so a domain with a high ratio of queries per child is unlikely to be targeted. The default, an unset value, means that the ratio is not taken into account.

maximum_cache_hit_ratio

  • Float
  • Default: unset

The maximum ratio of queries answered from the cache for a domain to be considered under attack. A very high number of queries for the children of a domain being answered from the cache indicates a low likelihood of an attack going on. The default, an unset value, means that the ratio is not taken into account.

minimum_failure_ratio

  • Float
  • Default: unset

When set, if the ratio of failed (see failures) queries for the children of a domain, over the total number of queries for them, is less than this value then the domain will not be considered under attack.

minimum_number_of_children

  • Integer
  • Default: unset

When set, a domain that has less than this number of children will not be considered under attack.

minimum_number_of_labels

  • Integer
  • Default: unset

When set, a domain that has less than this number of labels will not be considered under attack. This is useful to avoid blocking the root or TLDs, for example.

minimum_number_of_qps

  • Integer
  • Default: unset

When set, a domain whose children receive less than this number of queries per second will not be considered under attack. This is useful to avoid false positive for domains seeing very few queries, for example. Note that the QPS is computed by looking at the number of queries found in the in-memory ring buffers over the configured time window, and divided by the number of seconds in that window. Since the ring buffers have a fixed size, it is likely that the actual number of queries per second will be under-evaluated.

action

  • String
  • Default: drop

The action to take for new queries to a domain detected as under attack. Supported values are:

  • drop: Equivalent to DNSAction.Drop
  • none: Equivalent to DNSAction.None
  • noop: Equivalent to DNSAction.Noop
  • nxdomain: Equivalent to DNSAction.Nxdomain, a NXDomain response will be generated by DNSdist. The response will of course not include any DNSSEC signatures, which will lead to validation failure for DNSSEC-signed domains
  • refused: Equivalent to DNSAction.Refused, a REFUSED response will be generated by DNSdist
  • truncate: Equivalent to DNSAction.Truncate, a response with the TC bit set will be generated by DNSdist if the query was received over UDP (including DNSCrypt over UDP), telling the client to retry over TCP
  • norecurse: Equivalent to DNSAction.NoRecurse, the query will be forwarded with the RD bit cleared, telling resolving backends not to do recursion and only use their caches

window

  • Integer
  • Default: 60

The time windows, in seconds, to consider when looking at queries and responses present in the in-memory ring buffers.

action_duration

  • Integer
  • Default: 60

The number of seconds before the generated dynamic rules expire.

comment

  • String
  • Default: "Pseudo-Random Subdomain Attack"

The comment that will be assigned to dynamic rules inserted when an attack is detected.

exclude_suffixes

  • List of strings
  • Default: empty

A list of suffixes that should never be considered under attack. For example, if powerdns.com. is present in that list, neither this domain nor any of its sub-domains will ever have a dynamic rule inserted for them.

policies

  • List of policy objects
  • Default: empty
  • DNSdist version required: >= 2.0.2

A list of mitigation policies (see below) that are applied to queries received for a domain that is currently considered as experiencing a PRSD attack. See the PRSD documentation for more details. Note that the policies are internally translated to regular DNSdist rules, and as such they are evaluated sequentially. This is particularly important when using different policies based on the client IP, as the first matching policy will be executed and might not necessarily be the best match for the client IP. It also means that rules declared in the DNSdist configuration before the Defender configuration is applied by calling setup() will be executed before the policies-related rules. If any of these regular rules stops the processing, the policies-related rules will not be executed. For this reason we recommend applying the Defender configuration before defining any custom rules in the DNSdist configuration.

A policy can have several selectors (see subnets and protocols). All the selectors need to match for the policy to be executed. Note that only the first policy that matches a given query is applied, even if subsequent policies would have matched as well.

policies.options
  • Policy options object
  • Default: empty

Additional options, see below.

policies.options.allow_cache_lookups
  • Boolean
  • Default: false

When a policy matches the incoming query, whether to defer the action until after the cache lookup. This allows cache hits to be sent to the clients, applying the configured action to cache misses only. Note that this option should not be used if a cache is not set on the pool the queries are routed to, otherwise it will completely bypass the policy because cache miss rules are not executed if there is no cache associated to the pool.

policies.protocols
  • List of strings
  • Default: empty

If the protocol used by the client to send this query to DNSdist is present in this list of protocols, the selector matches. Available protocols are "Do53 UDP", "Do53 TCP", "DNSCrypt UDP", "DNSCrypt TCP", "DNS over TLS" and "DNS over HTTPS".

policies.subnets
  • List of strings
  • Default: empty

A list of subnets as strings. If the client IP matches one of the subnets then the selector matches.

policies.action
  • Policy action object
  • Default: N/A

The action to take if this policy matches. The default is to drop queries if there is no action object. An action object must have a type.

policies.action.type
  • String
  • Default: "drop"

The action to take if this policy matches. The default is to drop queries if there is no action object. Supported actions are:

  • "allow": let the query go through. Regular rules will not be applied
  • "drop": drop the query
  • "log": log the query at the info level before letting it go through. Subsequent policy rules will not be applied but regular rules will be
  • "none"/"noop": let the query go through. Subsequent policy rules will not be applied but regular rules will be
  • "norecurse": let the query go through but force the RD bit to 0, disabling recursion. If the backend is a recursive resolver, it will only answer if the response is in its cache
  • "nxdomain": send an immediate NXDomain response
  • "slip": let the query go through with a 1 out of slip probability, otherwise apply the action configured in action
  • "rate-limit": only let up to qps of queries per second per subnet (see ipv4_mask and ipv6_mask) go through, and apply the action defined in rate_exceeded_action otherwise
  • "refused": send an immediate REFUSED response
  • "route": route to the pool specified in pool. Subsequent policy rules will not be applied but regular rules will be
  • "servfail": send an immediate SERVFAIL response
  • "truncate": if the query was received over UDP (including DNSCrypt UDP), send an immediate TC=1 response telling the client to retry over TCP. Otherwise let the query go through, subsequent policy rules will not be applied but regular rules will be
policies.action.slip
  • Integer

When the type of the policy is set to "slip", the probabilty of a query to go through. 1 means all queries go through, 4 1 out of 4, etc.

policies.action.pool
  • String

When the type of the policy is set to "route", the name of the backends pool to route the query to.

policies.action.action
  • String

When the type of the policy is set to "slip", the action to take if the query doesn't go through. Available values are:

  • "drop": drop the query
  • "none"/"noop": let the query go through. Subsequent policy rules will not be applied but regular rules will be
  • "norecurse": let the query go through but force the RD bit to set, disabling recursion. If the backend is a recursive resolver, it will only answer if the response is in its cache
  • "nxdomain": send an immediate NXDomain response
  • "refused": send an immediate REFUSED response
  • "servfail": send an immediate SERVFAIL response
  • "truncate": if the query was received over UDP (including DNSCrypt UDP), send an immediate TC=1 response telling the client to retry over TCP. Otherwise let the query go through, subsequent policy rules will not be applied but regular rules will be
policies.action.rate_exceeded_action
  • String

When the type of the policy is set to "rate-limit", the action to take if the QPS rate for this subnet is over the threshold. Available values are:

  • "drop": drop the query, the default
  • "none"/"noop": let the query go through. Subsequent policy rules will not be applied but regular rules will be
  • "norecurse": let the query go through but force the RD bit to set, disabling recursion. If the backend is a recursive resolver, it will only answer if the response is in its cache
  • "nxdomain": send an immediate NXDomain response
  • "refused": send an immediate REFUSED response
  • "servfail": send an immediate SERVFAIL response
  • "truncate": if the query was received over UDP (including DNSCrypt UDP), send an immediate TC=1 response telling the client to retry over TCP. Otherwise let the query go through, subsequent policy rules will not be applied but regular rules will be
policies.action.qps
  • Integer

When the type of the policy is set to "rate-limit", the number of queries per second allowed for this subnet.

policies.action.ipv4_mask
  • Integer
  • Default: 32

The mask to apply to IPv4 address to identify a client. Default is 32 which is the whole address.

policies.action.ipv6_mask
  • Integer
  • Default: 64

The mask to apply to IPv6 address to identify a client. Default is 64 which is usually the size of the subnet allocated to end users.

Tunneling

This module implements detection and mitigation for tunneling and data exfiltration attacks.

block_null_queries

  • Boolean
  • Default: true

Whether to apply mitigation (see tunneling.rcode) to DNS queries using the NULL type, usually indicative of the iodine tunneling tool.

limit_qps_per_client

  • Boolean
  • Default: false

Whether the maximum number of queries per second is global to all clients (false, the default) or per client (true). When the limit is per-client, global.ipv4_mask and global.ipv6_mask can be used to configure the netmask to apply to identify a client.

maximum_qps_none_class_over_udp

  • Integer
  • Default: nil

The maximum number of queries per second (globally or per-client, depending on the value of tunneling.limit_qps_per_client) to DNS queries using the None class received over UDP. Default is nil which means no limit will be enforced.

maximum_qps_none_class_over_tcp

  • Integer
  • Default: nil

The maximum number of queries per second (globally or per-client, depending on the value of tunneling.limit_qps_per_client) to DNS queries using the None class received over TCP. Default is nil which means no limit will be enforced.

maximum_qps_any_class_over_udp

  • Integer
  • Default: nil

The maximum number of queries per second (globally or per-client, depending on the value of tunneling.limit_qps_per_client) to DNS queries using the Any class received over UDP. Default is nil which means no limit will be enforced.

maximum_qps_any_class_over_tcp

  • Integer
  • Default: nil

The maximum number of queries per second (globally or per-client, depending on the value of tunneling.limit_qps_per_client) to DNS queries using the Any class received over TCP. Default is nil which means no limit will be enforced.

rcode

  • String
  • Default: "refused"

The DNS response code to return when a tunneling or data exfiltration attempt is detected.

type

Should be set to tunneling.

Query rate

This module is equivalent to DNSdist's DynBlockRulesGroup:setQueryRate().

action

  • DNSAction
  • Default: value of setDynBlocksAction()

The action to take when the dynamic rule matches.

action_duration

  • Integer
  • Required

The number of seconds before the generated dynamic rules expire.

comment

  • String
  • Default: Empty

The message to show next to the dynamic rule.

rate

  • Integer
  • Required

The number of queries per second to exceed from this client.

seconds

  • Integer
  • Required

Number of seconds the rate has been exceeded.

type

Should be set to query-rate.

warning_rate

  • Float
  • Default: 0

If set to a non-zero value, the rate above which a warning message will be issued and a no-op block inserted.

QType rate

This module is equivalent to DNSdist's DynBlockRulesGroup:setQTypeRate().

action

  • DNSAction
  • Default: value of setDynBlocksAction()

The action to take when the dynamic rule matches.

action_duration

  • Integer
  • Required

The number of seconds before the generated dynamic rules expire.

comment

  • String
  • Default: Empty

The message to show next to the dynamic rule.

qtype

  • DNSQType or '#number'
  • Required

The query type code the limit will apply to.

rate

  • Integer
  • Required

The number of queries per second to exceed from this client for this specific query type.

seconds

  • Integer
  • Required

Number of seconds the rate has been exceeded.

type

Should be set to qtype-rate.

warning_rate

  • Float
  • Default: 0

If set to a non-zero value, the rate above which a warning message will be issued and a no-op block inserted.

RCode rate

This module is equivalent to DNSdist's DynBlockRulesGroup:setRCodeRate().

action

  • DNSAction
  • Default: value of setDynBlocksAction()

The action to take when the dynamic rule matches.

action_duration

  • Integer
  • Required

The number of seconds before the generated dynamic rules expire.

comment

  • String
  • Default: Empty

The message to show next to the dynamic rule.

rate

  • Integer
  • Required

Number of responses per second to exceed.

rcode

  • DNSRCode
  • Required

The response code the limit will apply to.

seconds

  • Integer
  • Required

Number of seconds the rate has been exceeded.

type

Should be set to rcode-rate.

warning_rate

  • Float
  • Default: 0

If set to a non-zero value, the rate above which a warning message will be issued and a no-op block inserted.

RCode ratio

This module is equivalent to DNSdist's DynBlockRulesGroup:setRCodeRatio().

action

  • DNSAction
  • Default: value of setDynBlocksAction()

The action to take when the dynamic rule matches.

action_duration

  • Integer
  • Required

The number of seconds before the generated dynamic rules expire.

comment

  • String
  • Default: Empty

The message to show next to the dynamic rule.

ratio

  • Float
  • Required

The ratio to exceed between queries for this client triggering this specific response code and all queries for this client.

rcode

  • DNSRCode
  • Required

The response code the limit will apply to.

seconds

  • Integer
  • Required

Number of seconds the ratio has been exceeded.

type

Should be set to rcode-ratio.

warning_rate

  • Float
  • Default: 0

If set to a non-zero value, the ratio above which a warning message will be issued and a no-op block inserted.

Trashbin

maximum_formerr_responses_per_second

  • Integer
  • Default: 0

Number of FORMERR responses per second to exceed. The default value, 0, means that no limit is enforced.

maximum_notimp_responses_per_second

  • Integer
  • Default: 0

Number of NOTIMP responses per second to exceed. The default value, 0, means that no limit is enforced.

type

Should be set to trashbin.

Amplification

action

  • DNSAction
  • Default: value of setDynBlocksAction()

The action to take when the dynamic rule matches.

action_duration

  • Integer
  • Required

The number of seconds before the generated dynamic rules expire.

comment

  • String
  • Default: Empty

The message to show next to the dynamic rule.

max_response_byte_rate

  • Integer
  • Required

Bandwidth, in bytes per second, for a client to exceed.

warning_max_response_byte_rate

  • Integer
  • Required

Bandwidth, in bytes per second, for a client to exceed to trigger a warning in the logs.

seconds

  • Integer
  • Required

Number of seconds the rate has been exceeded.

type

Should be set to amplification.

Dynamic rules synchronization

type

Should be set to dynamic-rules-sync.

server

  • String
  • Required

The NATS server that can will used to synchronize the dynamic rules. The server should have been defined in a section of type nats-server, see nats-servers.

channel

  • String
  • Default: "dnsdist_dyn_blocks"

The NATS channel on which the dynamic rules will be exchanged.

consume

  • Boolean
  • Default: true

Whether to consume and apply dynamic rules generated by other instances.

publish

  • Boolean
  • Default: true

Whether to publish dynamic rules generated by this instance.

publish_suffixes

  • Boolean
  • Default: true

Whether to publish dynamic rules for zones (PRSD) generated by this instance.

publish_netmasks

  • Boolean
  • Default: true

Whether to publish dynamic rules for client IPs and subnets (PRSD) generated by this instance.

NATS servers

type

Should be set to nats-servers.

servers

List of NATS servers that can be used in the remaining of the configuration.

host

  • String
  • Default: "127.0.0.1"

The IP address of the NATS server.

port

  • Integer
  • Default: 4222

The TCP port used by the NATS server.

username

  • String
  • Default: empty

If the NATS server requires authentication, which is recommended, the username to use.

password

  • String
  • Default: empty

If the NATS server requires authentication, which is recommended, the password to use.

tls

  • Boolean
  • Default: false

Whether to use TLS to connect to the NATS server, which is recommended.

tls_certificate

  • String
  • Default: Empty

If TLS is used, the path to a file containing the TLS client certificate in PEM format.

tls_key

  • String
  • Default: Empty

If TLS is used, the path to a file containing the TLS client key corresponding to the certificate, in PEM format.

tls_ca_file

  • String
  • Default: Empty

If TLS is used, the path to a file containing the CA certificate to validate the server certificate against.

tls_ca_path

  • String
  • Default: Empty

If TLS is used, the path to a directory containing the CA certificates to validate the server certificate against.

timeout

  • Integer
  • Default: 1

The timeout to use for blocking network operations.

debug

  • Boolean
  • Default: false

Whether to enable the logging of NATS operations, to help investigate issues.

STEK synchronization

servers

List of NATS servers that can be used in the remaining of the configuration.

host

  • String
  • Default: "127.0.0.1"

The IP address of the NATS server.

port

  • Integer
  • Default: 4222

The TCP port used by the NATS server.

username

  • String
  • Default: empty

If the NATS server requires authentication, which is recommended, the username to use.

password

  • String
  • Default: empty

If the NATS server requires authentication, which is recommended, the password to use.

tls

  • Boolean
  • Default: false

Whether to use TLS to connect to the NATS server, which is recommended.

tls_certificate

  • String
  • Default: Empty

If TLS is used, the path to a file containing the TLS client certificate in PEM format.

tls_key

  • String
  • Default: Empty

If TLS is used, the path to a file containing the TLS client key corresponding to the certificate, in PEM format.

tls_ca_file

  • String
  • Default: Empty

If TLS is used, the path to a file containing the CA certificate to validate the server certificate against.

tls_ca_path

  • String
  • Default: Empty

If TLS is used, the path to a directory containing the CA certificates to validate the server certificate against.

timeout

  • Integer
  • Default: 1

The timeout to use for blocking network operations.

debug

  • Boolean
  • Default: false

Whether to enable the logging of NATS operations, to help investigate issues.

syncs

List of properties that should be synchronized. As of 1.0, only the stek type is supported.

type

Should be set to stek.

server

  • String
  • Required

The name of NATS server entry defined in the servers section.

channel

  • String
  • Default: "dnsdist_steks"

The NATS channel on which the STEKs will be exchanged.

publish

  • Boolean
  • Default: false

Whether this instance should publish the TLS session ticket keys it generates to the NATS bus, or load them when a new one is read.