Skip to content

dstore-dist

Root Node Config

A minimal dstore-dist configuration (missing the details of the destination and route configuration) could be:

listen:
  - "127.0.0.1:2000"
  - "[::1]:2000"
tls_listen:
  - addr: "127.0.0.1:2001"
    tlsconfig:
      cert_file: /etc/certs/cert.pem
      key_file: /etc/certs/cert.key
log:
  level: Warn
ipsets:
  ipset1:
    file: /etc/ipset1.txt
    poll_interval: 10s
destinations:
  mydestination1:
    <destination configuration>
  mydestination2:
    <destination configuration>
routes:
  myroute1:
    <route configuration>
  myroute2:
    <route configuration>

The following YAML key-values are supported for configuration at the root node:

Parameter Type Default Description
batch_buffer_size int 1048576 The size in bytes of the buffer(s) used to batch messages internally. Normally the default of 1048576 (1MB) will suffice, but when using Kafka, making this value around 90% of the value of the kafka max_msg_size is a good idea, to avoid fragmentation of the messages when sending to Kafka.
conn_timeout go:DurationString The idle timeout for incoming connections to dstore-dist. Defaults to no timeout, i,e. only applies if explicitly configured.
debug boolean false Enable/disable very verbose debug logging
destinations Map of Destination Each map key is the name of a destination, and the value is a Destination
history_num_batches int Number of batches to keep in memory for the history API. A batch is capped at 1 MB by default, see batch_buffer_size for the actual size. If this is unset or set to 0, the history API is disabled. The history API can be accessed at /api/history. By default this URL will print additional usage information, including how to switch to Protobuf or JSON output format, and how to filter on certain fields.
http_address string Listen address for HTTP webserver for Prometheus metrics and status page. Value is an address:port string, using the same format as for listen addresses.
http_api_key string If set, an X-API-Key header matching this key is required to access the optional HTTP history API.
input_framing string 16bit Controls whether to expect 16-bit or 32-bit length prefixes for incoming protobuf messages. Valid values are 16bit and 32bit.
ipsets Map of IP Set
listen List of string The addresses that dstore-dist will listen on for new protobuf messages. The value is a list of address:port strings, in either v4 or v6 format. IPv6 addresses must be placed in square brackets like this [::1]. You can omit the address to listen on all local addresses.
log Log Config
routes Map of Route Each map key is the name of a route, and the value is a Route
tls_listen List of TLS Listen The addresses that dstore-dist will listen on for new protobuf messages. The value is a list of address:port strings, in either v4 or v6 format. IPv6 addresses must be placed in square brackets like this [::1]. You can omit the address to listen on all local addresses.

A note on the input_framing parameter:

  • Protobuf messages sent and received by dstore components contain a length prefix so that the length of each message can be determined and read safely.
  • Historically PowerDNS processes have emitted protobuf messages with a 16-bit length prefix.
  • Due to the increasing amount of data in the protobuf message, including data such as Open Telemetry, there is a small chance that the 16-bit prefix will not be enough to hold the entire message.
  • Thus PowerDNS products such as recursor, authoritative, and dnsdist either support or will support the capability to emit 32-bit length prefixes.
  • The dstore-dist input framing parameter allows you to control whether to expect 16-bit or 32-bit length prefixes. However note that this is a global switch that applies to all input, i.e. it is not possible to accept mixed input streams of 16-bit and 32-bit length prefixes. Thus you should ensure that all processes that send data to dstore-dist are using the same prefix length, whether that is 16-bit or 32-bit.
  • Similarly the other applications in dstore that process protobuf: topn-reporter and eventforwarder can be configured to accept 32-bit length prefixes. Note that dstore-dist enables protobuf sent out to be "upgraded" from 16-bit to 32-bit, but it is not possible to downgrade from 32-bit to 16-bit prefixes (because data may be lost).

Log Config

Log Configuration is as follows:

Parameter Type Default Description
level string Defaults to Info. Can also be set to Warn, Error, Debug or Trace. For debug level to take effect, the -debug flag must also be set.
stdout boolean false By default logging will go to stderr, set this to true send to stdout instead.
text boolean false If true, enable text-based logging. The default is JSON logging.

TLS Listen

You can configure a TLS Listener as follows:

Parameter Type Default Description
addr string The address:port to listen on
tlsconfig TLS Config Configuration of TLS parameters

TLS Config

Parameter Type Default Description
insecure_skip_verify boolean false Controls whether a client verifies the server's certificate chain and hostname.
ca_file string Optional CA file to use (PEM).
ca string Optional CA to use specified as a string in PEM format.
add_system_ca_pool boolean false Adds the system CA pool if private CAs are enabled, when set.
cert_file string Optional certificate file to use (PEM).
cert string Optional certificate to use specified as a string in PEM format.
key_file string Optional key file to use (PEM).
key string Optional key to use specified as a string in PEM format.
require_client_cert boolean false Controls whether a client certificate is required (MTLS). ca must be set if this is true.
watch_certs boolean false If true, enables background reloading of certifcate files.
watch_certs_poll_interval go:DurationString 5s If watch_certs is true, how often to check for changes.

