I'm learning about DNSSEC today but I don't quite understand about how a parent zone would store all of its child's Key Signing Keys (DNSKEY 257) in its DS record set.
There is one DS
record per DNSKEY (KSK) + hashing algorithm. So typically, for one KSK and one hashing algorithm, that makes one record.
For strenght and forward compatibility lots of parents hash with two algorithms (like SHA-1 and SHA-256) so in normal operations (one KSK) that means two DS
records.
In case of preparation of KSK rollover or in the middle of it, there would be two DNSKEY
(for KSK), hence twice the number of DS
records, so typically 4.
A DS
record has the hash of the key, so it is small.
As far as I understand, if I have a subdomain, say, subdomain.icann.org, which can have its own DNSSEC records, the DS record of icann.org will have to include the hash of the public Key Signing Key of the private key used for signing records in subdomain.icann.org.
Half true. This is only true is subdomain.example.com
is delegated from example.com
. If not, subdomain.example.com
is just one record among others in the example.com
zone and there is nothing about DNSKEY
or DS
records.
Wouldn't this mean that the DS record set in .org would be an extremely huge list of its child Key Signing Key hashes?
You seem to be in the assumption that the DS
records are all on the same name, they are not. The owner of a DS
record is the zone name that is delegated. So if a zone has 1 million of delegations, all signed, there will be 1 million DS
records (twice if multiple hashing algorithms, twice if multiple DNSKEY, etc.), but each one will have the corresponding zone name as owner. Note that the zone name is needed to compute the DS
record hash value (and not only the key content).
Interestingly, I did a quick check with dig DS org and I notice that there is only 1 DS record!
Of course, per the above. The root zone has multiple DS
records, for all the TLDs being DNSSEC enabled (almost all, but not all), but each DS
record is for the given TLD, there is no single DS
record mixing everything together, that would never work (again: the hash is a combination of the name of the zone AND the DNSKEY
- only one, the DS
record has a "key ID" to reference a given DNSKEY
if multiple ones).
Then, how does the resolver even verify if a Key Signing Key of its child zones is trusted with only that one single hash in the DS record of the .org most parent zone?
In summary, and schematizing, having www.example.com/A
to check for DNSSEC validity, a resolver has to:
- find the zone it is in (not detailing that)
- find the
RRSIG
records on www.example.com
; if they exist, find the DNSKEY
that generated those (if no RRSIG
records, name is not DNSSEC validated)
- so fetch
DNSKEY
records: in case of ZSK/KSK split (majority of cases but not mandatory nor single case out there), it may have to find also RRSIG
records of DNSKEY
records
- once it is up to the
DNSKEY
in the zone that signs everything transitively (so a KSK), it goes to parent (com
here) to find out if there is DS
record matching that DNSKEY
record, and if the cryptography works; so it ask parent for a (one or more) DS
record on the name example.com
; any other zone is not involved here, either there is - one or more - DS
records at parent for this specific example.com
zone, or there is none (in which case of course it means the delegation is not secure as not validated by DNSSEC mechanisms).
- if so, it now looks at
RRSIG
records of that specific DS
record at parent, and start from the beginning, to find the keys in that parent zone, and the "next" DS
records towards root, up to reaching root.
Recommendations:
- use DNSviz online: it will clearly show delegations and DNSSEC related informations (
DS
and DNSKEY
records and how they are linked together)
- locally use
delv
, which is kind of a successor of dig
and is tailored for DNSSEC operations. Its +vtrace
will show you exactly how one resolver validates a given name, with all records it has to fetch, as following:
$ delv +vtrace icann.org @9.9.9.9
;; fetch: icann.org/A
;; validating icann.org/A: starting
;; validating icann.org/A: attempting positive response validation
;; fetch: icann.org/DNSKEY
;; validating icann.org/DNSKEY: starting
;; validating icann.org/DNSKEY: attempting positive response validation
;; fetch: icann.org/DS
;; validating icann.org/DS: starting
;; validating icann.org/DS: attempting positive response validation
;; fetch: org/DNSKEY
;; validating org/DNSKEY: starting
;; validating org/DNSKEY: attempting positive response validation
;; fetch: org/DS
;; validating org/DS: starting
;; validating org/DS: attempting positive response validation
;; fetch: ./DNSKEY
;; validating ./DNSKEY: starting
;; validating ./DNSKEY: attempting positive response validation
;; validating ./DNSKEY: verify rdataset (keyid=20326): success
;; validating ./DNSKEY: marking as secure (DS)
;; validating org/DS: in fetch_callback_dnskey
;; validating org/DS: keyset with trust secure
;; validating org/DS: resuming validate
;; validating org/DS: verify rdataset (keyid=60955): success
;; validating org/DS: marking as secure, noqname proof not needed
;; validating org/DNSKEY: in fetch_callback_ds
;; validating org/DNSKEY: dsset with trust secure
;; validating org/DNSKEY: verify rdataset (keyid=26974): success
;; validating org/DNSKEY: marking as secure (DS)
;; validating icann.org/DS: in fetch_callback_dnskey
;; validating icann.org/DS: keyset with trust secure
;; validating icann.org/DS: resuming validate
;; validating icann.org/DS: verify rdataset (keyid=10821): success
;; validating icann.org/DS: marking as secure, noqname proof not needed
;; validating icann.org/DNSKEY: in fetch_callback_ds
;; validating icann.org/DNSKEY: dsset with trust secure
;; validating icann.org/DNSKEY: no DNSKEY matching DS
;; validating icann.org/DNSKEY: verify rdataset (keyid=18060): success
;; validating icann.org/DNSKEY: marking as secure (DS)
;; validating icann.org/A: in fetch_callback_dnskey
;; validating icann.org/A: keyset with trust secure
;; validating icann.org/A: resuming validate
;; validating icann.org/A: verify rdataset (keyid=43109): success
;; validating icann.org/A: marking as secure, noqname proof not needed
; fully validated
icann.org. 600 IN A 192.0.43.7
icann.org. 600 IN RRSIG A 7 2 600 20230420040745 20230330014551 43109 icann.org. ZlywQfipe8weEimV/PO7L3uGoXqDMUoIfVs9Dr4Za0OYEGu2os2IDF/3 MWqLNCZzQ+2fdGBFCj46Prg5w53DvnWa7YTWYk9NdYMI31DuPxyYR9lo 3kfZM3scucyebCt6SmQ0fR8dq+Dq4j0hYk3n+VYnntTxRTr/fw2o8Fo7 bmg=
Note that a validating resolver can be top down (starting with DS
record at root + the local hardcoded trust anchor) until reaching the requested name (or an error in the path) or bottom up (specially if parts of the answer still exist in cache, and only revalidation is needed).