DNSTap For BIND Basic

Posted by Henry Du on Monday, October 5, 2020

DNSTap Basic

Introduction

DNSTap is a fast, flexible method for capturing and logging DNS traffic. Developed by Robert Edmonds at Farsight Security, Inc., and supported by multiple DNS implementations, dnstap uses libfstrm (a lightweight high-speed framing library, see https://github.com/farsightsec/fstrm) to send event payloads which are encoded using Protocol Buffers (libprotobuf-c, a mechanism for serializing structured data developed by Google, Inc.; see https://developers.google.com/protocol-buffers).

Enable DNSTap for BIND

To enable dnstap at BIND compile time, the fstrm and protobuf-c libraries must be available, and BIND must be configured with –enable-dnstap.

The dnstap option is a bracketed list of message types to be logged. These may be set differently for each view. Supported types are client, auth, resolver, and forwarder. Specifying type all causes all dnstap messages to be logged, regardless of type.

Each type may take an additional argument to indicate whether to log query messages or response messages; if not specified, both queries and responses are logged.

Example: To log all authoritative queries and responses, recursive client responses, and upstream queries sent by the resolver, use:

dnstap {
  auth;
  client response;
  resolver query;
};

The following configuration is another DNSTap example configured in named.conf

dnstap {
        auth;
        client;
        forwarder;
        resolver;
    };
    dnstap-identity "site_id:0e4e035fcf2c4f1096443ad75aefc45e";
    dnstap-output unix "/var/run/dnstap/dnstap.sock";

DNSTap Protobuf Schema

According to DNStap protobuf definition, the message was described below

    // There are eight types of "Message" defined that correspond to the
    // four arrows in the following diagram, slightly modified from RFC 1035
    // section 2:

    //    +---------+               +----------+           +--------+
    //    |         |     query     |          |   query   |        |
    //    | Stub    |-SQ--------CQ->| Recursive|-RQ----AQ->| Auth.  |
    //    | Resolver|               | Server   |           | Name   |
    //    |         |<-SR--------CR-|          |<-RR----AR-| Server |
    //    +---------+    response   |          |  response |        |
    //                              +----------+           +--------+

    // Each arrow has two Type values each, one for each "end" of each arrow,
    // because these are considered to be distinct events. Each end of each
    // arrow on the diagram above has been marked with a two-letter Type
    // mnemonic. Clockwise from upper left, these mnemonic values are:
    //
    //   SQ:        STUB_QUERY
    //   CQ:      CLIENT_QUERY
    //   RQ:    RESOLVER_QUERY
    //   AQ:        AUTH_QUERY
    //   AR:        AUTH_RESPONSE
    //   RR:    RESOLVER_RESPONSE
    //   CR:      CLIENT_RESPONSE
    //   SR:        STUB_RESPONSE

    // Two additional types of "Message" have been defined for the
    // "forwarding" case where an upstream DNS server is responsible for
    // further recursion. These are not shown on the diagram above, but have
    // the following mnemonic values:

    //   FQ:   FORWARDER_QUERY
    //   FR:   FORWARDER_RESPONSE

    // The "Message" Type values are defined below.

DNSTap Read

Logged dnstap messages can be parsed using the dnstap-read utility (dnstap-read -y your_dnstap_binary_file). The following snippet is human readable format messages.

type: MESSAGE
identity: site_id:0e4e035fcf2c4f1096443ad75aefc45e
version: BIND 9.11.5-S6
message:
  type: RESOLVER_QUERY
  query_time: !!timestamp 2020-10-01T20:48:18Z
  message_size: 40b
  socket_family: INET
  socket_protocol: UDP
  query_address: 172.28.5.240
  response_address: 199.9.14.201
  query_port: 44651
  response_port: 53
  query_message_data:
    opcode: QUERY
    status: NOERROR
    id:   3186
    flags: cd
    QUESTION: 1
    ANSWER: 0
    AUTHORITY: 0
    ADDITIONAL: 1
    OPT_PSEUDOSECTION:
      EDNS:
        version: 0
        flags: do
        udp: 512
        COOKIE: a9cd8f4c675a744f
    QUESTION_SECTION:
      - . IN DNSKEY
  query_message: |
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id:   3186
    ;; flags: cd    ; QUESTION: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags: do; udp: 512
    ; COOKIE: a9cd8f4c675a744f
    ;; QUESTION SECTION:
    ;.				IN	DNSKEY
    
---
type: MESSAGE
identity: site_id:0e4e035fcf2c4f1096443ad75aefc45e
version: BIND 9.11.5-S6
message:
  type: RESOLVER_QUERY
  query_time: !!timestamp 2020-10-01T20:48:18Z
  message_size: 40b
  socket_family: INET
  socket_protocol: UDP
  query_address: 172.28.5.240
  response_address: 199.9.14.201
  query_port: 43603
  response_port: 53
  query_message_data:
    opcode: QUERY
    status: NOERROR
    id:  16002
    flags:
    QUESTION: 1
    ANSWER: 0
    AUTHORITY: 0
    ADDITIONAL: 1
    OPT_PSEUDOSECTION:
      EDNS:
        version: 0
        flags: do
        udp: 512
        COOKIE: a9cd8f4c675a744f
    QUESTION_SECTION:
      - . IN NS
  query_message: |
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id:  16002
    ;; flags:    ; QUESTION: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags: do; udp: 512
    ; COOKIE: a9cd8f4c675a744f
    ;; QUESTION SECTION:
    ;.				IN	NS
    
---

Reference

  1. For more information on dnstap, see http://dnstap.info.
  2. DNS Query response logging with DNSTap