IPSet

Parameter Type Required Default Description
file string yes The path to a file containing newline separated IP prefixes (v4 or v6) which can be used for filtering events with various filters.
poll_interval go:DurationString 5s How often to check the file for changes.

An example IPSet file is shown below:

127.0.0.1/16
128.243.0.0/16
# Comments beginning with # are allowed
fe80::1cc0:3e8c:119f:c2e1/18

Destination

The following parameters can be used to configure a destination:

Parameter Type Default Description
blackhole boolean false Messages to this destination will be dropped
burst integer 0 When rate limiting, allow burst size of n events
channel_buf_size integer 100 The size of the channel buffer used to send batches to destinations. If the destination is writing very large files, e.g. for s3 storage destinations, which can halt processing of new messages for that destination, it can help to increase the buffer size to avoid dropping batches. Use the dstore_dist_route_remote_drop_total metric as a guide - e.g. if it is regularly greater than 0 (increasing the number of workers can also help here).
framing string 16bit The framing type to use when sending protobuf to this destination. Possible values are 16bit, 32bit and repeated. This is ignored when the destination does not support protobuf, or when the output encoding is not protobuf.
ip_obfuscation IP Obfuscation Settings that control obfuscation of from/to IP addresses.
rate integer 0 Rate limit throughput to n messages per second (0 or empty means no rate limiting will take place).
sample integer 0 Sample messages to one out of n messages.
type string pdns Type of destination.
Available options: "pdns" "kafka" "storage" "websub" "otel".
See below for more configuration options specific to each destination type.

Some notes on the framing parameter for destinations:

  • The only destinations that support protobuf output are pdns, kafka and storage
  • Only pdns and storage destinations support the framing parameter.
  • The kafka destination ignores the framing parameter, as it always uses repeated framing.
  • All other destinations do not support protobuf and thus ignore the framing parameter.

IP Obfuscation

Parameter Type Default Description
enabled boolean false If true, obfuscate IP addresses in messages before sending to the destination. This can be useful for privacy reasons or to pseudo-anonymize data.
key string Encryption key. Must be 16 bytes long for ipcrypt-deterministic and 32 bytes for ipcrypt-pfx. Mutually exclusive with key_file.
key_file string Filename to read the key from. Mutually exclusive with key.
mode string ipcrypt-deterministic Obfuscation mode. Supported values are ipcrypt-pfx and ipcrypt-deterministic.
obfuscate_to boolean false Also obfuscate the to IP address if enabled. By default only the from address is obfuscated.

IP obfuscation uses an algorithm based on IPCrypt. By default, only the from IP address is obfuscated. Since encryption rather than hashing is used, the process is reversible; this allows for the data to be stored privately but still be able to be analyzed by the operations team if necessary, e.g. to track abuse.

The IP obfuscation modes are explained in more detail below:

  • ipcrypt-deterministic: IPs are obfuscated into an IPv6 address. This is the default mode, and is very fast (approx 5% performance degradation over no encryption).
  • ipcrypt-pfx: IPs are obfuscated into either IPv6 or IPv4 address, depending on the input address. This mode maintains network structure in encrypted IP addresses. Addresses from the same network produce encrypted addresses that share a common prefix, enabling privacy-preserving network analytics while preventing identification of specific networks or users. However, this mode is much slower than ipcrypt-deterministic, with a best-case 50% overall performance degradation for serialization (IPv4 from/to), with even worse performance for IPv6 addresses. Care should be taken when using pfx-mode.

N.B. IP Obfuscation is not supported for pdns destinations, nor is it supported when the output encoding is protobuf (i.e. kafka destinations without json_encode enabled, or storage destinations with protobuf encoding). For otel destinations, IP obfuscation applies to generated log records and does not modify the embedded OpenTelemetry trace payload.

Destination: pdns

Additional parameters are available on dstore-dist destinations with type: pdns (or no type). These should be attributes of the destination item itself. For example:

destinations:
  mydestination:
    type: pdns
    addresses:
      - myhost.example.com:1234
Parameter Type Required Default Description
addresses List of string yes List of addresses of downstream servers supporting the pdns protobuf protocol.
Should be either IP:port or host:port
connect_timeout go:DurationString "5s" How long to wait before timing out connection attempts
distribute string all Distribution algorithm when multiple addresses are configured.
Available options: "all","roundrobin", "sharded", "ordered"
shardreplicas integer 100 How many buckets to use for the hash table for sharded distribution type
tlsconfig TLS Config {} TLS configuration options
use_tls boolean false If true, attempt to connect to the addresses using TLS
write_timeout go:DurationString "5s" How long to wait before timing out write attempts

