]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Reject NSEC records with next field with \000 label
authorMark Andrews <marka@isc.org>
Wed, 1 Dec 2021 13:34:38 +0000 (00:34 +1100)
committerPetr Špaček <pspacek@isc.org>
Thu, 2 Dec 2021 13:27:18 +0000 (14:27 +0100)
A number of DNS implementation produce NSEC records with bad type
maps that don't contain types that exist at the name leading to
NODATA responses being synthesize instead of the records in the
zone.  NSEC records with these bad type maps often have the NSEC
NSEC field set to '\000.QNAME'.  We look for the first label of
this pattern.

e.g.
example.com NSEC \000.example.com SOA NS NSEC RRSIG
example.com RRRSIG NSEC ...
example.com SOA ...
example.com RRRSIG SOA ...
example.com NS ...
example.com RRRSIG NS ...
example.com A ...
example.com RRRSIG A ...

A is missing from the type map.

This introduces a temporary option 'reject-000-label' to control
this behaviour.

12 files changed:
bin/named/config.c
bin/named/named.conf.rst
bin/named/server.c
doc/arm/reference.rst
doc/man/named.conf.5in
doc/misc/options
doc/misc/options.active
doc/misc/options.grammar.rst
lib/dns/include/dns/view.h
lib/dns/resolver.c
lib/dns/view.c
lib/isccfg/namedconf.c

index 6a8fc599fb71b5827bf31940a6e26e94b844bab7..e93ad273edbff87265831cf2fd50dd910eb9e205 100644 (file)
@@ -177,6 +177,7 @@ options {\n\
        query-source address *;\n\
        query-source-v6 address *;\n\
        recursion true;\n\
+       reject-000-label yes;\n\
        request-expire true;\n\
        request-ixfr true;\n\
        require-server-cookie no;\n\
index f02d52d42567064dd5be02e18cad560b44dc587c..6c1ec9b260106cc737bcef0b46057c5f1dd82802 100644 (file)
@@ -388,6 +388,7 @@ OPTIONS
        recursing-file quoted_string;
        recursion boolean;
        recursive-clients integer;
+       reject-000-label boolean;// deprecated
        request-expire boolean;
        request-ixfr boolean;
        request-nsid boolean;
@@ -793,6 +794,7 @@ VIEW
                window integer;
        };
        recursion boolean;
+       reject-000-label boolean;// deprecated
        request-expire boolean;
        request-ixfr boolean;
        request-nsid boolean;
index 852d7dbf54f0d7a0de2c969d317c7e1ed49645f7..f7db73faf9349a55c1338e287e94b395fc478b71 100644 (file)
@@ -4456,6 +4456,11 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
        INSIST(result == ISC_R_SUCCESS);
        view->acceptexpired = cfg_obj_asboolean(obj);
 
+       obj = NULL;
+       result = named_config_get(maps, "reject-000-label", &obj);
+       INSIST(result == ISC_R_SUCCESS);
+       view->reject_000_label = cfg_obj_asboolean(obj);
+
        obj = NULL;
        /* 'optionmaps', not 'maps': don't check named_g_defaults yet */
        (void)named_config_get(optionmaps, "dnssec-validation", &obj);
index 279ae583d3b752c14bd8ed14344160b12d9ed804..97f4e925945a8a61bc2b97a18b2b7906d28a53dc 100644 (file)
@@ -2100,6 +2100,16 @@ Boolean Options
    default is ``no``. Setting this option to ``yes`` leaves ``named``
    vulnerable to replay attacks.
 
+``reject-000-label``
+   This can be used to control whether NSEC records which have the
+   ``next`` field starting with the ``\\000`` label are cached for
+   ``synth-from-dnssec``.  There are a number of DNSSEC implementations
+   that generate bad NSEC type maps where the ``next`` field starts with
+   the ``\\000`` label and between BIND 9.18 and BIND 9.20 there will be
+   a campaign to get these servers corrected.  In BIND 9.18 this defaults
+   to ``yes``.  In BIND 9.20 (BIND 9.19) this will default to ``no`` and
+   in BIND 9.22 (BIND 9.21) this option will be removed.
+
 ``querylog``
    Query logging provides a complete log of all incoming queries and all query
    errors. This provides more insight into the server's activity, but with a
@@ -2247,6 +2257,16 @@ Boolean Options
    named caching broken NSEC records from negative responses from servers
    that emit broken NSEC records with missing types that actually exist.
 
+   ``reject-000-label`` can be used to control whether NSEC records
+   which have the ``next`` field starting with the ``\\000`` label
+   are cached for ``synth-from-dnssec``.  There are a number of
+   DNSSEC implementations that generate bad NSEC type maps where
+   the ``next`` field starts with the ``\\000`` label and between
+   BIND 9.18 and BIND 9.20 there will be a campaign to get these
+   servers corrected.  In BIND 9.18 this defaults to ``yes``.  In
+   BIND 9.20 (BIND 9.19) this will default to ``no`` and in BIND 9.22
+   (BIND 9.21) this option will be removed.
+
    .. note:: DNSSEC validation must be enabled for this option to be effective.
       This initial implementation only covers synthesis of answers from
       NSEC records; synthesis from NSEC3 is planned for the future. This
