coredns/plugin/dnstap
Denis MACHARD 83fc3bb5da
dnstap tls support (#5917)
Signed-off-by: dmachard <5562930+dmachard@users.noreply.github.com>
2023-02-20 18:34:48 -05:00
..
msg plugin/dnstap: various cleanups (#4179) 2020-10-12 19:10:35 +02:00
encoder.go Clean up dependency on github.com/golang/protobuf (#5222) 2022-03-14 09:09:50 -07:00
handler.go auto go fmt 2022-09-12 10:30:25 +00:00
handler_test.go add golangci-lint linter (#5499) 2022-07-10 11:06:33 -07:00
io.go dnstap tls support (#5917) 2023-02-20 18:34:48 -05:00
io_test.go add golangci-lint linter (#5499) 2022-07-10 11:06:33 -07:00
log_test.go Clean up tests logging (#1979) 2018-07-19 16:23:06 +01:00
README.md dnstap tls support (#5917) 2023-02-20 18:34:48 -05:00
setup.go dnstap tls support (#5917) 2023-02-20 18:34:48 -05:00
setup_test.go dnstap tls support (#5917) 2023-02-20 18:34:48 -05:00
writer.go Fix import ordering presubmit test (#4422) 2021-01-24 17:28:49 +00:00

dnstap

Name

dnstap - enables logging to dnstap.

Description

dnstap is a flexible, structured binary log format for DNS software; see https://dnstap.info. With this plugin you make CoreDNS output dnstap logging.

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).

Syntax

dnstap SOCKET [full] {
  [identity IDENTITY]
  [version VERSION]
  [skipverify]
}
  • SOCKET is the socket (path) supplied to the dnstap command line tool.
  • 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.
  • skipverify to skip tls verification during connection. Default to be secure

Examples

Log information about client requests and responses to /tmp/dnstap.sock.

dnstap /tmp/dnstap.sock

Log information including the wire-format DNS message about client requests and responses to /tmp/dnstap.sock.

dnstap unix:///tmp/dnstap.sock full

Log to a remote endpoint.

dnstap tcp://127.0.0.1:6000 full

Log to a remote endpoint by FQDN.

dnstap tcp://example.com:6000 full

Log to a socket, overriding the default identity and version.

dnstap /tmp/dnstap.sock {
  identity my-dns-server1
  version MyDNSServer-1.2.3
}

Log to a remote TLS endpoint.

dnstap tls://127.0.0.1:6000 full {
  skipverify
}

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.

dnstap /tmp/dnstap.sock full
dnstap tcp://example.com:6000

Command Line Tool

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. It's written in Go.

The following command listens on the given socket and decodes messages to stdout.

$ dnstap -u /tmp/dnstap.sock

The following command listens on the given socket and saves message payloads to a binary dnstap-format log file.

$ dnstap -u /tmp/dnstap.sock -w /tmp/test.dnstap

Listen for dnstap messages on port 6000.

$ dnstap -l 127.0.0.1:6000

Using Dnstap in your plugin

In your setup function, collect and store a list of all dnstap plugins loaded in the config:

x :=  &ExamplePlugin{}

c.OnStartup(func() error {
    if taph := dnsserver.GetConfig(c).Handler("dnstap"); taph != nil {
        for tapPlugin, ok := taph.(*dnstap.Dnstap); ok; tapPlugin, ok = tapPlugin.Next.(*dnstap.Dnstap) {
            x.tapPlugins = append(x.tapPlugins, tapPlugin)
        }
    }
    return nil
})

And then in your plugin:

import (
  github.com/coredns/coredns/plugin/dnstap/msg
  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 {
        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)
    }
    // ...
}

See Also

The website dnstap.info has info on the dnstap protocol. The forward plugin's dnstap.go uses dnstap to tap messages sent to an upstream.