An explanation of the distribution algorithms is as follows: - all: All messages are sent to all addresses. - roundrobin: Messages are sent to addresses in a round-robin fashion. - sharded: Messages are sent to addresses in a sharded fashion. The query name is used as a key to determine which address to send the message to, using a consistent hashing algorithm. - ordered: Messages are sent to addresses in an ordered fashion. The first address is used if it is available, otherwise the second address is used, and so on.

Destination: kafka

Additional parameters are available on destinations with type: kafka. These should be nested attributes inside a kafka: item of the destination item itself. For example:

destinations:
  mydestination:
    type: kafka
    kafka:
      addresses:
        - kafka.endpoint.local:9092
      topic: mytopic

The nested kafka: attribute takes the following parameters:

Parameter Type Required Default Description
addresses List of string yes List of addresses of kafka endpoints.
Should be either IP:port or host:port
async boolean false If true, dstore-dist writes to Kafka never block and all responses from Kafka are ignored
balancer string "roundrobin" Balancer used to distribute Kafka messages amongst partitions.
Available options: "roundrobin" "leastbytes" "fnv-1a" "crc32" "murmur2"
batch_size integer 10000 Number of messages which will constitute a batch. dstore-dist will wait for new messages until either the batch size is reached, or the batch_timeout is exceeded
batch_timeout go:DurationString 1ms Timeout before an incomplete batch is written to Kafka
compression string "" Compression codec to use.
Available options: "gzip" "snappy" "lz4" "zstd"
No compression is performed when empty
exclude_fields List of string (see Include/Exclude fields) Specifies which fields to exclude from the output. Only applies to JSON encoding. By default all fields are included. Mutually exclusive with include_fields
include_fields List of string (see Include/Exclude fields) Specifies which fields to include in the output. Only applies to JSON encoding. By default all fields are included. Mutually exclusive with exclude_fields
instance_name string If configured, a header will be added to each Kafka message with this value
json_encode boolean false If true, JSON encode the data before sending to Kafka. Otherwise protobuf is sent (with repeated framing when single_msgs is false)
max_attempts integer 2 Number of times a message will be attempted to send to kafka
max_msg_size integer 900000 Maximum size of a kafka message (in bytes).
Cannot be lower than 65536.
num_workers integer 2 Number of concurrent workers that will process protobuf messages and send them to kafka
read_timeout go:DurationString 10s Timeout for reads from Kafka
required_acks string "one" How many acks are required from kafka.
Available options: "one" "all" "none"
sasl SASLConfig Optional SASL configuration
single_msgs boolean false If true, each Kafka message will only contain a single protobuf message
tlsconfig TLS Config {} TLS configuration options
topic string yes Name of Kafka topic to send messages to
use_tls boolean false If true, attempt to connect to the addresses using TLS
write_timeout go:DurationString 10s Timeout for writes to Kafka

SASL Config

The kafka nested sasl: attribute takes the following parameters:

Parameter Type Required Default Description
type string yes The type of SASL authentication to use, one of plain, scram256 or scram512
username string yes The username to use for authentication
password string The password to use for authentication. Will be ignored if password_file is provided
password_file string A filename to read the password from. The file must have 0400 permissions. Overrides password if that is also specified

Include and Exclude Fields

The lists of fields that can be included or excluded from the output of the destination for JSON encodings, and for storage destinations using parquet encoding, can be configured using the include_fields and exclude_fields parameters.

The following fields are always present in the output of the destination:

Field Notes
type
time_sec Combined with time_usec for the Timestamp parquet column.
time_usec Combined with time_sec for the Timestamp parquet column.
response.query_time_sec Only output if type is response. Combined with response.query_time_usec for the ResponseTimestamp parquet column.
response.query_time_usec Only output if type is response. Combined with response.query_time_sec for the ResponseTimestamp parquet column.

The following field names are valid for inclusion/exclusion:

Field Notes
message_id
server_identity
socket_family
socket_protocol
from
from_port
to
to_port
in_bytes
id
query.qname
query.qtype
query.qclass
response.code Only output if type is response
response.rrs Only output if type is response
response.tags Only output if type is response
response.applied_policy Only output if type is response
response.applied_policy_type Only output if type is response
response.applied_policy_trigger Only output if type is response
response.applied_policy_hit Only output if type is response
response.applied_policy_kind Only output if type is response
response.validation_state Only output if type is response
original_requestor_subnet
requestor_id
initial_request_id
device_id
device_name
newly_observed_domain
meta
trace The trace field is valid for JSON output only. It is not included in storage parquet output.
http_version
worker_id
packet_cache_hit
outgoing_queries
header_flags
edns_version
ede
ede_text
open_telemetry_trace_id

