]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: log if a dnssec related limit was hit (if log_bogus is set) 13845/head
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 23 Feb 2024 12:24:25 +0000 (13:24 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 1 Mar 2024 13:17:08 +0000 (14:17 +0100)
(cherry picked from commit 9d4a01ffa2b724907e07db423da048f68f15eca2)

pdns/recursordist/pdns_recursor.cc
pdns/recursordist/syncres.hh
pdns/validate.cc
pdns/validate.hh

index f5978c7feded52e687da157f62d5931d976224fc..200635c1c0da19df5fd26df4eef291c8c6da710d 100644 (file)
@@ -569,10 +569,10 @@ static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy
           break;
         }
         catch (const pdns::validation::TooManySEC3IterationsException& e) {
-          if (g_logCommonErrors) {
+          if (g_logCommonErrors || (g_dnssecLogBogus && resolver.getDNSSECLimitHit())) {
             SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << comboWriter->getRemote() << " during resolve of the custom filter policy '" << appliedPolicy.getName() << "' while resolving '" << comboWriter->d_mdp.d_qname << "' because: " << e.what() << endl,
                  resolver.d_slog->error(Logr::Notice, e.what(), "Sending SERVFAIL during resolve of the custom filter policy",
-                                        "policyName", Logging::Loggable(appliedPolicy.getName()), "exception", Logging::Loggable("TooManySEC3IterationsException")));
+                                        "policyName", Logging::Loggable(appliedPolicy.getName()), "exception", Logging::Loggable("TooManySEC3IterationsException"), "dnsseclimithit", Logging::Loggable(resolver.getDNSSECLimitHit())));
           }
           res = RCode::ServFail;
           break;
@@ -1282,7 +1282,7 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi
       catch (const pdns::validation::TooManySEC3IterationsException& e) {
         if (g_logCommonErrors) {
           SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << comboWriter->getRemote() << " during resolve of '" << comboWriter->d_mdp.d_qname << "' because: " << e.what() << endl,
-               resolver.d_slog->error(Logr::Notice, e.what(), "Sending SERVFAIL during resolve"));
+               resolver.d_slog->error(Logr::Notice, e.what(), "Sending SERVFAIL during resolve", "dnsseclimithit", Logging::Loggable(true)));
         }
         res = RCode::ServFail;
       }
@@ -1403,6 +1403,9 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi
           if (resolver.doLog() || vStateIsBogus(state)) {
             // Only create logging object if needed below, beware if you change the logging logic!
             log = resolver.d_slog->withValues("vstate", Logging::Loggable(state));
+            if (resolver.getDNSSECLimitHit()) {
+              log = log->withValues("dnsseclimithit", Logging::Loggable(true));
+            }
             auto xdnssec = g_xdnssec.getLocal();
             if (xdnssec->check(comboWriter->d_mdp.d_qname)) {
               log = log->withValues("in-x-dnssec-names", Logging::Loggable(1));
@@ -1466,9 +1469,9 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi
           goto sendit; // NOLINT(cppcoreguidelines-avoid-goto)
         }
         catch (const pdns::validation::TooManySEC3IterationsException& e) {
-          if (g_logCommonErrors) {
+          if (g_logCommonErrors || (g_dnssecLogBogus && resolver.getDNSSECLimitHit())) {
             SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << comboWriter->getRemote() << " during validation of '" << comboWriter->d_mdp.d_qname << "|" << QType(comboWriter->d_mdp.d_qtype) << "' because: " << e.what() << endl,
-                 resolver.d_slog->error(Logr::Notice, e.what(), "Sending SERVFAIL during validation", "exception", Logging::Loggable("TooManySEC3IterationsException")));
+                 resolver.d_slog->error(Logr::Notice, e.what(), "Sending SERVFAIL during validation", "exception", Logging::Loggable("TooManySEC3IterationsException"), "dnsseclimithit", Logging::Loggable(resolver.getDNSSECLimitHit())));
           }
           goto sendit; // NOLINT(cppcoreguidelines-avoid-goto)
         }
index b77fc24c3ed8f310f0534c29802dafad2b79a00b..4298b8b3bd4c695741000f52e57f6bd09368136d 100644 (file)
@@ -465,6 +465,11 @@ public:
     return d_queryValidationState;
   }
 