index 52c1da4f4016868dd698554d148d0f85f8adaffd..ebfc33e9754d6575892902c7acbbff0478b0d4c9 100644 (file)
@@ -455,6 +455,7 @@ options {
       recursing\-file quoted_string;
       recursion boolean;
       recursive\-clients integer;
+      reject\-000\-label boolean;// deprecated
       request\-expire boolean;
       request\-ixfr boolean;
       request\-nsid boolean;
@@ -896,6 +897,7 @@ view string [ class ] {
               window integer;
       };
       recursion boolean;
+      reject\-000\-label boolean;// deprecated
       request\-expire boolean;
       request\-ixfr boolean;
       request\-nsid boolean;
index 52485fd3386a86c2c1db6ac48094b70230685bb4..f015f926a048601df3f892c640402a3fc1134bbf 100644 (file)
@@ -313,6 +313,7 @@ options {
         recursing-file <quoted_string>;
         recursion <boolean>;
         recursive-clients <integer>;
+        reject-000-label <boolean>; // deprecated
         request-expire <boolean>;
         request-ixfr <boolean>;
         request-nsid <boolean>;
@@ -673,6 +674,7 @@ view <string> [ <class> ] {
                 window <integer>;
         };
         recursion <boolean>;
+        reject-000-label <boolean>; // deprecated
         request-expire <boolean>;
         request-ixfr <boolean>;
         request-nsid <boolean>;
index 68aafb9ec92acdb400eafb922e70ae511f99846d..882c2473481756378cd74455341d5cd38a679b61 100644 (file)
@@ -311,6 +311,7 @@ options {
         recursing-file <quoted_string>;
         recursion <boolean>;
         recursive-clients <integer>;
+        reject-000-label <boolean>; // deprecated
         request-expire <boolean>;
         request-ixfr <boolean>;
         request-nsid <boolean>;
@@ -669,6 +670,7 @@ view <string> [ <class> ] {
                 window <integer>;
         };
         recursion <boolean>;
+        reject-000-label <boolean>; // deprecated
         request-expire <boolean>;
         request-ixfr <boolean>;
         request-nsid <boolean>;
index 8e69a096864aa0eeb792ecdd8be77bf4fe74db10..862461f6900220f746ccb7304c7054ca132a0c14 100644 (file)
        recursing-file <quoted_string>;
        recursion <boolean>;
        recursive-clients <integer>;
+       reject-000-label <boolean>; // deprecated
        request-expire <boolean>;
        request-ixfr <boolean>;
        request-nsid <boolean>;
index f1ec93877f356ccf46ea6fda916a7f5f590ae91b..43deee1039fa63c90dce5019d3733170d55b9eac 100644 (file)
@@ -130,6 +130,7 @@ struct dns_view {
        bool                  synthfromdnssec;
        bool                  trust_anchor_telemetry;
        bool                  root_key_sentinel;
+       bool                  reject_000_label;
        dns_transfer_format_t transfer_format;
        dns_acl_t                 *cacheacl;
        dns_acl_t                 *cacheonacl;
index e8b17aae19bba733b9a57bd7dd859db0f72dda2c..64fe5d0b5802bd9382c4161a561e31e06a93e658 100644 (file)
@@ -5210,6 +5210,32 @@ check_soa_and_dnskey(dns_rdataset_t *nsecset) {
        return (true);
 }
 
+/*
+ * Look for NSEC next name that starts with the label '\000'.
+ */
+static bool
+has_000_label(dns_rdataset_t *nsecset) {
+       dns_rdataset_t rdataset;
+       isc_result_t result;
+
+       dns_rdataset_init(&rdataset);
+       dns_rdataset_clone(nsecset, &rdataset);
+
+       for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
+            result = dns_rdataset_next(&rdataset))
+       {
+               dns_rdata_t rdata = DNS_RDATA_INIT;
+               dns_rdataset_current(&rdataset, &rdata);
+               if (rdata.length > 1 && rdata.data[0] == 1 &&
+                   rdata.data[1] == 0) {
+                       dns_rdataset_disassociate(&rdataset);
+                       return (true);
+               }
+       }
+       dns_rdataset_disassociate(&rdataset);
+       return (false);
+}
+
 /*
  * The validator has finished.
  */
@@ -5645,6 +5671,17 @@ answer_response:
                            !check_soa_and_dnskey(rdataset)) {
                                continue;
                        }
+
+                       /*
+                        * Look for \000 label in next name.
+                        */
+                       if (rdataset->type == dns_rdatatype_nsec &&
+                           fctx->res->view->reject_000_label &&
+                           has_000_label(rdataset))
+                       {
+                               continue;
+                       }
+
                        result = dns_db_findnode(fctx->cache, name, true,
                                                 &nsnode);
                        if (result != ISC_R_SUCCESS) {
index de5464f288c1cf23757cc3b6eb77e97202deadab..5b6ef543888cb9b789d02fe753ef0ecefa44e40e 100644 (file)
@@ -240,6 +240,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *name,
        view->synthfromdnssec = true;
        view->trust_anchor_telemetry = true;
        view->root_key_sentinel = true;
+       view->reject_000_label = true;
        view->new_zone_dir = NULL;
        view->new_zone_file = NULL;
        view->new_zone_db = NULL;
index ee0f3091f3b61151012a9f7bd123fff655f28f73..bf53b119d6fa20a8161ac2fd42547c902ac28981 100644 (file)
@@ -2118,6 +2118,7 @@ static cfg_clausedef_t view_clauses[] = {
        { "queryport-pool-updateinterval", NULL, CFG_CLAUSEFLAG_ANCIENT },
        { "rate-limit", &cfg_type_rrl, 0 },
        { "recursion", &cfg_type_boolean, 0 },
+       { "reject-000-label", &cfg_type_boolean, CFG_CLAUSEFLAG_DEPRECATED },
        { "request-nsid", &cfg_type_boolean, 0 },
        { "request-sit", NULL, CFG_CLAUSEFLAG_ANCIENT },
        { "require-server-cookie", &cfg_type_boolean, 0 },