mirror of
https://github.com/hickory-dns/hickory-dns.git
synced 2026-04-25 11:15:54 +03:00
[GH-ISSUE #2428] On 0.25.0-alpha.2, setting validate=true does not validate DNSSEC #987
Labels
No labels
blocked
breaking-change
bug
bug:critical
bug:tests
cleanup
compliance
compliance
compliance
crate:all
crate:client
crate:native-tls
crate:proto
crate:recursor
crate:resolver
crate:resolver
crate:rustls
crate:server
crate:util
dependencies
docs
duplicate
easy
easy
enhance
enhance
enhance
feature:dns-over-https
feature:dns-over-quic
feature:dns-over-tls
feature:dnsssec
feature:global_lb
feature:mdns
feature:tsig
features:edns
has workaround
ops
perf
platform:WASM
platform:android
platform:fuchsia
platform:linux
platform:macos
platform:windows
pull-request
question
test
tools
tools
trust
unclear
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/hickory-dns#987
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @msrd0 on GitHub (Sep 5, 2024).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2428
Describe the bug
DNSSEC isn't checked properly.
To Reproduce
Start hickory-dns with the following config:
Then, query
dnssec-failed.organd observe that a record is returned. Note that cloudflare (1.1.1.1) does DNSSEC validation, so I added a nameserver from the whois response to be sure that hickory actually receives a record to validate. https://dnsviz.net/d/dnssec-failed.org/dnssec/ shows that the domain has a bogus dnssec record.Expected behavior
I expect to (a) not receive any records, and (b) expect to receive some error indication like a SERVFAIL response.
System:
Version:
Crate: hickory-dns binary
Version: 0.25.0-alpha.2
@msrd0 commented on GitHub (Nov 25, 2024):
This problem is still present in 0.25.0-alpha.3
@bluejekyll commented on GitHub (Mar 2, 2025):
@divergentdave do you know if this is still an issue?
@divergentdave commented on GitHub (Mar 2, 2025):
I changed
zone_type = "Forward"zone_type = "External", andtrust_nx_responsestotrust_negative_responses, and I can reproduce this. (withcargo run --features dnssec-aws-lc-rs,tls-aws-lc-rs --package hickory-dns -- -c configs/issue_2428.toml -p 12345 -dandcargo run --features dnssec-aws-lc-rs,tls-aws-lc-rs --package hickory-dns -- -c configs/issue_2428.toml -p 12345 -d) See the tail end of the logs below. Validation is happening, but the validation error apparently isn't getting translated into a SERVFAIL response. Note that the stub resolver has not received the same level of attention lately as the recursive resolver. (Also, while this config works for demonstrating this issue, note that combining authoritative name servers and recursive resolvers in the list of upstreams for atype = "forward"stub resolver will lead to strange results.)@bluejekyll commented on GitHub (Mar 2, 2025):
thanks for the quick response.
@divergentdave commented on GitHub (Mar 4, 2025):
I opened PR #2830 to add a test for this. Fixing it will be involved, because there are a lot of little pieces missing.
impl Authority for ForwardAuthorityblock does not overridecan_validate_dnssec(), so this inherits the default implementation that always returns false. I think this should be returningself.resolver.options().validate.build_forwarded_response()has been written to work with the recursive resolver, but it is also used with the forward authority. Some implicit assumptions that are true of lookups returned by the recursor are no longer true in this case, where lookups are constructed from responses right off the network.EmptyLookupmay be used in some cases, such as when there is no NS or SOA record in the response. (I initially forgot to add an SOA record to the zone in my test, and then kept it that way when I noticed this code path) Theimpl LookupObject for EmptyLookupblock does not override thednssec_summary()method, and thus inherits the default implementation that always returnsInsecure. This effectively defeats the prior negative response validation.build_forwarded_response()has a lot of edge cases, and we should make sure all code paths through it are sound with respect to DNSSEC. If the requirements for validating resolvers and validating stub resolvers are too different, we may want to revisit using the same function for both use cases.@djc commented on GitHub (Mar 4, 2025):
Given this, I don't think we should block the release on this. @bluejekyll?
@msrd0 commented on GitHub (Mar 4, 2025):
If I may add my 2 cents here, I believe that a release with a non-working
validateoption would be a mistake. If you decide to release without working dnssec validation, please remove thevalidateoption and only re-introduce it once validation works.@djc commented on GitHub (Mar 4, 2025):
If this is not a regression compared to 0.24, 0.25.0 will not be worse (on this particular aspect) than the releases that are already out there. I definitely agree that we should fix this -- if it is not a regression I don't think we should hold back all the other improvements we made to DNSSEC (and everything else) in the past year.
@msrd0 commented on GitHub (Mar 4, 2025):
It is. 0.24 blocked all records without valid dnssec, including those with no dnssec at all (which I don't believe is indended behaviour, see #2429). In the 0.25 alpha versions I tested the option appears as a complete no-op.
@bluejekyll commented on GitHub (Mar 5, 2025):
If I have a moment I'd like to see not if I can get this working to at least match the old behavior, if not the correct current behavior.
@divergentdave commented on GitHub (Mar 12, 2025):
Here's a CFG of the existing
build_forwarded_response()function.Some more observations:
RCODE=REFUSEDin the case whereRD=0, rather than returning an empty response withNOERROR.Proof::Bogusto theDnssecSummarylogic if we have a record to hang the proof off of, or aProtoErrorKind::Nsec. Thus, we should make sure we test behavior when the response from the upstream resolver has empty sections. (though this might be covered by existing logic turning an empty response into an error).AuthLookup::dnssec_summary()returns a fallback ofDnssecSummary::Insecureif there are no records. This feels risky, compared to usingBogus.@msrd0 commented on GitHub (Mar 14, 2025):
Thanks for fixing this 😻