Destination: storage

Additional parameters are available on destinations with type: storage. These should be nested attributes inside a storage: item of the destination item itself. For example:

destinations:
  mydestination:
    type: storage
    storage:
      type: s3
      encoding: json
      options:
        endpoint_url: https://my.s3.endpoint.local
        bucket: myBucket
        region: myRegion

The nested storage: attribute takes the following parameters:

Parameter Type Required Default Description
encoding string "protobuf" Encoding used for the files.
Available options: "protobuf" "json" "bind" and "parquet"
exclude_fields List of string (see Include/Exclude fields) Specifies which fields to exclude from JSON or parquet output. By default all fields are included. Mutually exclusive with include_fields
file_extension string If provided, each file stored will have .<file_extension> appended, e.g. "json" will append ".json" to the file/object name
flush_interval go:DurationString 300s Time between consecutive flushes to storage (only if max_size is not reached before this interval)
include_fields List of string (see Include/Exclude fields) Specifies which fields to include in JSON or parquet output. By default all fields are included. Mutually exclusive with exclude_fields
max_size integer Maximum size in bytes of the file (before compression).
Defaults to dstore-dist's toplevel configuration item batchBufferSize. If batchBufferSize is not set the value will be 1048576. Note for "parquet" encoding, the default is 100MB, as parquet files should be large for good performance.
num_workers integer 2 Number of concurrent workers that will process protobuf messages and attempt to store them
options Storage Options yes Configuration of the storage backend
parse_rd boolean false If true, use the value of the RD flags set in the protobuf rather than assuming it's true. Only applies to "bind" encoding
request_timeout go:DurationString 5s How long to wait before giving up on sending requests to storage
type string "s3" Type of storage backend.
Available options: "s3" "azure" "fs"
use_compression boolean false If true, compress files using gzip compression

Encoding Options

There are currently four encoding options available:

  • protobuf - This is the default encoding. The protobuf is stored as a single binary blob.
  • json - Each message is encoded as a JSON string, with each message on a separate line. Fields can be controlled with include_fields and exclude_fields.
  • bind - Each message is encoded using the bind query log format, with each message on a separate line. Note that this encoding only includes a few fields from the protobuf.
  • parquet - The messages are stored in the parquet format. The parquet format is a columnar format, suitable for ingestion or querying by columnar DBs such as Clickhouse. Fields can be controlled with include_fields and exclude_fields.

For JSON, Protobuf and Parquet encodings, the type field is an integer which can be one of the following values:

Value of Type Description
1 DNS Query
2 DNS Response (also includes query)
3 DNS Outgoing Query
4 DNS Outgoing Response (also includes outgoing query)

The parquet format includes the following columns:

Column Parquet type Presence Description
Type unsigned integer Mandatory The type of the message: 1 for QUERY, 2 for RESPONSE, 3 for OUTGOING_QUERY and 4 for INCOMING_RESPONSE.
Timestamp timestamp (millisecond) Mandatory The timestamp of the query, in milliseconds since the Unix epoch (in UTC not localtime), in parquet timestamp format.
MessageID byte array Optional The UUID of the query.
ServerIdentity byte array Optional ID of the server emitting the protobuf message.
SocketFamily unsigned integer Optional Socket family as encoded in the protobuf.
SocketProtocol unsigned integer Optional Socket protocol as encoded in the protobuf.
SourceIP byte array Optional The IP address of the client that made the query.
SourcePort unsigned integer Optional The source port of the DNS query.
DestinationIP byte array Optional The IP address of the server that responded to the query.
DestinationPort unsigned integer Optional The destination port of the DNS query.
InBytes unsigned integer Optional Size of the query or response on the wire.
ID unsigned integer Optional The DNS query or response ID.
QueryName byte array Optional The DNS name that is being queried. Note that this includes the trailing dot.
QueryType string Optional The type of query, e.g. A, AAAA, MX, etc.
QueryClass string Optional The query class, e.g. IN.
Rcode unsigned integer Optional The response code for the query, e.g. 0 for NOERROR. This is only populated for response messages.
ResponseRRs list of ResponseRR fields Optional Resource records from the response.
Tags list of strings Optional Any tags present in the response. This is encoded as a parquet Array.
ResponseTimestamp timestamp (millisecond) Mandatory if type is response The timestamp of the original query for a response message, in milliseconds since the Unix epoch (in UTC not localtime), in parquet timestamp format.
ResponseAppliedPolicy byte array Optional Filtering policy applied to the response.
ResponseAppliedPolicyType unsigned integer Optional Type of the filtering policy applied to the response.
ResponseAppliedPolicyTrigger byte array Optional The RPZ trigger for the response policy.
ResponseAppliedPolicyHit byte array Optional The value that caused the response policy hit.
ResponseAppliedPolicyKind unsigned integer Optional Kind of response policy action applied.
ResponseValidationState unsigned integer Optional DNSSEC validation state for the response.
OriginalRequestorSubnet byte array Optional EDNS Client Subnet value.
RequestorID byte array Optional The username of the client that made the query.
InitialRequestID byte array Optional UUID of the incoming query that initiated this outgoing query or incoming response.
DeviceID byte array Optional The device ID of the client that made the query.
DeviceName byte array Optional The device name of the client that made the query.
NewlyObservedDomain boolean Optional Whether the domain has not been seen before.
Meta map to Meta fields Optional Arbitrary metadata, encoded as a parquet map from string keys to nested values.
HTTPVersion unsigned integer Optional HTTP version used for DNS over HTTP.
WorkerID unsigned integer Optional Worker thread ID.
PacketCacheHit boolean Optional Whether the answer came from the packet cache.
OutgoingQueries unsigned integer Optional Number of outgoing queries used to answer the query.
HeaderFlags unsigned integer Optional DNS header flags in wire format.
EdnsVersion unsigned integer Optional EDNS version and flags in wire format.

