]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Docs and small tweaks
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 24 Jan 2022 10:32:19 +0000 (11:32 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 24 Jan 2022 10:53:58 +0000 (11:53 +0100)
pdns/rec-lua-conf.cc
pdns/recursordist/docs/lua-config/ztc.rst
pdns/recursordist/docs/upgrade.rst
pdns/recursordist/rec-zonetocache.cc
pdns/recursordist/test-rec-zonetocache.cc

index 95ae6e15ac1f337a83ea748f2b582c29af1a97ef..823f9ba94e6a24b53d00047537a837f725217613 100644 (file)
@@ -453,17 +453,17 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
           string zonemdValidation = boost::get<string>(have.at("zonemd"));
           auto it = nameToVal.find(zonemdValidation);
           if (it == nameToVal.end()) {
-            throw std::runtime_error(zonemdValidation + " is not a valid value for `zonemdValidation`");
+            throw std::runtime_error(zonemdValidation + " is not a valid value for `zonemd`");
           }
           else {
             conf.d_zonemd = it->second;
           }
         }
-        if (have.count("zonemdDNSSEC")) {
-          string dnssec = boost::get<string>(have.at("zonemdDNSSEC"));
+        if (have.count("dnssec")) {
+          string dnssec = boost::get<string>(have.at("dnssec"));
           auto it = nameToVal.find(dnssec);
           if (it == nameToVal.end()) {
-            throw std::runtime_error(dnssec + " is not a valid value for `zonemdDNSSEC`");
+            throw std::runtime_error(dnssec + " is not a valid value for `dnssec`");
           }
           else {
             conf.d_dnssec = it->second;
index 1408076ca517a143382754574f4e30bdd4372b4b..d546313353699465690aed8c779301347fc9550f 100644 (file)
@@ -15,6 +15,26 @@ To load the root zone from Internic into the recursor once at startup and when t
 
      zoneToCache(".", "url", "https://www.internic.net/domain/root.zone", { refreshPeriod = 0 })
 
+DNSSEC and ZONEMD validation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Starting with version 4.7.0, the Recursor will do validation of the zone retrieved.
+Validation consists of two parts: ``DNSSEC`` and ``ZONEMD``.
+``ZONEMD`` is described in :rfc:`8976`.
+
+For the ``DNSSEC`` part, if the global :ref:`setting-dnssec` setting is not ``off`` or ``process-no-validate`` and the `DS` record from the parent zone or trust anchor indicates the zone is ``DNSSEC`` signed, the recursor will validate the ``DNSKEY`` records of the zone.
+If a ``ZONEMD`` record is present, it will also validate the ``ZONEMD`` record.
+If no ``ZONEMD`` is present, the ``NSEC`` or ``NSEC3`` denial of the ``ZONEMD`` record will be validated.
+Note that this is not a full validation of all signatures.
+The signatures of the remaining records will be verified on-demand once the records are inserted into the cache.
+
+For the ``ZONEMD`` part, if the zone has a ``ZONEMD`` record, the digest of the zone wil be verified.
+
+For both parts failure of validation will prevent the downloaded zone contents to be inserted into the cache.
+Absence of ``DNSSEC`` records is not considered a failure if the parent zone or negative trust anchor indicate the zone is ``Insecure``.
+Absence ``ZONEMD`` records is not considered a failure.
+This behaviour can be tuned with the ``zoneToCache`` specific `zonemd`_ and `dnssec`_ settings described below.
+
+
 Configuration
 ^^^^^^^^^^^^^
 .. function:: zoneToCache(zone, method, source [, settings ])
@@ -73,3 +93,21 @@ localAddress
 The source IP address to use when transferring using the ``axfr`` or ``url`` methods.
 When unset, :ref:`setting-query-local-address` is used.
 
+zonemd
+~~~~~~
+
+.. versionadded:: 4.7.0
+
+A string. possible values: ``ignore``: ignore ZONEMD records, ``validate``: validate ``ZONEMD`` if present, ``require``: require valid ``ZONEMD`` record to be present.
+Default ``validate``.
+
+
+dnssec
+~~~~~~
+
+.. versionadded:: 4.7.0
+
+A string, possible values: ``ignore``: do not do ``DNSSEC`` validation, ``validate``: validate ``DNSSEC`` records as described above but accept an ``Insecure`` (unsigned) zone, ``require``: require ``DNSSEC`` validation, as described above.
+Default ``validate``.
+
+
index 3231ca2ba603f9e34b1d89f75f8122c9778c343f..01a8cc4f05db8a124977b981f0ff2578487760f6 100644 (file)
@@ -14,7 +14,7 @@ Using the settings mentioned in :ref:`upgrade-offensive` now generates a warning
 File descriptor usage
 ^^^^^^^^^^^^^^^^^^^^^
 The number of file descriptors used by the Recursor has increased because the Recursor now keeps idle outgoing TCP/DoT connections open for a while.
-The extra file descriptors used compared to previous versions of the Recursor is :ref:`setting-tcp-out-max-idle-per-thread` times the number of worker threads (:ref:`threads`).
+The extra file descriptors used compared to previous versions of the Recursor is :ref:`setting-tcp-out-max-idle-per-thread` times the number of worker threads (:ref:`setting-threads`).
 
 New settings
 ^^^^^^^^^^^^
index 68f2aed6c8c9e5dc0bf04013c7b1225f3dcf5b19..fbcc221184d2a59522c8fb1e5148b9b08b2c9715 100644 (file)
@@ -286,10 +286,12 @@ vState ZoneData::dnssecValidate(pdns::ZoneMD& zonemd, size_t& zonemdCount) const
     if (nsecs.records.size() > 0 && nsecs.signatures.size() > 0) {
       nsecValidationStatus = validateWithKeySet(d_now, d_zone, nsecs.records, nsecs.signatures, validKeys);
       csp.emplace(std::make_pair(d_zone, QType::NSEC), nsecs);
-    } else if (nsec3s.records.size() > 0 && nsec3s.signatures.size() > 0) {
+    }
+    else if (nsec3s.records.size() > 0 && nsec3s.signatures.size() > 0) {
       nsecValidationStatus = validateWithKeySet(d_now, d_zone, nsec3s.records, nsec3s.signatures, validKeys);
       csp.emplace(std::make_pair(d_zone, QType::NSEC3), nsec3s);
-    } else {
+    }
+    else {
       d_log->info("No NSEC(3) records and/or RRSIGS found to deny ZONEMD");
       return vState::BogusInvalidDenial;
     }
@@ -347,11 +349,11 @@ void ZoneData::ZoneToCache(const RecZoneToCache::Config& config)
   }
 
   if (config.d_dnssec == pdns::ZoneMD::Config::Require && g_dnssecmode == DNSSECMode::Off) {
-    throw PDNSException("ZONEMD DNSSEC validation failure: dnssec is switched of but required by ZoneToCache");
+    throw PDNSException("ZONEMD DNSSEC validation failure: dnssec is switched off but required by ZoneToCache");
   }
 
   // Validate DNSKEYs and ZONEMD, rest of records are validated on-demand by SyncRes
-  if (config.d_dnssec == pdns::ZoneMD::Config::Require || (g_dnssecmode != DNSSECMode::Off && config.d_dnssec != pdns::ZoneMD::Config::Ignore)) {
+  if (config.d_dnssec == pdns::ZoneMD::Config::Require || (g_dnssecmode != DNSSECMode::Off && g_dnssecmode != DNSSECMode::ProcessNoValidate && config.d_dnssec != pdns::ZoneMD::Config::Ignore)) {
     size_t zonemdCount;
     auto validationStatus = dnssecValidate(zonemd, zonemdCount);
     d_log->info("ZONEMD record related DNSSEC validation", "validationStatus", Logging::Loggable(validationStatus),
index 21ad5eb0dd3170d41af0b706618865dc9a4dab3c..d671c39a16c4f4b8bb8b033aa164fdacc9375f4a 100644 (file)
@@ -68,7 +68,6 @@ static void zonemdTest(const std::string& lines, pdns::ZoneMD::Config mode, pdns
   BOOST_REQUIRE(fclose(fp) == 0);
 
   RecZoneToCache::Config config{".", "file", {temp}, ComboAddress(), TSIGTriplet()};
-  RecZoneToCache::State state;
   config.d_refreshPeriod = 0;
   config.d_retryOnError = 0;
   config.d_zonemd = mode;
@@ -77,6 +76,7 @@ static void zonemdTest(const std::string& lines, pdns::ZoneMD::Config mode, pdns
   // Start with a new, empty cache
   g_recCache = std::make_unique<MemRecursorCache>();
   BOOST_CHECK_EQUAL(g_recCache->size(), 0U);
+  RecZoneToCache::State state;
   RecZoneToCache::ZoneToCache(config, state);
   unlink(temp);