+  [[nodiscard]] bool getDNSSECLimitHit() const
+  {
+    return d_validationContext.d_limitHit;
+  }
+
   void setQueryReceivedOverTCP(bool tcp)
   {
     d_queryReceivedOverTCP = tcp;
index 16d144e643b0a4d9afdcf937f51464fda4bd94ab..6833ab9baa14330139eafb0bfcd8aec5c1fe49a3 100644 (file)
@@ -176,6 +176,7 @@ bool denialProvesNoDelegation(const DNSName& zone, const std::vector<DNSRecord>&
       }
 
       if (g_maxNSEC3sPerRecordToConsider > 0 && nsec3sConsidered >= g_maxNSEC3sPerRecordToConsider) {
+        context.d_limitHit = true;
         return false;
       }
       nsec3sConsidered++;
@@ -704,6 +705,7 @@ dState getDenial(const cspmap_t &validrrsets, const DNSName& qname, const uint16
 
         if (g_maxNSEC3sPerRecordToConsider > 0 && nsec3sConsidered >= g_maxNSEC3sPerRecordToConsider) {
           VLOG(log, qname << ": Too many NSEC3s for this record"<<endl);
+          context.d_limitHit = true;          
           return dState::NODENIAL;
         }
         nsec3sConsidered++;
@@ -805,6 +807,7 @@ dState getDenial(const cspmap_t &validrrsets, const DNSName& qname, const uint16
 
             if (g_maxNSEC3sPerRecordToConsider > 0 && nsec3sConsidered >= g_maxNSEC3sPerRecordToConsider) {
               VLOG(log, qname << ": Too many NSEC3s for this record"<<endl);
+              context.d_limitHit = true;
               return dState::NODENIAL;
             }
             nsec3sConsidered++;
@@ -891,6 +894,7 @@ dState getDenial(const cspmap_t &validrrsets, const DNSName& qname, const uint16
 
             if (g_maxNSEC3sPerRecordToConsider > 0 && nsec3sConsidered >= g_maxNSEC3sPerRecordToConsider) {
               VLOG(log, qname << ": Too many NSEC3s for this record"<<endl);
+              context.d_limitHit = true;
               return dState::NODENIAL;
             }
             nsec3sConsidered++;
@@ -1031,6 +1035,7 @@ vState validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t
     if (g_maxRRSIGsPerRecordToConsider > 0 && signaturesConsidered >= g_maxRRSIGsPerRecordToConsider) {
       VLOG(log, name<<": We have already considered "<<std::to_string(signaturesConsidered)<<" RRSIG"<<addS(signaturesConsidered)<<" for this record, stopping now"<<endl;);
       // possibly going Bogus, the RRSIGs have not been validated so Insecure would be wrong
+      context.d_limitHit = true;
       break;
     }
     signaturesConsidered++;
@@ -1049,6 +1054,9 @@ vState validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t
     for (const auto& key : keysMatchingTag) {
       if (g_maxDNSKEYsToConsider > 0 && dnskeysConsidered >= g_maxDNSKEYsToConsider) {
         VLOG(log, name << ": We have already considered "<<std::to_string(dnskeysConsidered)<<" DNSKEY"<<addS(dnskeysConsidered)<<" for tag "<<std::to_string(signature->d_tag)<<" and algorithm "<<std::to_string(signature->d_algorithm)<<", not considering the remaining ones for this signature"<<endl;);
+        if (!isValid) {
+          context.d_limitHit = true;
+        }
         return isValid ? vState::Secure : vState::BogusNoValidRRSIG;
       }
       dnskeysConsidered++;
@@ -1175,6 +1183,7 @@ vState validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t&
         // we need to break because we can have a partially validated set
         // where the KSK signs the ZSK(s), and even if we don't
         // we are going to try to get the correct EDE status (revoked, expired, ...)
+        context.d_limitHit = true;
         break;
       }
       dnskeysConsidered++;
@@ -1227,6 +1236,7 @@ vState validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t&
       if (g_maxRRSIGsPerRecordToConsider > 0 && signaturesConsidered >= g_maxRRSIGsPerRecordToConsider) {
         VLOG(log, zone << ": We have already considered "<<std::to_string(signaturesConsidered)<<" RRSIG"<<addS(signaturesConsidered)<<" for this record, stopping now"<<endl;);
         // possibly going Bogus, the RRSIGs have not been validated so Insecure would be wrong
+        context.d_limitHit = true;
         return vState::BogusNoValidDNSKEY;
       }
 
@@ -1235,6 +1245,7 @@ vState validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t&
       for (const auto& key : bytag) {
         if (g_maxDNSKEYsToConsider > 0 && dnskeysConsidered >= g_maxDNSKEYsToConsider) {
           VLOG(log, zone << ": We have already considered "<<std::to_string(dnskeysConsidered)<<" DNSKEY"<<addS(dnskeysConsidered)<<" for tag "<<std::to_string(sig->d_tag)<<" and algorithm "<<std::to_string(sig->d_algorithm)<<", not considering the remaining ones for this signature"<<endl;);
+          context.d_limitHit = true;
           return vState::BogusNoValidDNSKEY;
         }
         dnskeysConsidered++;
@@ -1242,6 +1253,7 @@ vState validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t&
         if (g_maxRRSIGsPerRecordToConsider > 0 && signaturesConsidered >= g_maxRRSIGsPerRecordToConsider) {
           VLOG(log, zone << ": We have already considered "<<std::to_string(signaturesConsidered)<<" RRSIG"<<addS(signaturesConsidered)<<" for this record, stopping now"<<endl;);
           // possibly going Bogus, the RRSIGs have not been validated so Insecure would be wrong
+          context.d_limitHit = true;
           return vState::BogusNoValidDNSKEY;
         }
         //          cerr<<"validating : ";
index 7d844bf11c6d07ce66fe5137139a85512aa998cb..034839fca052173c250448da3ac8dc488c0cc04c 100644 (file)
@@ -90,6 +90,7 @@ struct ValidationContext
   Nsec3HashesCache d_nsec3Cache;
   unsigned int d_validationsCounter{0};
   unsigned int d_nsec3IterationsRemainingQuota{0};
+  bool d_limitHit{false};
 };
 
 class TooManySEC3IterationsException : public std::runtime_error