Parquet ResponseRR Fields

Each item in ResponseRRs is encoded as a ResponseRR nested record with the following fields:

Field Parquet type Description
Name byte array Resource record name.
Type string Resource record type, e.g. A, AAAA, CNAME.
Class string Resource record class, e.g. IN.
TTL unsigned integer Resource record TTL.
Rdata byte array Resource record data, hex encoded, e.g. 7f000001 would represent 127.0.0.1
UDR boolean Whether this is the first time this record has been seen for the question.

Parquet Meta Fields

Meta is encoded as a parquet map. Each map key is the metadata key string, and each map value is a nested record with the following fields:

Field Parquet type Description
StringVal list of byte arrays String metadata values as raw protobuf bytes.
IntVal list of integers Integer metadata values.

Storage Options

For storage with type: s3 the following can be configured under options:

Parameter Type Required Default Description
access_key string S3 access key.
access_key_file string File containing the S3 access key.
bucket string yes Name of the S3 bucket
client_timeout go:DurationString 15m Specifies a time limit for requests made by this HTTP Client. The timeout includes connection time, any redirects, and reading the response body.
create_bucket boolean no Whether to try to create the bucket
dial_timeout go:DurationString 10s The maximum amount of time a dial will wait for a connect to complete
dial_keep_alive go:DurationString 10s Specifies the interval between keep-alive probes for an active network connection
endpoint_url string yes Endpoint of the S3 service to connect to
global_prefix string A prefix applied to all operations, allowing work within a prefix seamlessly
idle_conn_timeout go:DurationString 90s The maximum amount of time an idle (keep-alive) connection will remain idle before closing itself
init_timeout go:DurationString 20s The time we allow for initialisation, like credential checking and bucket creation
max_idle_conns integer 100 Controls the maximum number of idle (keep-alive) connections
num_minio_threads integer 4 Controls the number of threads to be used in the multipart put object operations
region string "us-east-1" Region used when connecting to the S3 endpoint
secret_key string S3 secret key.
secret_key_file string File containing the S3 secret key.
secrets_refresh_interval go:DurationString 15s Time between each secrets retrieval.
tls TLS Config {} TLS configuration options
tls_handshake_timeout go:DurationString 10s Specifies the maximum amount of time to wait for a TLS handshake

For storage with type: azure the following can be configured under options:

Parameter Type Required Default Description
account_key string Azure Storage account key. Required with account_name when use_shared_key is enabled and account_key_file is not set.
account_key_file string File containing the Azure Storage account key. Required with account_name when use_shared_key is enabled and account_key is not set.
account_name string Azure Storage account name. Required unless endpoint_url is set.
client_timeout go:DurationString 15m Specifies a time limit for requests made by this HTTP Client. The timeout includes connection time, any redirects, and reading the response body.
concurrency integer 1 Maximum number of concurrent upload workers used by Azure block blob stream uploads.
container string yes Name of the Azure Blob Storage container.
create_container boolean no Whether to try to create the container.
dial_keep_alive go:DurationString 10s Specifies the interval between keep-alive probes for an active network connection.
dial_timeout go:DurationString 10s The maximum amount of time a dial will wait for a connect to complete.
endpoint_url string Endpoint of the Azure Blob Storage service to connect to. This can be used for Azurite or custom endpoints.
global_prefix string A prefix applied to all operations, allowing work within a prefix seamlessly.
idle_conn_timeout go:DurationString 90s The maximum amount of time an idle (keep-alive) connection will remain idle before closing itself.
init_timeout go:DurationString 20s The time we allow for initialisation, like credential checking and container creation.
max_idle_conns integer 100 Controls the maximum number of idle (keep-alive) connections.
secrets_refresh_interval go:DurationString 15s Time between each secrets retrieval when account_key_file is used.
tls TLS Config {} TLS configuration options.
tls_handshake_timeout go:DurationString 10s Specifies the maximum amount of time to wait for a TLS handshake.
update_marker_force_list_interval go:DurationString 5m When use_update_marker is enabled, force a full LIST after this interval even if the update marker has not changed.
use_shared_key boolean no Whether to authenticate with an account key. When disabled, Azure default credentials are used.
use_update_marker boolean no Whether to write and read an update marker object to reduce Azure LIST calls. If enabled, it must be enabled on all instances using this container and prefix.

