2017-07-26 08:55:06 +01:00
# dnstap
2017-07-24 23:12:50 +02:00
2018-01-04 12:53:07 +00:00
## Name
2017-07-25 22:14:01 +02:00
2019-09-08 00:25:58 -07:00
*dnstap* - enables logging to dnstap.
2018-01-04 12:53:07 +00:00
## Description
2020-03-05 10:09:19 +00:00
dnstap is a flexible, structured binary log format for DNS software; see https://dnstap.info. With this
2018-01-04 12:53:07 +00:00
plugin you make CoreDNS output dnstap logging.
2020-11-03 15:31:34 +01:00
Every message is sent to the socket as soon as it comes in, the * dnstap * plugin has a buffer of
10000 messages, above that number dnstap messages will be dropped (this is logged).
2017-07-25 22:14:01 +02:00
2017-07-24 23:12:50 +02:00
## Syntax
2026-05-20 04:23:53 +02:00
### Outgoing Connections (Connect to Sink)
2017-07-25 22:14:01 +02:00
~~~ txt
2024-10-01 23:49:59 +08:00
dnstap SOCKET [full] [writebuffer] [queue] {
2022-09-07 09:22:38 -04:00
[identity IDENTITY]
[version VERSION]
2023-08-14 14:01:13 -04:00
[extra EXTRA]
2023-02-21 00:34:48 +01:00
[skipverify]
2022-09-07 09:22:38 -04:00
}
2017-07-25 22:14:01 +02:00
~~~
2017-07-24 23:12:50 +02:00
2020-11-05 14:37:16 +01:00
* **SOCKET** is the socket (path) supplied to the dnstap command line tool.
2017-07-25 22:14:01 +02:00
* `full` to include the wire-format DNS message.
2025-09-19 05:14:51 +03:00
* **writebuffer** sets the TCP write buffer multiplier in MiB. Valid range: [1, 1024].
* **queue** sets the queue multiplier, applied to 10,000 messages. Valid range: [1, 4096].
2022-09-07 09:22:38 -04:00
* **IDENTITY** to override the identity of the server. Defaults to the hostname.
* **VERSION** to override the version field. Defaults to the CoreDNS version.
2023-08-14 14:01:13 -04:00
* **EXTRA** to define "extra" field in dnstap payload, [metadata ](../metadata/ ) replacement available here.
2023-02-21 00:34:48 +01:00
* `skipverify` to skip tls verification during connection. Default to be secure
2017-07-25 22:14:01 +02:00
2026-05-20 04:23:53 +02:00
### Incoming Connections (Accept from Sinks)
~~~ txt
dnstap listen SOCKET [full] {
[identity IDENTITY]
[version VERSION]
[extra EXTRA]
[tls CERT KEY [CA]]
[skipverify]
}
~~~
* `listen` indicates this is a listening socket that accepts incoming connections from dnstap sinks.
* **SOCKET** is the socket address to listen on (e.g., `tcp://127.0.0.1:6000` , `unix:///tmp/dnstap.sock` ).
* `full` to include the wire-format DNS message.
* **IDENTITY** to override the identity of the server. Defaults to the hostname.
* **VERSION** to override the version field. Defaults to the CoreDNS version.
* **EXTRA** to define "extra" field in dnstap payload, [metadata ](../metadata/ ) replacement available here.
* `tls CERT KEY [CA]` to enable TLS for the listener. **CERT ** and **KEY ** are paths to the server certificate and key files. Optional **CA ** is the path to the CA certificate for client verification.
* `skipverify` to skip client certificate verification. Default is to verify client certificates. Equivalent to the **CA ** option above being unspecified.
**Note:** Incoming connections use unbuffered channels to broadcast events. If a connected sink becomes slow or disconnected, messages are dropped for that sink only, and the connection is closed.
2025-09-19 05:14:51 +03:00
2017-07-25 22:14:01 +02:00
## Examples
Log information about client requests and responses to * /tmp/dnstap.sock * .
~~~ txt
dnstap /tmp/dnstap.sock
~~~
2025-09-19 05:14:51 +03:00
Log information about client requests and responses with a custom TCP write buffer (1024 MiB) and queue capacity (2048 x 10000).
2024-10-01 23:49:59 +08:00
~~~ txt
dnstap /tmp/dnstap.sock full 1024 2048
~~~
2017-07-25 22:14:01 +02:00
Log information including the wire-format DNS message about client requests and responses to * /tmp/dnstap.sock * .
~~~ txt
2017-09-01 14:07:21 +02:00
dnstap unix:///tmp/dnstap.sock full
~~~
Log to a remote endpoint.
~~~ txt
dnstap tcp://127.0.0.1:6000 full
2017-07-25 22:14:01 +02:00
~~~
2017-07-24 23:12:50 +02:00
2022-05-13 02:13:26 +08:00
Log to a remote endpoint by FQDN.
~~~ txt
dnstap tcp://example.com:6000 full
~~~
2022-09-07 09:22:38 -04:00
Log to a socket, overriding the default identity and version.
~~~ txt
dnstap /tmp/dnstap.sock {
identity my-dns-server1
version MyDNSServer-1.2.3
}
~~~
2023-08-14 14:01:13 -04:00
Log to a socket, customize the "extra" field in dnstap payload. You may use metadata provided by other plugins in the extra field.
~~~ txt
forward . 8.8.8.8
metadata
dnstap /tmp/dnstap.sock {
extra "upstream: {/forward/upstream}"
}
~~~
2023-02-21 00:34:48 +01:00
Log to a remote TLS endpoint.
~~~ txt
dnstap tls://127.0.0.1:6000 full {
skipverify
}
~~~
2026-05-20 04:23:53 +02:00
Listen for incoming dnstap sink connections on a Unix socket.
~~~ txt
dnstap listen /tmp/dnstap.sock full
~~~
Listen for incoming dnstap sink connections on TCP.
~~~ txt
dnstap listen tcp://127.0.0.1:6000 full
~~~
Listen for incoming dnstap sink connections on TLS with mTLS client authentication.
~~~ txt
dnstap listen tls://127.0.0.1:6000 full {
tls /path/to/server-cert.pem /path/to/server-key.pem /path/to/ca.pem
}
~~~
Listen for incoming dnstap sink connections on TLS without client certificate verification.
~~~ txt
dnstap listen tls://127.0.0.1:6000 full {
tls /path/to/server-cert.pem /path/to/server-key.pem
skipverify
}
~~~
2022-11-28 10:33:31 -05:00
You can use _ dnstap _ more than once to define multiple taps. The following logs information including the
wire-format DNS message about client requests and responses to * /tmp/dnstap.sock * ,
and also sends client requests and responses without wire-format DNS messages to a remote FQDN.
~~~ txt
dnstap /tmp/dnstap.sock full
dnstap tcp://example.com:6000
~~~
2026-05-20 04:23:53 +02:00
You can also combine outgoing connections with incoming listeners:
~~~ txt
dnstap tcp://remote-collector.example.com:6000 full
dnstap listen tcp://127.0.0.1:6001 full
~~~
2018-01-04 12:53:07 +00:00
## Command Line Tool
2017-07-24 23:12:50 +02:00
2018-01-04 12:53:07 +00:00
Dnstap has a command line tool that can be used to inspect the logging. The tool can be found
2024-10-02 01:15:42 +09:00
at GitHub: <https://github.com/dnstap/golang-dnstap>. It's written in Go.
2017-07-24 23:12:50 +02:00
2017-07-25 22:14:01 +02:00
The following command listens on the given socket and decodes messages to stdout.
~~~ sh
2018-03-01 03:19:01 +01:00
$ dnstap -u /tmp/dnstap.sock
2017-07-25 22:14:01 +02:00
~~~
The following command listens on the given socket and saves message payloads to a binary dnstap-format log file.
~~~ sh
2018-03-01 03:19:01 +01:00
$ dnstap -u /tmp/dnstap.sock -w /tmp/test.dnstap
2017-07-25 22:14:01 +02:00
~~~
2017-09-01 14:07:21 +02:00
Listen for dnstap messages on port 6000.
~~~ sh
2018-03-01 03:19:01 +01:00
$ dnstap -l 127.0.0.1:6000
~~~
## Using Dnstap in your plugin
2022-11-28 10:33:31 -05:00
In your setup function, collect and store a list of all * dnstap * plugins loaded in the config:
2020-10-12 19:10:35 +02:00
~~~ go
2022-11-28 10:33:31 -05:00
x := &ExamplePlugin{}
2020-10-12 19:10:35 +02:00
c.OnStartup(func() error {
if taph := dnsserver.GetConfig(c).Handler("dnstap"); taph != nil {
2023-01-31 03:38:15 +08:00
for tapPlugin, ok := taph.(*dnstap.Dnstap); ok; tapPlugin, ok = tapPlugin.Next.(*dnstap.Dnstap) {
x.tapPlugins = append(x.tapPlugins, tapPlugin)
2018-03-01 03:19:01 +01:00
}
}
2020-10-12 19:10:35 +02:00
return nil
})
~~~
2018-03-01 03:19:01 +01:00
2020-10-12 19:10:35 +02:00
And then in your plugin:
~~~ go
2022-11-28 10:33:31 -05:00
import (
2023-08-14 14:01:13 -04:00
"github.com/coredns/coredns/plugin/dnstap/msg"
"github.com/coredns/coredns/request"
2022-11-28 10:33:31 -05:00
tap "github.com/dnstap/golang-dnstap"
)
func (x ExamplePlugin) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
for _, tapPlugin := range x.tapPlugins {
2020-10-12 19:10:35 +02:00
q := new(msg.Msg)
msg.SetQueryTime(q, time.Now())
msg.SetQueryAddress(q, w.RemoteAddr())
if tapPlugin.IncludeRawMessage {
buf, _ := r.Pack() // r has been seen packed/unpacked before, this should not fail
q.QueryMessage = buf
}
msg.SetType(q, tap.Message_CLIENT_QUERY)
2023-08-14 14:01:13 -04:00
// if no metadata interpretation is needed, just send the message
2020-10-12 19:10:35 +02:00
tapPlugin.TapMessage(q)
2023-08-14 14:01:13 -04:00
// OR: to interpret the metadata in "extra" field, give more context info
tapPlugin.TapMessageWithMetadata(ctx, q, request.Request{W: w, Req: query})
2020-10-12 19:10:35 +02:00
}
2018-03-01 03:19:01 +01:00
// ...
}
2017-09-01 14:07:21 +02:00
~~~
2018-01-04 12:53:07 +00:00
2018-01-10 11:45:12 +00:00
## See Also
2018-01-04 12:53:07 +00:00
2020-11-03 15:31:34 +01:00
The website [dnstap.info ](https://dnstap.info ) has info on the dnstap protocol. The * forward *
plugin's `dnstap.go` uses dnstap to tap messages sent to an upstream.