.\" Generated by Mmark Markdown Processer - mmark.miek.nl .TH "COREDNS-DNSTAP" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP \fIdnstap\fP - enables logging to dnstap. .SH "DESCRIPTION" .PP dnstap is a flexible, structured binary log format for DNS software; see https://dnstap.info \[la]https://dnstap.info\[ra]. With this plugin you make CoreDNS output dnstap logging. .PP Every message is sent to the socket as soon as it comes in, the \fIdnstap\fP plugin has a buffer of 10000 messages, above that number dnstap messages will be dropped (this is logged). .SH "SYNTAX" .PP .RS .nf dnstap SOCKET [full] .fi .RE .IP \(bu 4 \fBSOCKET\fP is the socket (path) supplied to the dnstap command line tool. .IP \(bu 4 \fB\fCfull\fR to include the wire-format DNS message. .SH "EXAMPLES" .PP Log information about client requests and responses to \fI/tmp/dnstap.sock\fP. .PP .RS .nf dnstap /tmp/dnstap.sock .fi .RE .PP Log information including the wire-format DNS message about client requests and responses to \fI/tmp/dnstap.sock\fP. .PP .RS .nf dnstap unix:///tmp/dnstap.sock full .fi .RE .PP Log to a remote endpoint. .PP .RS .nf dnstap tcp://127.0.0.1:6000 full .fi .RE .SH "COMMAND LINE TOOL" .PP Dnstap has a command line tool that can be used to inspect the logging. The tool can be found at Github: https://github.com/dnstap/golang-dnstap \[la]https://github.com/dnstap/golang-dnstap\[ra]. It's written in Go. .PP The following command listens on the given socket and decodes messages to stdout. .PP .RS .nf $ dnstap \-u /tmp/dnstap.sock .fi .RE .PP The following command listens on the given socket and saves message payloads to a binary dnstap-format log file. .PP .RS .nf $ dnstap \-u /tmp/dnstap.sock \-w /tmp/test.dnstap .fi .RE .PP Listen for dnstap messages on port 6000. .PP .RS .nf $ dnstap \-l 127.0.0.1:6000 .fi .RE .SH "USING DNSTAP IN YOUR PLUGIN" .PP In your setup function, check to see if the \fIdnstap\fP plugin is loaded: .PP .RS .nf c.OnStartup(func() error { if taph := dnsserver.GetConfig(c).Handler("dnstap"); taph != nil { if tapPlugin, ok := taph.(dnstap.Dnstap); ok { f.tapPlugin = \&tapPlugin } } return nil }) .fi .RE .PP And then in your plugin: .PP .RS .nf func (x RandomPlugin) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { if tapPlugin != nil { 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) tapPlugin.TapMessage(q) } // ... } .fi .RE .SH "SEE ALSO" .PP The website dnstap.info \[la]https://dnstap.info\[ra] has info on the dnstap protocol. The \fIforward\fP plugin's \fB\fCdnstap.go\fR uses dnstap to tap messages sent to an upstream.