For storage with type: fs the following can be configured under options:

Parameter Type Required Default Description
root_path string yes The path to a directory in which the files will be stored

Destination: websub

Additional parameters are available on destinations with type: websub. These should be nested attributes inside a websub: item of the destination item itself. For example:

destinations:
  mydestination:
    type: websub
    websub:
      client_id: dstoreuser
      client_secret: 12345
      token_url: https://myidp.example.com/token
      scopes:
        - foo
        - bar
      publish_url: https://websub.example.com/
      tlsconfig:
        insecure_skip_verify: true
      topic: dnsmessage
      request_timeout: 1s
      headers:
        X-Custom-Header: foobar

The nested websub: attribute takes the following parameters:

Parameter Type Required Default Description
client_id string yes The Client ID to use for authenticating to the token endpoint
client_secret string yes The Client Secret to use for authenticating to the token endpoint
exclude_fields List of string (see Include/Exclude fields) Specifies which fields to exclude from the output. By default all fields are included. Mutually exclusive with include_fields
headers map Map of headers, with the header name followed by the value
include_fields List of string (see Include/Exclude fields) Specifies which fields to include in the output. By default all fields are included. Mutually exclusive with exclude_fields
max_size integer 1048576 Max size in bytes of the messages field in the JSON sent to the websub server
num_workers integer 2 Number of concurrent workers to use - add more if performance is an issue
publish_url string yes The URL of the websub endpoint. If the URL path does not end with /webSub/v1/publish then that path will be appended to the URL
request_timeout go:DurationString 10s The request timeout when sending to the websub endpoint
scopes array of string If specified, which scopes to request from the token endpoint
tlsconfig TLS Config Optional TLS configuration for the connections to the websub and token endpoints
token_url string yes The URL of the token endpoint
topic string yes The topic to use when sending to the websub endpoint

See dstore-dist manpage for details of the JSON that is sent in the body of the POST request to the WebSub endpoint.

Destination: otel

Additional parameters are available on destinations with type: otel. These should be nested attributes inside a otel: item of the destination item itself. For example:

destinations:
  otel-traces:
    type: otel
    otel:
      target: host.example.com:4317
      tlsconfig:
        insecure_skip_verify: true
      request_timeout: 1s
  otel-logs:
    type: otel
    ip_obfuscation:
      enabled: true
      key_file: /etc/dstore-dist/ipcrypt.key
    otel:
      target: collector.example.com:4317
      disable_traces: true
      enable_logs: true
      log_include_fields:
        - query.qname
        - query.qtype
        - response.tags
        - response.code
        - from

By default, an otel destination sends OpenTelemetry traces from the openTelemetryData field. Trace forwarding should only receive messages which contain OpenTelemetry data; otherwise the destination has no trace payload to send. Use the has_otel_data filter for trace-only routes:

route:
  otel-traces:
    destinations:
      - otel-traces
    filters:
      - has_otel_data: true

Set enable_logs: true to convert each DNS message into an OTLP log record. If both traces and logs are enabled on the same destination, dstore-dist exports both signals to the configured collector. Use disable_traces: true for a logs-only destination.

The nested otel: attribute takes the following parameters:

Parameter Type Required Default Description
disable_traces boolean false If true, do not export embedded OpenTelemetry trace data from messages.
enable_logs boolean false If true, convert DNS messages into OTLP log records and export them to the logs service.
log_exclude_fields List of string (see Include/Exclude fields) Specifies which DNS fields to exclude from generated OTel log attributes. Mutually exclusive with log_include_fields.
log_include_fields List of string (see Include/Exclude fields) Specifies which DNS fields to include in generated OTel log attributes. By default all fields are included. Mutually exclusive with log_exclude_fields.
max_size integer 1048576 Maximum size in bytes sent to the target in a single gRPC request.
num_workers integer 4 Number of concurrent workers to use - add more if performance is an issue.
request_timeout go:DurationString 5s Request timeout for exports via OTLP.
target string yes The OTLP endpoint to send data to using gRPC. You can use the dns:// URI scheme as well.
tlsconfig TLS Config Optional TLS configuration for the connection to the target.

