I'm trying to implement a toy project DNSSEC supported DNS resolver to learn about both DNS and DNSSEC.
Most of my implementation are finished. But for some domains it's not working correctly, and I noticed some differences when comparing with results from https://dnssec-analyzer.verisignlabs.com/
So the simplified flow of my DNSSEC validation went like this:
getZoneKeys(fqdn) -> keys: if fqdn == ".": return rootKeys // recursively find the parent zone keys parentKeys = getZoneKeys(parentFqdn(fqdn)) // query the DS records ds = dnsQuery(fqdn, TypeDS) // query the DNSKEY records dnskey = dnsQuery(fqdn, TypeDNSKEY) // according to DNS zone delegation, DS records should be verified using parent zone keys valid = verify(ds, parentKeys) if valid == NSEC: return Insecure // after DS is verified, those keys referenced from the DS records can be added to the zone keys set zoneKeys = findMatchingKeys(dnskey, ds) // then use the verified zone keys so far to verify the whole DNSKEY RR set valid = verify(dnskey, zoneKeys) if valid == NSEC: return Insecure // all the reset keys in the DNSKEY RR set will be added to the zone key zoneKeys = getAllDNSKEYs(dnskey) dnsQueryAndValidate(fqdn, type) -> record, valid: record = dnsQuery(fqdn, type) zoneKeys = getZoneKeys(fqdn) valid = verify(dsrecord, zoneKeys)
This is working for e.g.
www.cloudflare.com but not for e.g.
exp.igw0.nyi.freebsd.org. And I used https://dnssec-analyzer.verisignlabs.com/ to compare my flow with its results.
I found that for
www.cloudflare.com result, the zone key delegation happens all along the way down to
www.cloudflare.com, which means all
www.cloudflare.com. have their own DNS zone, and each zone except the root zone receives key delegation from its parent through DS records. This is exactly how my program is checking for and is working.
dev.future.internetsociety.org result, the zone key delegation stops at
internetsociety.org, and it seems it doesn't even check the zone for
future.internetsociety.org, and directly jumps to checking
dev.future.internetsociety.org, and using
internetsociety.org's zone key to verify
dev.future.internetsociety.org's A RRset.
Furthermore, even more stangely, for
exp.igw0.nyi.freebsd.org result, the zone key delegation stops at
freebsd.org, and then the A RRSet for
exp.igw0.nyi.freebsd.org is being checked consecutively for four times.
I think I don't quit understand what DNS zone really means in practice. Does it mean if a subdomain doesn't have a DS record, with a NSEC proof, then its zone keys should inherit the keys from the cloest parent zone that has a zone keys? Or if there are other criteria to check if a domain has its own DNS zone? And finally, how to properly handle the zone delegation for DNSSEC?