From 4b9cd8e81d7b0e883d4521ed764180c5c484ae13 Mon Sep 17 00:00:00 2001 From: k-akashi Date: Wed, 27 Dec 2023 07:26:21 +0900 Subject: [PATCH] Add DoH and DoT to dnstap message --- daemon/worker.c | 4 +- dnstap/dnstap.c | 25 +++++++++--- dnstap/dnstap.h | 4 ++ dnstap/dnstap.proto | 82 ++++++++++++++++++++++++++++++++++---- services/outside_network.c | 10 ++--- util/netevent.c | 4 +- 6 files changed, 108 insertions(+), 21 deletions(-) diff --git a/daemon/worker.c b/daemon/worker.c index e52513f74..aeadf32d4 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1464,7 +1464,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, if(worker->dtenv.log_client_query_messages) { log_addr(VERB_ALGO, "request from client", &repinfo->client_addr, repinfo->client_addrlen); log_addr(VERB_ALGO, "to local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen); - dt_msg_send_client_query(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->buffer, + dt_msg_send_client_query(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->ssl, c->buffer, ((worker->env.cfg->sock_queue_timeout && timeval_isset(&c->recv_tv))?&c->recv_tv:NULL)); } #endif @@ -1953,7 +1953,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, if(worker->dtenv.log_client_response_messages) { log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen); log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen); - dt_msg_send_client_response(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->buffer); + dt_msg_send_client_response(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->ssl, c->buffer); } #endif if(worker->env.cfg->log_replies) diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index d9cdf7cea..5cdda0c2d 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -305,6 +305,7 @@ dt_msg_fill_net(struct dt_msg *dm, struct sockaddr_storage *qs, struct sockaddr_storage *rs, enum comm_point_type cptype, + void *cpssl, ProtobufCBinaryData *qaddr, protobuf_c_boolean *has_qaddr, uint32_t *qport, protobuf_c_boolean *has_qport, ProtobufCBinaryData *raddr, protobuf_c_boolean *has_raddr, @@ -376,8 +377,18 @@ dt_msg_fill_net(struct dt_msg *dm, dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP; dm->m.has_socket_protocol = 1; } else if (cptype == comm_tcp) { + if (cpssl == NULL) { + /* socket_protocol */ + dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP; + dm->m.has_socket_protocol = 1; + } else { + /* socket_protocol */ + dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__DOT; + dm->m.has_socket_protocol = 1; + } + } else if (cptype == comm_http) { /* socket_protocol */ - dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP; + dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__DOH; dm->m.has_socket_protocol = 1; } else { /* other socket protocol */ @@ -391,6 +402,7 @@ dt_msg_send_client_query(struct dt_env *env, struct sockaddr_storage *qsock, struct sockaddr_storage *rsock, enum comm_point_type cptype, + void *cpssl, sldns_buffer *qmsg, struct timeval* tstamp) { @@ -413,7 +425,7 @@ dt_msg_send_client_query(struct dt_env *env, dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message); /* socket_family, socket_protocol, query_address, query_port, response_address, response_port */ - dt_msg_fill_net(&dm, qsock, rsock, cptype, + dt_msg_fill_net(&dm, qsock, rsock, cptype, cpssl, &dm.m.query_address, &dm.m.has_query_address, &dm.m.query_port, &dm.m.has_query_port, &dm.m.response_address, &dm.m.has_response_address, @@ -429,6 +441,7 @@ dt_msg_send_client_response(struct dt_env *env, struct sockaddr_storage *qsock, struct sockaddr_storage *rsock, enum comm_point_type cptype, + void *cpssl, sldns_buffer *rmsg) { struct dt_msg dm; @@ -448,7 +461,7 @@ dt_msg_send_client_response(struct dt_env *env, dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message); /* socket_family, socket_protocol, query_address, query_port, response_address, response_port */ - dt_msg_fill_net(&dm, qsock, rsock, cptype, + dt_msg_fill_net(&dm, qsock, rsock, cptype, cpssl, &dm.m.query_address, &dm.m.has_query_address, &dm.m.query_port, &dm.m.has_query_port, &dm.m.response_address, &dm.m.has_response_address, @@ -463,6 +476,7 @@ dt_msg_send_outside_query(struct dt_env *env, struct sockaddr_storage *rsock, struct sockaddr_storage *qsock, enum comm_point_type cptype, + void *cpssl, uint8_t *zone, size_t zone_len, sldns_buffer *qmsg) { @@ -498,7 +512,7 @@ dt_msg_send_outside_query(struct dt_env *env, dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message); /* socket_family, socket_protocol, response_address, response_port, query_address, query_port */ - dt_msg_fill_net(&dm, rsock, qsock, cptype, + dt_msg_fill_net(&dm, rsock, qsock, cptype, cpssl, &dm.m.response_address, &dm.m.has_response_address, &dm.m.response_port, &dm.m.has_response_port, &dm.m.query_address, &dm.m.has_query_address, @@ -513,6 +527,7 @@ dt_msg_send_outside_response(struct dt_env *env, struct sockaddr_storage *rsock, struct sockaddr_storage *qsock, enum comm_point_type cptype, + void *cpssl, uint8_t *zone, size_t zone_len, uint8_t *qbuf, size_t qbuf_len, const struct timeval *qtime, @@ -556,7 +571,7 @@ dt_msg_send_outside_response(struct dt_env *env, dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message); /* socket_family, socket_protocol, response_address, response_port, query_address, query_port */ - dt_msg_fill_net(&dm, rsock, qsock, cptype, + dt_msg_fill_net(&dm, rsock, qsock, cptype, cpssl, &dm.m.response_address, &dm.m.has_response_address, &dm.m.response_port, &dm.m.has_response_port, &dm.m.query_address, &dm.m.has_query_address, diff --git a/dnstap/dnstap.h b/dnstap/dnstap.h index 169bdc2c6..77914c20c 100644 --- a/dnstap/dnstap.h +++ b/dnstap/dnstap.h @@ -133,6 +133,7 @@ dt_msg_send_client_query(struct dt_env *env, struct sockaddr_storage *qsock, struct sockaddr_storage *rsock, enum comm_point_type cptype, + void *cpssl, struct sldns_buffer *qmsg, struct timeval* tstamp); @@ -149,6 +150,7 @@ dt_msg_send_client_response(struct dt_env *env, struct sockaddr_storage *qsock, struct sockaddr_storage *rsock, enum comm_point_type cptype, + void *cpssl, struct sldns_buffer *rmsg); /** @@ -168,6 +170,7 @@ dt_msg_send_outside_query(struct dt_env *env, struct sockaddr_storage *rsock, struct sockaddr_storage *qsock, enum comm_point_type cptype, + void *cpssl, uint8_t *zone, size_t zone_len, struct sldns_buffer *qmsg); @@ -192,6 +195,7 @@ dt_msg_send_outside_response(struct dt_env *env, struct sockaddr_storage *rsock, struct sockaddr_storage *qsock, enum comm_point_type cptype, + void *cpssl, uint8_t *zone, size_t zone_len, uint8_t *qbuf, size_t qbuf_len, const struct timeval *qtime, diff --git a/dnstap/dnstap.proto b/dnstap/dnstap.proto index 88bfb4e94..dfc8ad411 100644 --- a/dnstap/dnstap.proto +++ b/dnstap/dnstap.proto @@ -13,8 +13,8 @@ // with this file. If not, see: // // . -syntax = "proto2"; +syntax = "proto2"; package dnstap; // "Dnstap": this is the top-level dnstap type, which is a "union" type that @@ -56,11 +56,60 @@ enum SocketFamily { INET6 = 2; // IPv6 (RFC 2460) } -// SocketProtocol: the transport protocol of a socket. This specifies how to -// interpret "transport port" fields. +// SocketProtocol: the protocol used to transport a DNS message. enum SocketProtocol { - UDP = 1; // User Datagram Protocol (RFC 768) - TCP = 2; // Transmission Control Protocol (RFC 793) + 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 @@ -158,6 +207,24 @@ message Message { // 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. @@ -215,6 +282,9 @@ message Message { // 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. @@ -236,7 +306,6 @@ message Message { // RESOLVER_QUERY: // socket_family, socket_protocol -// query_name, query_type, query_class // query_message // query_time_sec, query_time_nsec // query_zone @@ -244,7 +313,6 @@ message Message { // RESOLVER_RESPONSE: // socket_family, socket_protocol -// query_name, query_type, query_class // query_time_sec, query_time_nsec // query_zone // response_address, response_port diff --git a/services/outside_network.c b/services/outside_network.c index 12923f07d..c3a6a1638 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -1009,7 +1009,7 @@ use_free_buffer(struct outside_network* outnet) sldns_buffer tmp; sldns_buffer_init_frm_data(&tmp, w->pkt, w->pkt_len); dt_msg_send_outside_query(outnet->dtenv, &w->sq->addr, - &pend_tcp->pi->addr, comm_tcp, w->sq->zone, + &pend_tcp->pi->addr, comm_tcp, NULL, w->sq->zone, w->sq->zonelen, &tmp); } #endif @@ -2237,7 +2237,7 @@ randomize_and_send_udp(struct pending* pend, sldns_buffer* packet, int timeout) outnet->dtenv->log_forwarder_query_messages)) { log_addr(VERB_ALGO, "from local addr", &pend->pc->pif->addr, pend->pc->pif->addrlen); log_addr(VERB_ALGO, "request to upstream", &pend->addr, pend->addrlen); - dt_msg_send_outside_query(outnet->dtenv, &pend->addr, &pend->pc->pif->addr, comm_udp, + dt_msg_send_outside_query(outnet->dtenv, &pend->addr, &pend->pc->pif->addr, comm_udp, NULL, pend->sq->zone, pend->sq->zonelen, packet); } #endif @@ -2517,7 +2517,7 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet, sldns_buffer tmp; sldns_buffer_init_frm_data(&tmp, w->pkt, w->pkt_len); dt_msg_send_outside_query(sq->outnet->dtenv, &sq->addr, - &pend->pi->addr, comm_tcp, sq->zone, + &pend->pi->addr, comm_tcp, NULL, sq->zone, sq->zonelen, &tmp); } #endif @@ -3083,7 +3083,7 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error, log_addr(VERB_ALGO, "response from upstream", &sq->addr, sq->addrlen); log_addr(VERB_ALGO, "to local addr", &pi->addr, pi->addrlen); dt_msg_send_outside_response(sq->outnet->dtenv, &sq->addr, - &pi->addr, c->type, sq->zone, sq->zonelen, sq->qbuf, + &pi->addr, c->type, c->ssl, sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen, &sq->last_sent_time, sq->outnet->now_tv, c->buffer); } @@ -3296,7 +3296,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, log_addr(VERB_ALGO, "to local addr", &p->pc->pif->addr, p->pc->pif->addrlen); dt_msg_send_outside_response(outnet->dtenv, &sq->addr, - &p->pc->pif->addr, c->type, sq->zone, sq->zonelen, + &p->pc->pif->addr, c->type, c->ssl, sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen, &sq->last_sent_time, sq->outnet->now_tv, c->buffer); } diff --git a/util/netevent.c b/util/netevent.c index 141e48d48..baa79d746 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -4766,7 +4766,7 @@ comm_point_send_reply(struct comm_reply *repinfo) if(repinfo->c->dtenv != NULL && repinfo->c->dtenv->log_client_response_messages) { log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen); log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen); - dt_msg_send_client_response(repinfo->c->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->buffer); + dt_msg_send_client_response(repinfo->c->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->ssl, repinfo->c->buffer); } #endif } else { @@ -4777,7 +4777,7 @@ comm_point_send_reply(struct comm_reply *repinfo) if(repinfo->c->tcp_parent->dtenv != NULL && repinfo->c->tcp_parent->dtenv->log_client_response_messages) { log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen); log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen); - dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, + dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->ssl, ( repinfo->c->tcp_req_info? repinfo->c->tcp_req_info->spool_buffer: repinfo->c->buffer )); } #endif