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*
* @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<string> meta;
- meta.push_back("1");
+ meta.push_back(deleteAlg ? "0" : "1");
return d_keymetadb->setDomainMetadata(zname, "PUBLISH-CDNSKEY", meta) && clearMetaCache(zname);
}
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);
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<CDNSKEYRecordContent> PacketHandler::s_deleteCDNSKEYContent = std::make_shared<CDNSKEYRecordContent>("0 3 0 AA==");
+const std::shared_ptr<CDSRecordContent> PacketHandler::s_deleteCDSContent = std::make_shared<CDSRecordContent>("0 0 0 00");
+
PacketHandler::PacketHandler():B(s_programname), d_dk(&B)
{
++s_count;
{
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<DNSKEYRecordContent>(value.first.getDNSKEY());
- rr.auth=true;
- r->addRecord(std::move(rr));
+ r->addRecord(DNSZoneRecord(rr));
haveOne=true;
}
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);
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);
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);
int trySuperMasterSynchronous(const DNSPacket& p, const DNSName& tsigkeyname);
static NetmaskGroup s_allowNotifyFrom;
static set<string> s_forwardNotify;
+ static const std::shared_ptr<CDNSKEYRecordContent> s_deleteCDNSKEYContent;
+ static const std::shared_ptr<CDSRecordContent> s_deleteCDSContent;
private:
int trySuperMaster(const DNSPacket& p, const DNSName& tsigkeyname);
cout<<"set-account ZONE ACCOUNT Change the account (owner) of ZONE to ACCOUNT"<<endl;
cout<<"set-nsec3 ZONE ['PARAMS' [narrow]] Enable NSEC3 with PARAMS. Optionally narrow"<<endl;
cout<<"set-presigned ZONE Use presigned RRSIGs from storage"<<endl;
- cout<<"set-publish-cdnskey ZONE Enable sending CDNSKEY responses for ZONE"<<endl;
+ cout<<"set-publish-cdnskey ZONE [delete] Enable sending CDNSKEY responses for ZONE. Add 'delete' to publish a CDNSKEY with a"<<endl;
+ cout<<" DNSSEC delete algorithm"<<endl;
cout<<"set-publish-cds ZONE [DIGESTALGOS] Enable sending CDS responses for ZONE, using DIGESTALGOS as signature algorithms"<<endl;
cout<<" DIGESTALGOS should be a comma separated list of numbers, it is '2' by default"<<endl;
cout<<"add-meta ZONE KIND VALUE Add zone metadata, this adds to the existing KIND"<<endl;
return 0;
}
else if(cmds[0]=="set-publish-cdnskey") {
- if(cmds.size() < 2) {
- cerr<<"Syntax: pdnsutil set-publish-cdnskey ZONE"<<endl;
+ if(cmds.size() < 2 || (cmds.size() == 3 && cmds[2] != "delete")) {
+ cerr<<"Syntax: pdnsutil set-publish-cdnskey ZONE [delete]"<<endl;
return 0;
}
- if (! dk.setPublishCDNSKEY(DNSName(cmds[1]))) {
+ if (! dk.setPublishCDNSKEY(DNSName(cmds[1]), (cmds.size() == 3 && cmds[2] == "delete"))) {
cerr << "Could not set publishing for CDNSKEY records for "<< cmds[1]<<endl;
return 1;
}
// 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<DNSKEYRecordContent>(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<DNSKEYRecordContent>(value.first.getDNSKEY());
+ cdnskey.push_back(zrr);
+ }
}
if(!publishCDS.empty()){
zrr.dr.d_type=QType::CDS;
vector<string> digestAlgos;
stringtok(digestAlgos, publishCDS, ", ");
- for(auto const &digestAlgo : digestAlgos) {
- zrr.dr.d_content=std::make_shared<DSRecordContent>(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<DSRecordContent>(makeDSFromDNSKey(target, value.first.getDNSKEY(), pdns_stou(digestAlgo)));
+ cds.push_back(zrr);
+ }
}
}
}
$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
}
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
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]
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.
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
-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
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'
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