]> granicus.if.org Git - pdns/commitdiff
auth: keep slave dnssec status in sync with the master
authorKees Monshouwer <mind04@monshouwer.org>
Thu, 1 Jun 2017 23:08:27 +0000 (01:08 +0200)
committermind04 <mind04@monshouwer.org>
Sat, 3 Jun 2017 14:27:12 +0000 (16:27 +0200)
pdns/dbdnsseckeeper.cc
pdns/dnsseckeeper.hh
pdns/slavecommunicator.cc
pdns/ueberbackend.cc
pdns/ueberbackend.hh

index d3bfff37373d2a2480a829dc1f35426f7d26bbfc..35e70977092469113c6af49da258d66ef991c712 100644 (file)
@@ -51,6 +51,11 @@ pthread_rwlock_t DNSSECKeeper::s_keycachelock = PTHREAD_RWLOCK_INITIALIZER;
 AtomicCounter DNSSECKeeper::s_ops;
 time_t DNSSECKeeper::s_last_prune;
 
+bool DNSSECKeeper::doesDNSSEC()
+{
+  return d_keymetadb->doesDNSSEC();
+}
+
 bool DNSSECKeeper::isSecuredZone(const DNSName& zone) 
 {
   if(isPresigned(zone))
index 73b4b89fd194717d90ec29952b20f6ea9bde8e67..da79a796adadf64af0e7db183019854dfabf4986 100644 (file)
@@ -156,6 +156,7 @@ public:
     if(d_ourDB)
       delete d_keymetadb;
   }
+  bool doesDNSSEC();
   bool isSecuredZone(const DNSName& zone);
   static uint64_t dbdnssecCacheSizes(const std::string& str);
   keyset_t getEntryPoints(const DNSName& zname);
index 6731862fd410cdb8334039702fcd474bbd29d745..c58f10c973588dd4eac0aafbeeb5547165ea3d89 100644 (file)
@@ -779,7 +779,7 @@ void CommunicatorClass::slaveRefresh(PacketHandler *P)
 
       DomainNotificationInfo dni;
       dni.di=di;
-      dni.dnssecOk = dk.isPresigned(di.zone);
+      dni.dnssecOk = dk.doesDNSSEC();
 
       if(dk.getTSIGForAccess(di.zone, sr.master, &dni.tsigkeyname)) {
         string secret64;
@@ -874,14 +874,10 @@ void CommunicatorClass::slaveRefresh(PacketHandler *P)
       di.backend->setFresh(di.id);
     }
     else if(theirserial == ourserial) {
-      if(!dk.isPresigned(di.zone)) {
-        L<<Logger::Info<<"Domain '"<< di.zone<<"' is fresh (not presigned, no RRSIG check)"<<endl;
-        di.backend->setFresh(di.id);
-      }
-      else {
+      uint32_t maxExpire=0, maxInception=0;
+      if(dk.isPresigned(di.zone)) {
         B->lookup(QType(QType::RRSIG), di.zone); // can't use DK before we are done with this lookup!
         DNSZoneRecord zr;
-        uint32_t maxExpire=0, maxInception=0;
         while(B->get(zr)) {
           auto rrsig = getRR<RRSIGRecordContent>(zr.dr);
           if(rrsig->d_type == QType::SOA) {
@@ -889,14 +885,30 @@ void CommunicatorClass::slaveRefresh(PacketHandler *P)
             maxExpire = std::max(maxExpire, rrsig->d_sigexpire);
           }
         }
-        if(maxInception == ssr.d_freshness[di.id].theirInception && maxExpire == ssr.d_freshness[di.id].theirExpire) {
-          L<<Logger::Info<<"Domain '"<< di.zone<<"' is fresh and apex RRSIGs match"<<endl;
-          di.backend->setFresh(di.id);
-        }
-        else {
-          L<<Logger::Warning<<"Domain '"<< di.zone<<"' is fresh, but RRSIGS differ, so DNSSEC stale"<<endl;
-          addSuckRequest(di.zone, *di.masters.begin());
-        }
+      }
+      if(! maxInception && ! ssr.d_freshness[di.id].theirInception) {
+        L<<Logger::Info<<"Domain '"<< di.zone<<"' is fresh (no DNSSEC)"<<endl;
+        di.backend->setFresh(di.id);
+      }
+      else if(maxInception == ssr.d_freshness[di.id].theirInception && maxExpire == ssr.d_freshness[di.id].theirExpire) {
+        L<<Logger::Info<<"Domain '"<< di.zone<<"' is fresh and SOA RRSIGs match"<<endl;
+        di.backend->setFresh(di.id);
+      }
+      else if(maxExpire >= now && ! ssr.d_freshness[di.id].theirInception ) {
+        L<<Logger::Info<<"Domain '"<< di.zone<<"' is fresh, master is no longer signed but (some) signatures are still vallid"<<endl;
+        di.backend->setFresh(di.id);
+      }
+      else if(maxInception && ! ssr.d_freshness[di.id].theirInception ) {
+        L<<Logger::Warning<<"Domain '"<< di.zone<<"' is stale, master is no longer signed and all signatures have expired"<<endl;
+        addSuckRequest(di.zone, *di.masters.begin());
+      }
+      else if(dk.doesDNSSEC() && ! maxInception && ssr.d_freshness[di.id].theirInception) {
+        L<<Logger::Warning<<"Domain '"<< di.zone<<"' is stale, master has signed"<<endl;
+        addSuckRequest(di.zone, *di.masters.begin());
+      }
+      else {
+        L<<Logger::Warning<<"Domain '"<< di.zone<<"' is fresh, but RRSIGs differ, so DNSSEC is stale"<<endl;
+        addSuckRequest(di.zone, *di.masters.begin());
       }
     }
     else {
index 258c85dc28d4622c275cbea54e2585932f654f44..cb5eac570e2287995946dcad8a7606e8c56f3aeb 100644 (file)
@@ -98,6 +98,15 @@ bool UeberBackend::createDomain(const DNSName &domain)
   return false;
 }
 
+bool UeberBackend::doesDNSSEC()
+{
+  for(auto* db :  backends) {
+    if(db->doesDNSSEC())
+      return true;
+  }
+  return false;
+}
+
 bool UeberBackend::addDomainKey(const DNSName& name, const DNSBackend::KeyData& key, int64_t& id)
 {
   id = -1;
index c6989dddedf7fde49c99b4d0256ad7964d8241fb..37ab30d8849003ef28f628d7e9f7b1f9120d22ed 100644 (file)
@@ -109,6 +109,7 @@ public:
   bool getDomainInfo(const DNSName &domain, DomainInfo &di);
   bool createDomain(const DNSName &domain);
   
+  bool doesDNSSEC();
   bool addDomainKey(const DNSName& name, const DNSBackend::KeyData& key, int64_t& id);
   bool getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys);
   bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta);