// dnstap: flexible, structured event replication format for DNS software // // This file contains the protobuf schemas for the "dnstap" structured event // replication format for DNS software. // Written in 2013-2014 by Farsight Security, Inc. // // To the extent possible under law, the author(s) have dedicated all // copyright and related and neighboring rights to this file to the public // domain worldwide. This file is distributed without any warranty. // // You should have received a copy of the CC0 Public Domain Dedication along // with this file. If not, see: // // . syntax = "proto2"; package dnstap; // "Dnstap": this is the top-level dnstap type, which is a "union" type that // contains other kinds of dnstap payloads, although currently only one type // of dnstap payload is defined. // See: https://developers.google.com/protocol-buffers/docs/techniques#union message Dnstap { // DNS server identity. // If enabled, this is the identity string of the DNS server which generated // this message. Typically this would be the same string as returned by an // "NSID" (RFC 5001) query. optional bytes identity = 1; // DNS server version. // If enabled, this is the version string of the DNS server which generated // this message. Typically this would be the same string as returned by a // "version.bind" query. optional bytes version = 2; // Extra data for this payload. // This field can be used for adding an arbitrary byte-string annotation to // the payload. No encoding or interpretation is applied or enforced. optional bytes extra = 3; // Identifies which field below is filled in. enum Type { MESSAGE = 1; } required Type type = 15; // One of the following will be filled in. optional Message message = 14; } // SocketFamily: the network protocol family of a socket. This specifies how // to interpret "network address" fields. enum SocketFamily { INET = 1; // IPv4 (RFC 791) INET6 = 2; // IPv6 (RFC 2460) } // SocketProtocol: the protocol used to transport a DNS message. enum SocketProtocol { UDP = 1; // DNS over UDP transport (RFC 1035 section 4.2.1) TCP = 2; // DNS over TCP transport (RFC 1035 section 4.2.2) DOT = 3; // DNS over TLS (RFC 7858) DOH = 4; // DNS over HTTPS (RFC 8484) DNSCryptUDP = 5; // DNSCrypt over UDP (https://dnscrypt.info/protocol) DNSCryptTCP = 6; // DNSCrypt over TCP (https://dnscrypt.info/protocol) DOQ = 7; // DNS over QUIC (RFC 9250) } // Policy: information about any name server operator policy // applied to the processing of a DNS message. message Policy { // Match: what aspect of the message or message exchange // triggered the application of the Policy. enum Match { QNAME = 1; // Name in question section of query CLIENT_IP = 2; // Client IP address RESPONSE_IP = 3; // Address in A/AAAA RRSet NS_NAME = 4; // Authoritative name server, by name NS_IP = 5; // Authoritative name server, by IP address } // The Action taken to implement the Policy. enum Action { NXDOMAIN = 1; // Respond with NXDOMAIN NODATA = 2; // Respond with empty answer section PASS = 3; // Do not alter the response (passthrough) DROP = 4; // Do not respond. TRUNCATE = 5; // Truncate UDP response, forcing TCP retry LOCAL_DATA = 6; // Respond with local data from policy } // type: the type of policy applied, e.g. "RPZ" for a // policy from a Response Policy Zone. optional string type = 1; // rule: the rule matched by the message. // // In a RPZ context, this is the owner name of the rule in // the Reponse Policy Zone in wire format. optional bytes rule = 2; // action: the policy action taken in response to the // rule match. optional Action action = 3; // match: the feature of the message exchange which matched the rule. optional Match match = 4; // The matched value. Format depends on the matched feature . optional bytes value = 5; } // Message: a wire-format (RFC 1035 section 4) DNS message and associated // metadata. Applications generating "Message" payloads should follow // certain requirements based on the MessageType, see below. message Message { // 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. enum Type { // AUTH_QUERY is a DNS query message received from a resolver by an // authoritative name server, from the perspective of the authoritative // name server. AUTH_QUERY = 1; // AUTH_RESPONSE is a DNS response message sent from an authoritative // name server to a resolver, from the perspective of the authoritative // name server. AUTH_RESPONSE = 2; // RESOLVER_QUERY is a DNS query message sent from a resolver to an // authoritative name server, from the perspective of the resolver. // Resolvers typically clear the RD (recursion desired) bit when // sending queries. RESOLVER_QUERY = 3; // RESOLVER_RESPONSE is a DNS response message received from an // authoritative name server by a resolver, from the perspective of // the resolver. RESOLVER_RESPONSE = 4; // CLIENT_QUERY is a DNS query message sent from a client to a DNS // server which is expected to perform further recursion, from the // perspective of the DNS server. The client may be a stub resolver or // forwarder or some other type of software which typically sets the RD // (recursion desired) bit when querying the DNS server. The DNS server // may be a simple forwarding proxy or it may be a full recursive // resolver. CLIENT_QUERY = 5; // CLIENT_RESPONSE is a DNS response message sent from a DNS server to // a client, from the perspective of the DNS server. The DNS server // typically sets the RA (recursion available) bit when responding. CLIENT_RESPONSE = 6; // FORWARDER_QUERY is a DNS query message sent from a downstream DNS // server to an upstream DNS server which is expected to perform // further recursion, from the perspective of the downstream DNS // server. FORWARDER_QUERY = 7; // FORWARDER_RESPONSE is a DNS response message sent from an upstream // DNS server performing recursion to a downstream DNS server, from the // perspective of the downstream DNS server. FORWARDER_RESPONSE = 8; // STUB_QUERY is a DNS query message sent from a stub resolver to a DNS // server, from the perspective of the stub resolver. STUB_QUERY = 9; // STUB_RESPONSE is a DNS response message sent from a DNS server to a // stub resolver, from the perspective of the stub resolver. STUB_RESPONSE = 10; // TOOL_QUERY is a DNS query message sent from a DNS software tool to a // DNS server, from the perspective of the tool. TOOL_QUERY = 11; // TOOL_RESPONSE is a DNS response message received by a DNS software // tool from a DNS server, from the perspective of the tool. TOOL_RESPONSE = 12; // UPDATE_QUERY is a Dynamic DNS Update request (RFC 2136) received // by an authoritative name server, from the perspective of the // authoritative name server. UPDATE_QUERY = 13; // UPDATE_RESPONSE is a Dynamic DNS Update response (RFC 2136) sent // from an authoritative name server, from the perspective of the // authoritative name server. UPDATE_RESPONSE = 14; } // One of the Type values described above. required Type type = 1; // One of the SocketFamily values described above. optional SocketFamily socket_family = 2; // One of the SocketProtocol values described above. optional SocketProtocol socket_protocol = 3; // The network address of the message initiator. // For SocketFamily INET, this field is 4 octets (IPv4 address). // For SocketFamily INET6, this field is 16 octets (IPv6 address). optional bytes query_address = 4; // The network address of the message responder. // For SocketFamily INET, this field is 4 octets (IPv4 address). // For SocketFamily INET6, this field is 16 octets (IPv6 address). optional bytes response_address = 5; // The transport port of the message initiator. // This is a 16-bit UDP or TCP port number, depending on SocketProtocol. optional uint32 query_port = 6; // The transport port of the message responder. // This is a 16-bit UDP or TCP port number, depending on SocketProtocol. optional uint32 response_port = 7; // The time at which the DNS query message was sent or received, depending // on whether this is an AUTH_QUERY, RESOLVER_QUERY, or CLIENT_QUERY. // This is the number of seconds since the UNIX epoch. optional uint64 query_time_sec = 8; // The time at which the DNS query message was sent or received. // This is the seconds fraction, expressed as a count of nanoseconds. optional fixed32 query_time_nsec = 9; // The initiator's original wire-format DNS query message, verbatim. optional bytes query_message = 10; // The "zone" or "bailiwick" pertaining to the DNS query message. // This is a wire-format DNS domain name. optional bytes query_zone = 11; // The time at which the DNS response message was sent or received, // depending on whether this is an AUTH_RESPONSE, RESOLVER_RESPONSE, or // CLIENT_RESPONSE. // This is the number of seconds since the UNIX epoch. optional uint64 response_time_sec = 12; // The time at which the DNS response message was sent or received. // This is the seconds fraction, expressed as a count of nanoseconds. optional fixed32 response_time_nsec = 13; // The responder's original wire-format DNS response message, verbatim. optional bytes response_message = 14; // Operator policy applied to the processing of this message, if any. optional Policy policy = 15; } // All fields except for 'type' in the Message schema are optional. // It is recommended that at least the following fields be filled in for // particular types of Messages. // AUTH_QUERY: // socket_family, socket_protocol // query_address, query_port // query_message // query_time_sec, query_time_nsec // AUTH_RESPONSE: // socket_family, socket_protocol // query_address, query_port // query_time_sec, query_time_nsec // response_message // response_time_sec, response_time_nsec // RESOLVER_QUERY: // socket_family, socket_protocol // query_message // query_time_sec, query_time_nsec // query_zone // response_address, response_port // RESOLVER_RESPONSE: // socket_family, socket_protocol // query_time_sec, query_time_nsec // query_zone // response_address, response_port // response_message // response_time_sec, response_time_nsec // CLIENT_QUERY: // socket_family, socket_protocol // query_message // query_time_sec, query_time_nsec // CLIENT_RESPONSE: // socket_family, socket_protocol // query_time_sec, query_time_nsec // response_message // response_time_sec, response_time_nsec