5 releases (3 breaking)

0.5.0 Feb 28, 2023
0.4.0 Nov 8, 2022
0.3.1 Oct 12, 2022
0.3.0 Jul 11, 2022
0.1.0 Feb 12, 2022

#2430 in Command line utilities

Apache-2.0

100KB
1.5K SLoC

dnstap-utils

A collection of dnstap utilities implemented using the Rust programming language.

dnstap-replay

dnstap-replay is a dnstap collection server which receives dnstap messages from one or more DNS nameservers and replays them against a target nameserver. The responses from the target nameserver are compared against the originally logged response messages and any mismatches or other errors are made available in dnstap format via an HTTP endpoint for later analysis.

dnstap-replay: dnstap message requirements

dnstap-replay was designed for testing authoritative nameservers. The only type of dnstap log payload that dnstap-replay supports is the Message/AUTH_RESPONSE type. Any other dnstap log payload types will be silently ignored by dnstap-replay.

The following fields are required to be set in the dnstap log payload:

  • query_address
  • query_port
  • query_message
  • response_message

Typically, dnstap Message/*_RESPONSE log payloads do not include both the query_message and response_message fields on the assumption that the query message will be logged separately by a Message/*_QUERY log payload. However, this presents a problem for the replay-and-comparison phase in dnstap-replay because it is not entirely trivial to derive the original DNS query message given only the DNS response message. In some cases it may be impossible to recover the original query, for instance if the query is not a validly formatted DNS message.

For the Knot DNS server, support was added in version 3.1.4 to add a configuration option responses-with-queries to the dnstap module that logs both query and response messages together in the Message/AUTH_RESPONSE log payload type. The mod-dnstap configuration stanza in knot.conf would need to look like the following to produce dnstap output with the fields needed by dnstap-replay:

mod-dnstap:
  - id: "default"
    sink: "[...]"
    log-queries: off
    log-responses: on
    responses-with-queries: on

dnstap-replay: PROXY support in target nameserver

dnstap-replay was originally designed for testing nameservers that may have source IP address dependent behavior or configuration. When a dnstap-originated DNS query message is replayed by dnstap-replay, the target nameserver sees the source IP address of the machine running dnstap-replay on the UDP packets containing the replayed query messages. This may elicit varying DNS response message content from the target nameserver.

In order to avoid this problem, dnstap-replay can use the haproxy PROXY protocol to prepend the original source address and source port as logged in the query_address and query_port dnstap message fields to the outgoing DNS query message sent to the target nameserver. This requires support in the target nameserver. Currently, at least dnsdist, PowerDNS Authoritative Nameserver, PowerDNS Recursor, and Knot DNS have support for the PROXY header.

To enable this functionality in dnstap-replay, add the --proxy option to the command-line parameters.

Support for PROXYv2 as a connection target was added in Knot DNS version 3.2.2, which adds a configuration option proxy_allowlist that lists the IP addresses that are allowed to initiate queries with the PROXYv2 header. It is enabled by placing the option in the server configuration stanza, for instance:

server:
    []
    proxy-allowlist: 127.0.0.0/8

dnstap-replay: HTTP server

dnstap-replay includes a built-in HTTP server to export Prometheus metrics which are available at the /metrics HTTP endpoint.

When dnstap-replay sends a DNS query to the target nameserver and the response from the target nameserver does not exactly match the originally logged response message, a log message containing the mismatched response message is generated and buffered in memory and can be retrieved from the /errors HTTP endpoint. This endpoint drains the error buffer and provides the output in Frame Streams format containing dnstap payloads.

The dnstap log messages exported via the /errors endpoint are the originally logged dnstap messages received by dnstap-replay, with the dnstap extra field populated with a serialized version of the error encountered by dnstap-replay. This preserves the original DNS response message as well as the DNS response message sent by the target nameserver, which allows for byte-for-byte analysis of the mismatch.

A separate /timeouts endpoint is available which can be used to retrieve dnstap log messages that resulted in timeouts when re-querying the target nameserver. The format used is the same as the /errors endpoint.

dnstap-replay: Command-line example

dnstap-replay requires the --dns, --http, and --unix arguments to be provided.

The --dns argument specifies the IP address and port of the target nameserver which will receive replayed DNS queries.

The --http argument specifies the IP address and port for the built-in HTTP server.

The --unix argument specifies the filesystem path to bind the dnstap Unix socket to.

Additionally, there are command-line options --channel-capacity and --channel-error-capacity which allow tuning of internal buffer sizes.

For example, the following command-line invocation will listen on the filesystem path /run/dnstap.sock for incoming dnstap connections from the DNS server(s) that will send dnstap log data and on the TCP socket 127.0.0.1:53080 for incoming HTTP connections. Replayed DNS queries will be sent to the target nameserver which should be configured to listen on 127.0.0.1:53053.

    $ dnstap-replay --dns 127.0.0.1:53053 --http 127.0.0.1:53080 --unix /run/dnstap.sock

The Prometheus metrics endpoint can be accessed at http://127.0.0.1:53080/metrics.

The Frame Streams "errors" endpoint can be accessed at http://127.0.0.1:53080/errors.

The Frame Streams "timeouts" endpoint can be accessad at http://127.0.0.1:53080/timeouts.

dnstap-dump

dnstap-dump is a utility which dumps a Frame Streams formatted dnstap file to YAML. The output format is very similar to the format generated by the dnstap-ldns utility.

It has support for decoding the extra field in dnstap error payloads produced by dnstap-replay, and it also dumps DNS wire messages in hex-encoded wire format as well as in dig-style output.

fmt-dns-message

fmt-dns-message is a utility which converts a hex-encoded wire format DNS message to dig-style output using the NLnet Labs domain crate.

License

dnstap-utils is distributed under the terms of the Apache-2.0 license. See the LICENSE and NOTICE files for details.

Dependencies

~14–25MB
~371K SLoC