]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4759. [func] Add logging channel "trust-anchor-telementry" to
authorMark Andrews <marka@isc.org>
Fri, 6 Oct 2017 02:01:14 +0000 (13:01 +1100)
committerMark Andrews <marka@isc.org>
Fri, 6 Oct 2017 02:01:14 +0000 (13:01 +1100)
                        record trust-anchor-telementry in incoming requests.
                        Both _ta-XXXX.<anchor>/NULL and EDNS KEY-TAG options
                        are logged.  [RT #46124]

CHANGES
bin/named/statschannel.c
bin/tests/system/dnssec/tests.sh
doc/arm/logging-categories.xml
lib/ns/client.c
lib/ns/include/ns/client.h
lib/ns/include/ns/log.h
lib/ns/include/ns/stats.h
lib/ns/log.c
lib/ns/query.c

diff --git a/CHANGES b/CHANGES
index f3c54c8fc17b88b0ef80a5706e2d2c9d21428864..ebc45adca9af8c8e4087baa94822694d67e7c346 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+4759.  [func]          Add logging channel "trust-anchor-telementry" to
+                       record trust-anchor-telementry in incoming requests.
+                       Both _ta-XXXX.<anchor>/NULL and EDNS KEY-TAG options
+                       are logged.  [RT #46124]
+
 4758.  [doc]           Remove documentation of unimplemented "topology".
                        [RT #46161]
 
index 848d5e0e03723ee3b10c1c1239b137981a19d229..a8e18fd87041d8ba997c1736a6b5dd2bf5af9edd 100644 (file)
@@ -302,6 +302,7 @@ init_desc(void) {
                       "successful uses of stale cache data after lookup failure",
                       "QryUsedStale");
        SET_NSSTATDESC(prefetch, "queries triggered prefetch", "Prefetch");
+       SET_NSSTATDESC(keytagopt, "Keytag option received", "KeyTagOpt");
        INSIST(i == ns_statscounter_max);
 
        /* Initialize resolver statistics */
index e02b44cf45326b5133c0936cba49399f1ebdfaf7..8e968db64bbd3d8e7f6b95cbb35961c14f744849 100644 (file)
@@ -3315,16 +3315,24 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
-echo "I:check that trust-anchor-telemetry queries are received ($n)"
+echo "I:check that _ta-XXXX trust-anchor-telemetry queries are logged ($n)"
 ret=0
-grep "query '_ta-[0-9a-f]*/NULL/IN' approved" ns1/named.run > /dev/null || ret=1
+grep "trust-anchor-telemetry '_ta-[0-9a-f]*/IN' from" ns1/named.run > /dev/null || ret=1
 n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
-echo "I:check that trust-anchor-telemetry are not sent when disabled ($n)"
+echo "I:check that _ta-AAAA trust-anchor-telemetry are not sent when disabled ($n)"
 ret=0
-grep "sending trust-anchor-telemetry query '_ta-[0-9a-f]*/NULL" ns1/named.run > /dev/null && ret=1
+grep "sending trust-anchor-telemetry query '_ta-[0-9a-f]*/IN" ns1/named.run > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:check that KEY-TAG trust-anchor-telemetry queries are logged ($n)"
+ret=0
+$DIG $DIGOPTS . dnskey +ednsopt=KEY-TAG:ffff @10.53.0.1 > dig.out.ns4.test$n || ret=1
+grep "trust-anchor-telemetry './IN' from .* 65535" ns1/named.run > /dev/null || ret=1
 n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
index 36232edcd54f12c804a7206fbeac3852a338ed1e..62e1ed8265bc65e4061e14ce8a5e334fa1c85c06 100644 (file)
          </para>
        </entry>
       </row>
+      <row rowsep="0">
+       <entry colname="1">
+         <para><command>trust-anchor-telemetry</command></para>
+       </entry>
+       <entry colname="2">
+         <para>
+           Logs trust-anchor-telemetry requests received by named.
+         </para>
+       </entry>
+      </row>
       <row rowsep="0">
        <entry colname="1">
          <para><command>unmatched</command></para>
index d914b595aeee514b40af14f38cbd0138c0e18197..7a67ed1a6b27bae3d31d9d4ab451577bd89832bb 100644 (file)
@@ -544,6 +544,12 @@ exit_check(ns_client_t *client) {
                client->mortal = ISC_FALSE;
                client->sendcb = NULL;
 
+               if (client->keytag != NULL) {
+                       isc_mem_put(client->mctx, client->keytag,
+                                   client->keytag_len);
+                       client->keytag_len = 0;
+               }
+
                /*
                 * Put the client on the inactive list.  If we are aiming for
                 * the "freed" state, it will be removed from the inactive
@@ -612,6 +618,11 @@ exit_check(ns_client_t *client) {
                        dns_message_puttemprdataset(client->message,
                                                    &client->opt);
                }
+               if (client->keytag != NULL) {
+                       isc_mem_put(client->mctx, client->keytag,
+                                   client->keytag_len);
+                       client->keytag_len = 0;
+               }
 
                dns_message_destroy(&client->message);
 
@@ -2094,6 +2105,23 @@ process_ecs(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
        return (ISC_R_SUCCESS);
 }
 
+static isc_result_t
+process_keytag(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
+
+       if (optlen == 0 || (optlen % 2) != 0) {
+               isc_buffer_forward(buf, (unsigned int)optlen);
+               return (DNS_R_OPTERR);
+       }
+
+       client->keytag = isc_mem_get(client->mctx, optlen);
+       if (client->keytag != NULL) {
+               client->keytag_len = optlen;
+               memmove(client->keytag, isc_buffer_current(buf), optlen);
+       }
+       isc_buffer_forward(buf, (unsigned int)optlen);
+       return (ISC_R_SUCCESS);
+}
+
 static isc_result_t
 process_opt(ns_client_t *client, dns_rdataset_t *opt) {
        dns_rdata_t rdata;
@@ -2190,6 +2218,16 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
                                                   ns_statscounter_padopt);
                                isc_buffer_forward(&optbuf, optlen);
                                break;
+                       case DNS_OPT_KEY_TAG:
+                               result = process_keytag(client, &optbuf,
+                                                       optlen);
+                               if (result != ISC_R_SUCCESS) {
+                                       ns_client_error(client, result);
+                                       return (result);
+                               }
+                               ns_stats_increment(client->sctx->nsstats,
+                                                  ns_statscounter_keytagopt);
+                               break;
                        default:
                                ns_stats_increment(client->sctx->nsstats,
                                                   ns_statscounter_otheropt);
@@ -3014,6 +3052,8 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
        ISC_LINK_INIT(client, link);
        ISC_LINK_INIT(client, rlink);
        ISC_QLINK_INIT(client, ilink);
+       client->keytag = NULL;
+       client->keytag_len = 0;
 
        /*
         * We call the init routines for the various kinds of client here,
index 4b9ccf424dfba9d318f1f8363322253e6758fa3d..e5ec70dacfbeb9967fe476885c8e52477cc8fe50 100644 (file)
@@ -164,6 +164,8 @@ struct ns_client {
        ISC_QLINK(ns_client_t)  ilink;
        unsigned char           cookie[8];
        isc_uint32_t            expire;
+       unsigned char           *keytag;
+       isc_uint16_t            keytag_len;
 };
 
 typedef ISC_QUEUE(ns_client_t) client_queue_t;
index 0355e84e687294eb72df797bd91c31aeed7ecc97..d6997eb3e60183e77e2c0ebd069437884b5e1452 100644 (file)
@@ -24,6 +24,7 @@ LIBNS_EXTERNAL_DATA extern isc_logmodule_t ns_modules[];
 #define NS_LOGCATEGORY_QUERIES         (&ns_categories[3])
 #define NS_LOGCATEGORY_UPDATE_SECURITY (&ns_categories[4])
 #define NS_LOGCATEGORY_QUERY_ERRORS    (&ns_categories[5])
+#define NS_LOGCATEGORY_TAT             (&ns_categories[6])
 
 /*
  * Backwards compatibility.
index cb734f4524f0824b295c66b00cebdaaa06497ca6..61e68a197770073d5f822375a73bdb2e68c66185 100644 (file)
@@ -97,8 +97,9 @@ enum {
        ns_statscounter_usedstale = 62,
 
        ns_statscounter_prefetch = 63,
+       ns_statscounter_keytagopt = 64,
 
-       ns_statscounter_max = 64
+       ns_statscounter_max = 65
 };
 
 void
index 82860780f95865e64cbd01db6ec04502d1d5af22..741146976a86260984ea774b23fc0266edb60d77 100644 (file)
@@ -31,6 +31,7 @@ LIBNS_EXTERNAL_DATA isc_logcategory_t ns_categories[] = {
        { "unmatched",                  0 },
        { "update-security",            0 },
        { "query-errors",               0 },
+       { "trust-anchor-telemetry",     0 },
        { NULL,                         0 }
 };
 
index cf9b78e2188fa4246351a67aa59c5bc9cd8166a1..ee156efe6a31548db11542629804aa85314ea812 100644 (file)
@@ -4027,7 +4027,7 @@ rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype,
                        zbits &= allowed;
                        if (zbits != 0) {
                                isc_netaddr_fromsockaddr(&netaddr,
-                                                       &client->peeraddr);
+                                                        &client->peeraddr);
                                result = rpz_rewrite_ip(client, &netaddr, qtype,
                                                        DNS_RPZ_TYPE_CLIENT_IP,
                                                        zbits, &rdataset);
@@ -10478,6 +10478,66 @@ query_done(query_ctx_t *qctx) {
        return (qctx->result);
 }
 
+static inline void
+log_tat(ns_client_t *client) {
+       char namebuf[DNS_NAME_FORMATSIZE];
+       char clientbuf[ISC_NETADDR_FORMATSIZE];
+       char classname[DNS_RDATACLASS_FORMATSIZE];
+       isc_netaddr_t netaddr;
+       char *tags = NULL;
+       size_t taglen = 0;
+
+       if (!isc_log_wouldlog(ns_lctx, ISC_LOG_INFO)) {
+               return;
+       }
+
+       if ((client->query.qtype != dns_rdatatype_null ||
+            !dns_name_istat(client->query.qname)) &&
+           (client->keytag == NULL ||
+            client->query.qtype != dns_rdatatype_dnskey))
+       {
+               return;
+       }
+
+       isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+       dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
+       isc_netaddr_format(&client->destaddr, clientbuf, sizeof(clientbuf));
+       dns_rdataclass_format(client->view->rdclass, classname,
+                             sizeof(classname));
+
+       if (client->query.qtype == dns_rdatatype_dnskey) {
+               isc_uint16_t keytags = client->keytag_len / 2;
+               size_t len = taglen = sizeof("65000") * keytags + 1;
+               char *cp = tags = isc_mem_get(client->mctx, taglen);
+               int i = 0;
+
+               INSIST(client->keytag != NULL);
+               if (tags != NULL) {
+                       while (keytags-- > 0U) {
+                               int n;
+                               isc_uint16_t keytag;
+                               keytag = (client->keytag[i * 2] << 8) |
+                                        client->keytag[i * 2 + 1];
+                               n = snprintf(cp, len, " %u", keytag);
+                               if (n > 0 && (size_t)n <= len) {
+                                       cp += n;
+                                       len -= n;
+                                       i++;
+                               } else {
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       isc_log_write(ns_lctx, NS_LOGCATEGORY_TAT, NS_LOGMODULE_QUERY,
+                     ISC_LOG_INFO, "trust-anchor-telemetry '%s/%s' from %s%s",
+                     namebuf, classname, clientbuf, tags != NULL? tags : "");
+       if (tags != NULL) {
+               isc_mem_put(client->mctx, tags, taglen);
+       }
+}
+
 static inline void
 log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
        char namebuf[DNS_NAME_FORMATSIZE];
@@ -10691,6 +10751,8 @@ ns_query_start(ns_client_t *client) {
        client->query.qtype = qtype = rdataset->type;
        dns_rdatatypestats_increment(client->sctx->rcvquerystats, qtype);
 
+       log_tat(client);
+
        if (dns_rdatatype_ismeta(qtype)) {
                switch (qtype) {
                case dns_rdatatype_any: