From 481508ab7d699580e207c7901c8647287a7ce616 Mon Sep 17 00:00:00 2001 From: Kees Monshouwer Date: Wed, 21 Oct 2020 00:49:21 +0200 Subject: [PATCH] auth: add support for dnssec removal to CDS/CDNSKEY --- docs/manpages/pdnsutil.1.rst | 8 +++-- pdns/dbdnsseckeeper.cc | 4 +-- pdns/dnsseckeeper.hh | 2 +- pdns/packethandler.cc | 34 ++++++++++++++----- pdns/packethandler.hh | 2 ++ pdns/pdnsutil.cc | 9 ++--- pdns/tcpreceiver.cc | 26 ++++++++++---- regression-tests/start-test-stop | 4 +++ .../tests/axfr/expected_result.dnssec | 6 +++- .../tests/axfr/expected_result.nsec3 | 6 +++- .../tests/axfr/expected_result.nsec3-optout | 6 +++- .../expected_result.nsec3-optout | 2 +- .../expected_result.dnssec | 2 +- .../tests/publishing-cds-cdnskey/command | 4 +++ .../publishing-cds-cdnskey/expected_result | 14 ++++++++ 15 files changed, 99 insertions(+), 30 deletions(-) diff --git a/docs/manpages/pdnsutil.1.rst b/docs/manpages/pdnsutil.1.rst index dce9405ef3..4b263de2fb 100644 --- a/docs/manpages/pdnsutil.1.rst +++ b/docs/manpages/pdnsutil.1.rst @@ -116,9 +116,11 @@ unset-nsec3 *ZONE* set-publish-cds *ZONE* [*DIGESTALGOS*] Set *ZONE* to respond to queries for its CDS records. the optional argument *DIGESTALGOS* should be a comma-separated list of DS - algorithms to use. By default, this is 2 (SHA-256). -set-publish-cdnskey *ZONE* - Set *ZONE* to publish CDNSKEY records. + algorithms to use. By default, this is 2 (SHA-256). 0 will publish a + CDS with a DNSSEC delete algorithm. +set-publish-cdnskey *ZONE* [**delete**] + Set *ZONE* to publish CDNSKEY records. Add 'delete' to publish a CDNSKEY + with a DNSSEC delete algorithm. unset-publish-cds *ZONE* Set *ZONE* to stop responding to queries for its CDS records. unset-publish-cdnskey *ZONE* diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc index 650cbd0e69..076bd77c5e 100644 --- a/pdns/dbdnsseckeeper.cc +++ b/pdns/dbdnsseckeeper.cc @@ -461,10 +461,10 @@ bool DNSSECKeeper::unsetPublishCDS(const DNSName& zname) * @param zname DNSName of the zone * @return true if the data was inserted, false otherwise */ -bool DNSSECKeeper::setPublishCDNSKEY(const DNSName& zname) +bool DNSSECKeeper::setPublishCDNSKEY(const DNSName& zname, bool deleteAlg) { vector meta; - meta.push_back("1"); + meta.push_back(deleteAlg ? "0" : "1"); return d_keymetadb->setDomainMetadata(zname, "PUBLISH-CDNSKEY", meta) && clearMetaCache(zname); } diff --git a/pdns/dnsseckeeper.hh b/pdns/dnsseckeeper.hh index 9f758cf7f5..2d61046f88 100644 --- a/pdns/dnsseckeeper.hh +++ b/pdns/dnsseckeeper.hh @@ -213,7 +213,7 @@ public: bool isPresigned(const DNSName& zname, bool useCache=true); bool setPresigned(const DNSName& zname); bool unsetPresigned(const DNSName& zname); - bool setPublishCDNSKEY(const DNSName& zname); + bool setPublishCDNSKEY(const DNSName& zname, bool deleteAlg); void getPublishCDNSKEY(const DNSName& zname, std::string& value); bool unsetPublishCDNSKEY(const DNSName& zname); bool setPublishCDS(const DNSName& zname, const string& digestAlgos); diff --git a/pdns/packethandler.cc b/pdns/packethandler.cc index 8985346581..29628f9de1 100644 --- a/pdns/packethandler.cc +++ b/pdns/packethandler.cc @@ -57,6 +57,10 @@ set PacketHandler::s_forwardNotify; extern string s_programname; +// See https://www.rfc-editor.org/rfc/rfc8078.txt and https://www.rfc-editor.org/errata/eid5049 for details +const std::shared_ptr PacketHandler::s_deleteCDNSKEYContent = std::make_shared("0 3 0 AA=="); +const std::shared_ptr PacketHandler::s_deleteCDSContent = std::make_shared("0 0 0 00"); + PacketHandler::PacketHandler():B(s_programname), d_dk(&B) { ++s_count; @@ -108,23 +112,29 @@ bool PacketHandler::addCDNSKEY(DNSPacket& p, std::unique_ptr& r, cons { string publishCDNSKEY; d_dk.getPublishCDNSKEY(p.qdomain,publishCDNSKEY); - if (publishCDNSKEY != "1") + if (publishCDNSKEY.empty()) return false; DNSZoneRecord rr; - bool haveOne=false; + rr.dr.d_type=QType::CDNSKEY; + rr.dr.d_ttl=sd.minimum; + rr.dr.d_name=p.qdomain; + rr.auth=true; + + if (publishCDNSKEY == "0") { // delete DS via CDNSKEY + rr.dr.d_content=s_deleteCDNSKEYContent; + r->addRecord(std::move(rr)); + return true; + } + bool haveOne=false; DNSSECKeeper::keyset_t entryPoints = d_dk.getEntryPoints(p.qdomain); for(const auto& value: entryPoints) { if (!value.second.published) { continue; } - rr.dr.d_type=QType::CDNSKEY; - rr.dr.d_ttl=sd.minimum; - rr.dr.d_name=p.qdomain; rr.dr.d_content=std::make_shared(value.first.getDNSKEY()); - rr.auth=true; - r->addRecord(std::move(rr)); + r->addRecord(DNSZoneRecord(rr)); haveOne=true; } @@ -205,6 +215,12 @@ bool PacketHandler::addCDS(DNSPacket& p, std::unique_ptr& r, const SO rr.dr.d_name=p.qdomain; rr.auth=true; + if(std::find(digestAlgos.begin(), digestAlgos.end(), "0") != digestAlgos.end()) { // delete DS via CDS + rr.dr.d_content=s_deleteCDSContent; + r->addRecord(std::move(rr)); + return true; + } + bool haveOne=false; DNSSECKeeper::keyset_t keyset = d_dk.getEntryPoints(p.qdomain); @@ -553,7 +569,7 @@ void PacketHandler::emitNSEC(std::unique_ptr& r, const SOAData& sd, c nrc.set(QType::DNSKEY); string publishCDNSKEY; d_dk.getPublishCDNSKEY(name, publishCDNSKEY); - if (publishCDNSKEY == "1") + if (! publishCDNSKEY.empty()) nrc.set(QType::CDNSKEY); string publishCDS; d_dk.getPublishCDS(name, publishCDS); @@ -608,7 +624,7 @@ void PacketHandler::emitNSEC3(std::unique_ptr& r, const SOAData& sd, n3rc.set(QType::DNSKEY); string publishCDNSKEY; d_dk.getPublishCDNSKEY(name, publishCDNSKEY); - if (publishCDNSKEY == "1") + if (! publishCDNSKEY.empty()) n3rc.set(QType::CDNSKEY); string publishCDS; d_dk.getPublishCDS(name, publishCDS); diff --git a/pdns/packethandler.hh b/pdns/packethandler.hh index 3ffba371e3..bb56440148 100644 --- a/pdns/packethandler.hh +++ b/pdns/packethandler.hh @@ -63,6 +63,8 @@ public: int trySuperMasterSynchronous(const DNSPacket& p, const DNSName& tsigkeyname); static NetmaskGroup s_allowNotifyFrom; static set s_forwardNotify; + static const std::shared_ptr s_deleteCDNSKEYContent; + static const std::shared_ptr s_deleteCDSContent; private: int trySuperMaster(const DNSPacket& p, const DNSName& tsigkeyname); diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index b2b5c0f3bb..debc9ec105 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -2169,7 +2169,8 @@ try cout<<"set-account ZONE ACCOUNT Change the account (owner) of ZONE to ACCOUNT"<& q, // generate CDS and CDNSKEY records if(entryPointIds.count(value.second.id) > 0){ - if(publishCDNSKEY == "1") { + if(!publishCDNSKEY.empty()) { zrr.dr.d_type=QType::CDNSKEY; - zrr.dr.d_content = std::make_shared(value.first.getDNSKEY()); - cdnskey.push_back(zrr); + if (publishCDNSKEY == "0") { + if (cdnskey.empty()) { + zrr.dr.d_content=PacketHandler::s_deleteCDNSKEYContent; + cdnskey.push_back(zrr); + } + } else { + zrr.dr.d_content = std::make_shared(value.first.getDNSKEY()); + cdnskey.push_back(zrr); + } } if(!publishCDS.empty()){ zrr.dr.d_type=QType::CDS; vector digestAlgos; stringtok(digestAlgos, publishCDS, ", "); - for(auto const &digestAlgo : digestAlgos) { - zrr.dr.d_content=std::make_shared(makeDSFromDNSKey(target, value.first.getDNSKEY(), pdns_stou(digestAlgo))); - cds.push_back(zrr); + if(std::find(digestAlgos.begin(), digestAlgos.end(), "0") != digestAlgos.end()) { + if(cds.empty()) { + zrr.dr.d_content=PacketHandler::s_deleteCDSContent; + cds.push_back(zrr); + } + } else { + for(auto const &digestAlgo : digestAlgos) { + zrr.dr.d_content=std::make_shared(makeDSFromDNSKey(target, value.first.getDNSKEY(), pdns_stou(digestAlgo))); + cds.push_back(zrr); + } } } } diff --git a/regression-tests/start-test-stop b/regression-tests/start-test-stop index 714aec8080..5c1bbcba7a 100755 --- a/regression-tests/start-test-stop +++ b/regression-tests/start-test-stop @@ -147,6 +147,10 @@ securezone () $PDNSUTIL --config-dir=. $configname set-publish-cds $zone 2>&1 $PDNSUTIL --config-dir=. $configname set-publish-cdnskey $zone 2>&1 fi + if [ "$zone" = "dnssec-parent.com" ]; then + $PDNSUTIL --config-dir=. $configname set-publish-cds $zone 0 2>&1 + $PDNSUTIL --config-dir=. $configname set-publish-cdnskey $zone delete 2>&1 + fi fi } diff --git a/regression-tests/tests/axfr/expected_result.dnssec b/regression-tests/tests/axfr/expected_result.dnssec index 3454e5ab3d..4aac677664 100644 --- a/regression-tests/tests/axfr/expected_result.dnssec +++ b/regression-tests/tests/axfr/expected_result.dnssec @@ -5,14 +5,18 @@ delegated.dnssec-parent.com. 3600 IN RRSIG NSEC 13 3 3600 [expiry] [inception] [ dnssec-parent.com. 3600 IN A 9.9.9.9 dnssec-parent.com. 3600 IN NS ns1.dnssec-parent.com. dnssec-parent.com. 3600 IN NS ns2.dnssec-parent.com. -dnssec-parent.com. 3600 IN NSEC insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. A NS SOA RRSIG NSEC DNSKEY +dnssec-parent.com. 3600 IN NSEC insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. A NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY dnssec-parent.com. 3600 IN RRSIG A 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN RRSIG NS 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN RRSIG NSEC 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN RRSIG SOA 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN SOA ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400 dnssec-parent.com. 3600 IN SOA ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400 +dnssec-parent.com. 86400 IN CDNSKEY 0 3 0 AA== +dnssec-parent.com. 86400 IN CDS 0 0 0 00 dnssec-parent.com. 86400 IN DNSKEY 257 3 13 ... +dnssec-parent.com. 86400 IN RRSIG CDNSKEY 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... +dnssec-parent.com. 86400 IN RRSIG CDS 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 86400 IN RRSIG DNSKEY 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. 3600 IN NS ns.example.com. insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. 3600 IN NSEC something1.auth-ent.dnssec-parent.com. NS RRSIG NSEC diff --git a/regression-tests/tests/axfr/expected_result.nsec3 b/regression-tests/tests/axfr/expected_result.nsec3 index ee9acb69d7..8b9d290b3b 100644 --- a/regression-tests/tests/axfr/expected_result.nsec3 +++ b/regression-tests/tests/axfr/expected_result.nsec3 @@ -7,15 +7,19 @@ delegated.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] dnssec-parent.com. 3600 IN A 9.9.9.9 dnssec-parent.com. 3600 IN NS ns1.dnssec-parent.com. dnssec-parent.com. 3600 IN NS ns2.dnssec-parent.com. -dnssec-parent.com. 3600 IN NSEC3 1 0 1 abcd [next owner] A NS SOA RRSIG DNSKEY NSEC3PARAM +dnssec-parent.com. 3600 IN NSEC3 1 0 1 abcd [next owner] A NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY dnssec-parent.com. 3600 IN RRSIG A 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN RRSIG NS 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN RRSIG SOA 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN SOA ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400 dnssec-parent.com. 3600 IN SOA ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400 +dnssec-parent.com. 86400 IN CDNSKEY 0 3 0 AA== +dnssec-parent.com. 86400 IN CDS 0 0 0 00 dnssec-parent.com. 86400 IN DNSKEY 257 3 13 ... dnssec-parent.com. 86400 IN NSEC3PARAM 1 0 1 abcd +dnssec-parent.com. 86400 IN RRSIG CDNSKEY 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... +dnssec-parent.com. 86400 IN RRSIG CDS 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 86400 IN RRSIG DNSKEY 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 86400 IN RRSIG NSEC3PARAM 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... ent.auth-ent.dnssec-parent.com. 3600 IN NSEC3 1 0 1 abcd [next owner] diff --git a/regression-tests/tests/axfr/expected_result.nsec3-optout b/regression-tests/tests/axfr/expected_result.nsec3-optout index 577ce72ee7..c4da9a3352 100644 --- a/regression-tests/tests/axfr/expected_result.nsec3-optout +++ b/regression-tests/tests/axfr/expected_result.nsec3-optout @@ -5,15 +5,19 @@ delegated.dnssec-parent.com. 3600 IN NS ns2.delegated.dnssec-parent.com. dnssec-parent.com. 3600 IN A 9.9.9.9 dnssec-parent.com. 3600 IN NS ns1.dnssec-parent.com. dnssec-parent.com. 3600 IN NS ns2.dnssec-parent.com. -dnssec-parent.com. 3600 IN NSEC3 1 1 1 abcd [next owner] A NS SOA RRSIG DNSKEY NSEC3PARAM +dnssec-parent.com. 3600 IN NSEC3 1 1 1 abcd [next owner] A NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY dnssec-parent.com. 3600 IN RRSIG A 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN RRSIG NS 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN RRSIG SOA 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN SOA ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400 dnssec-parent.com. 3600 IN SOA ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400 +dnssec-parent.com. 86400 IN CDNSKEY 0 3 0 AA== +dnssec-parent.com. 86400 IN CDS 0 0 0 00 dnssec-parent.com. 86400 IN DNSKEY 257 3 13 ... dnssec-parent.com. 86400 IN NSEC3PARAM 1 0 1 abcd +dnssec-parent.com. 86400 IN RRSIG CDNSKEY 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... +dnssec-parent.com. 86400 IN RRSIG CDS 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 86400 IN RRSIG DNSKEY 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 86400 IN RRSIG NSEC3PARAM 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. 3600 IN NS ns.example.com. diff --git a/regression-tests/tests/ds-at-unsecure-zone-cut/expected_result.nsec3-optout b/regression-tests/tests/ds-at-unsecure-zone-cut/expected_result.nsec3-optout index c8588f25ea..aa2cafbf23 100644 --- a/regression-tests/tests/ds-at-unsecure-zone-cut/expected_result.nsec3-optout +++ b/regression-tests/tests/ds-at-unsecure-zone-cut/expected_result.nsec3-optout @@ -2,7 +2,7 @@ 1 7on3vems0f8k9999ikei0ig4lfijekdr.dnssec-parent.com. IN RRSIG 3600 NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... 1 dnssec-parent.com. IN RRSIG 3600 SOA 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... 1 dnssec-parent.com. IN SOA 3600 ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400 -1 dvkuo8kja65gcsq600e6di9u719lsj8u.dnssec-parent.com. IN NSEC3 3600 1 1 1 abcd NIH4L3ODLUG7EN20PENJ8DGNU4OHC98F A NS SOA RRSIG DNSKEY NSEC3PARAM +1 dvkuo8kja65gcsq600e6di9u719lsj8u.dnssec-parent.com. IN NSEC3 3600 1 1 1 abcd NIH4L3ODLUG7EN20PENJ8DGNU4OHC98F A NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY 1 dvkuo8kja65gcsq600e6di9u719lsj8u.dnssec-parent.com. IN RRSIG 3600 NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... 2 . IN OPT 32768 Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 diff --git a/regression-tests/tests/ent-unsigned-delegation/expected_result.dnssec b/regression-tests/tests/ent-unsigned-delegation/expected_result.dnssec index 5ccb41dcd0..f7edf1b5e5 100644 --- a/regression-tests/tests/ent-unsigned-delegation/expected_result.dnssec +++ b/regression-tests/tests/ent-unsigned-delegation/expected_result.dnssec @@ -1,4 +1,4 @@ -1 dnssec-parent.com. IN NSEC 3600 insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. A NS SOA RRSIG NSEC DNSKEY +1 dnssec-parent.com. IN NSEC 3600 insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. A NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY 1 dnssec-parent.com. IN RRSIG 3600 NSEC 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... 1 dnssec-parent.com. IN RRSIG 3600 SOA 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... 1 dnssec-parent.com. IN SOA 3600 ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400 diff --git a/regression-tests/tests/publishing-cds-cdnskey/command b/regression-tests/tests/publishing-cds-cdnskey/command index 529c0cc099..6043f58205 100755 --- a/regression-tests/tests/publishing-cds-cdnskey/command +++ b/regression-tests/tests/publishing-cds-cdnskey/command @@ -4,6 +4,10 @@ cleandig secure-delegated.dnssec-parent.com CDS dnssec cleandig secure-delegated.dnssec-parent.com CDNSKEY dnssec cleandig secure-delegated.dnssec-parent.com ANY dnssec tcp | grep 'CDS\|CDNSKEY' | grep -v 'NSEC' +cleandig dnssec-parent.com CDS dnssec +cleandig dnssec-parent.com CDNSKEY dnssec +cleandig dnssec-parent.com ANY dnssec tcp | grep 'CDS\|CDNSKEY' | grep -v 'NSEC' + # We only want to know if we get these records when the default secure-zone is use # This means a single ZSK, we don't care about the contents cleandig cdnskey-cds-test.com CDS dnssec | perl -pe 's!86400.*!86400!g' diff --git a/regression-tests/tests/publishing-cds-cdnskey/expected_result b/regression-tests/tests/publishing-cds-cdnskey/expected_result index 15fdc76804..42d41acf25 100644 --- a/regression-tests/tests/publishing-cds-cdnskey/expected_result +++ b/regression-tests/tests/publishing-cds-cdnskey/expected_result @@ -16,6 +16,20 @@ Reply to question for qname='secure-delegated.dnssec-parent.com.', qtype=CDNSKEY 0 secure-delegated.dnssec-parent.com. IN RRSIG 86400 CDNSKEY 8 3 86400 [expiry] [inception] [keytag] secure-delegated.dnssec-parent.com. ... 0 secure-delegated.dnssec-parent.com. IN RRSIG 86400 CDS 8 3 86400 [expiry] [inception] [keytag] secure-delegated.dnssec-parent.com. ... 0 secure-delegated.dnssec-parent.com. IN RRSIG 86400 CDS 8 3 86400 [expiry] [inception] [keytag] secure-delegated.dnssec-parent.com. ... +0 dnssec-parent.com. IN CDS 86400 0 0 0 00 +0 dnssec-parent.com. IN RRSIG 86400 CDS 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... +2 . IN OPT 32768 +Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='dnssec-parent.com.', qtype=CDS +0 dnssec-parent.com. IN CDNSKEY 86400 0 3 0 AA== +0 dnssec-parent.com. IN RRSIG 86400 CDNSKEY 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... +2 . IN OPT 32768 +Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='dnssec-parent.com.', qtype=CDNSKEY +0 dnssec-parent.com. IN CDNSKEY 86400 0 3 0 AA== +0 dnssec-parent.com. IN CDS 86400 0 0 0 00 +0 dnssec-parent.com. IN RRSIG 86400 CDNSKEY 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... +0 dnssec-parent.com. IN RRSIG 86400 CDS 13 2 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... 0 cdnskey-cds-test.com. IN CDS 86400 0 cdnskey-cds-test.com. IN RRSIG 86400 2 . IN OPT 32768 -- 2.47.2