OTel log attributes

Generated OTel logs use the log record event name dns.query, dns.response, dns.outgoing_query, dns.incoming_response, according to the DNS message type. Log records have severity INFO and a short string body such as DNS response.

The attributes emitted for generated OTel logs depend on the DNS message contents and on log_include_fields / log_exclude_fields. The following table lists the possible attributes. Unless noted otherwise, attributes are log record attributes.

Attribute name Type Description
service.name string Resource attribute. Always set to powerdns.
service.instance.id string Resource attribute. Server identity from the DNS message, when present.
dns.id int DNS message identifier.
dns.question.name string Query name.
dns.question.type string Query type name, such as A or AAAA; numeric string for unknown types.
dns.question.class string Query class name, such as IN; numeric string for unknown classes.
dns.message.id bytes Binary message ID.
dns.message.size int Input message size in bytes.
network.type string Network address family: ipv4 or ipv6.
network.transport string Transport protocol, such as udp or tcp.
dns.transport string DNS transport name, such as udp, tcp, dot, doh, dnscrypt_udp, or dnscrypt_tcp.
network.protocol.name string Application protocol name. Set to http for DNS over HTTPS messages.
network.protocol.version string HTTP protocol version for DNS over HTTPS messages, when known.
client.address string Client IP address. If IP obfuscation is enabled on the destination, this contains the obfuscated source address.
client.port int Client source port.
server.address string Server IP address. If IP obfuscation is enabled on the destination, this contains the obfuscated destination address.
server.port int Server destination port.
dns.response.rcode int DNS response code.
dns.response.rrs array<DNS Response RR]> Response resource records.
dns.response.tags array<string> Response tags.
dns.policy.name string Applied policy name.
dns.policy.type string Applied policy type.
dns.policy.trigger string Applied policy trigger.
dns.policy.hit string Applied policy hit.
dns.policy.kind string Applied policy kind.
dns.dnssec.validation_state string DNSSEC validation state.
dns.response.time_unix_nano int Response timestamp in Unix nanoseconds. This is emitted when the DNS message includes a response timestamp.
dns.edns.client_subnet string EDNS Client Subnet address, when present.
enduser.id string Requestor ID.
dns.initial_request.id bytes Binary initial request ID.
enduser.device.id string Device ID.
enduser.device.name string Device name.
dns.question.newly_observed bool Whether the queried domain is newly observed.
thread.id int Worker ID.
dns.cache.hit bool Whether the packet cache was hit.
dns.outgoing_queries.count int Number of outgoing queries.
dns.header.flags int DNS header flags.
dns.edns.version int EDNS version.
dns.ede int Extended DNS Error code.
dns.ede.text string Extended DNS Error text.
DNS Response RR
Attribute name Type Description
name string Name of the RR, e.g. powerdns.com.
ttl int TTL of the RR, e.g. 3600
class string Class of the RR, e.g. IN
type string Type of the RR, e.g. AAAA
rdata string Record data, e.g. 1.2.3.4

Route

Parameters which can be used to configure a dstore-dist route:

destinations:
  mydestination:
    type: pdns
    addresses:
      - another.dstoredist.endpoint.local:1234
routes:
  myroute:
    destinations:
      - mydestination
Parameter Type Required Default Description
append_tags List of string [] List of tags which will be appended to each message for this route
destinations List of string yes List of names of destinations, these must have been configured on this dstore-dist instance
filters List of Filter {} Filters to restrict which messages are sent for this route

Filters

By default, all events will be sent to a particular destination, however configuring filters for a route allows only events matching the filter to be sent.

For example the following filters configuration ensures that only events that contain the query name foo.com and are sent over IPv4 transport are sent to the destinations listed under myroute:

destinations:
  mydestination:
    type: pdns
    addresses:
      - another.dstoredist.endpoint.local:1234
routes:
  myroute:
    destinations:
      - mydestination
    filters:
      - qname: foo.com
      - is_ipv4: true

Note that the top-level filters are joined with an implicit and filter, meaning that all filters have to match for a message to reach the specified destination(s).

Matching Filters

Matching filters are used to match events based on specific information in the query/response. The list of possible filters is listed below:

Parameter Type Default Description
dst_port integer Matches the destination (to) port in the message
dst_port_gte
dst_port_gt
dst_port_lte
dst_port_lt
integer These perform integer comparisons on the dst_port field in the message
dst_port_not integer This is simply the inverse of dst_port
edns_version integer Match the edns version in the message
edns_version_gte
edns_version_gt
edns_version_lte
edns_version_lt
integer These perform integer comparisons on the edns version in the message
edns_version_not integer This is simply the inverse of edns_version
from_in_ipset string Match all messages where the from IP is in a range contained in the named IP set
has_deviceid boolean Matches if the message has a deviceid field
has_policy boolean Matches if message has an appliedPolicy field in the response
has_requestorid boolean Matches if message has a requestorID fields in the response
has_tags boolean Matches if message has any tags set
has_aa_flag boolean Matches if message has AA flag set
has_tc_flag boolean Matches if message has TC flag set
has_rd_flag boolean Matches if message has RD flag set
has_ra_flag boolean Matches if message has RA flag set
has_ad_flag boolean Matches if message has AD flag set
has_cd_flag boolean Matches if message has CD flag set
has_do_flag boolean Matches if message has DO flag set
has_otel_data boolean Matches if message has an non-empty OpenTelemetryData field
has_policy boolean Matches if message has an appliedPolicy field in the response
has_unique_domain_response boolean Matches if message has a unique domain response flag set in any response RR. Only applied to responses.
is_ipv4 boolean Matches if the DNS query was received over IPv4
is_ipv4 boolean Matches if the DNS query was received over IPv4
is_response boolean Matches if the message is a response message (as opposed to a query message)
is_query boolean Matches if the message is a query message (as opposed to a response message)
is_outgoing_query boolean Matches if the message is an outgoing query message (i.e. a query sent by a server)
is_incoming_response boolean Matches if the message is an incoming response message (i.e. in response to an outgoing query)
is_tcp boolean Matches if the DNS query was received over TCP
is_udp boolean Matches if the DNS query was received over UDP
is_newly_observed_domain boolean Matches if the DNS query was a newly observed domain
is_cache_hit boolean Matches if the DNS query was answered without performing outgoing queries
is_packet_cache_hit boolean Matches if the DNS query was answered specifically from the packet cache
latency_msec integer Matches the latency field in the message, in milliseconds
latency_msec_gte
latency_msec_gt
latency_msec_lte
latency_msec_lt
integer These perform integer comparisons on the latency_msec field in the message
latency_msec_not integer This is simply the inverse of latency_msec
meta_key string Matches if there is a meta field key with this name
meta_key_int string Matches meta field key and value, in the form key=, e.g. profile=1
meta_key_string string Matches meta field key and value, in the form key=, e.g. profile_name=foo
outgoing_queries integer Matches the number of outgoing queries this event generated
outgoing_queries_gte
outgoing_queries_gt
outgoing_queries_lte
outgoing_queries_lt
integer These perform integer comparisons on the outgoing_queries field in the message
outgoing_queries_not integer This is simply the inverse of outgoing_queries
policy_kind string Matches if the policyKind field is a match (case-insensitive). Possible values for policy_kind are none, noaction, drop, nxdomain, nodata, truncate.
policy_type string Matches if the policyType field is a match (case-insensitive). Possible values for policy_type are none, unknown, qname, clientip, responseip, nsdname, nsip.
qname string The value is a domain name; the filter matches if the query qname is an exact match (case-insensitive) for the specified domain name.
qname_sub string The value is a domain name; the filter matches if the query qname is a subdomain of the specified domain name. Matches are case-insensitive.
qtype string or integer The value matches the query resource record type of the request. It can be specified as a string or an integer, as any string will be converted to an integer using the mapping specified in https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml. If the type is very new, you may need to use the integer version.
qtype_gte
qtype_gt
qtype_lte
qtype_lt
string or integer These perform integer comparisons on qtype, after converting the type to an integer
qtype_not string or integer This is simply the inverse of qtype
requestor_id string Match if the requestor_id field is a match
reqsubnet_in_ipset string Match all messages where the 'origRequestedSubnet' IP is in a range contained in the named IP set
rcode integer Match the response code in the message (only for messages that contain a response)
rcode_gte
rcode_gt
rcode_lte
rcode_lt
integer These perform integer comparisons on the response code in the message
rcode_not integer This is simply the inverse of rcode
src_port integer Matches the source (from) port in the message
src_port_gte
src_port_gt
src_port_lte
src_port_lt
integer These perform integer comparisons on the src_port field in the message
src_port_not integer This is simply the inverse of src_port
tag string Match a specific tag
tag_prefix string Match the start of a tag

Boolean Logic Filters

The and, or and not filters are used to combine or invert matching filters to create more complex filter patterns.

Parameter Type Default Description
and List of Filter Applies a logical AND to all the specified filters
not Filter Inverts the specified filter
or List of Filter Applies a logical OR to all the specified filters

For example:

routes:
  myroute:
    destinations:
      - mydestination
    filters:
      - tag: REQUIRED_TAG
      - or:
        - tag: GAMBLING
        - tag: FASHION
      - not:
          qname: foo.com