Commit graph

44469 commits

Author SHA1 Message Date
Ondřej Surý
86b87dfd29 [9.20] fix: usr: Don't synthesize negative responses with pending NSEC
If an NSEC record has not yet been validated and is cached with trust
pending, don't use it to synthesize negative responses.

Closes #5872 

Closes #5887 

Closes #5977

Backport of MR !12281

Merge branch 'backport-5977-validate-synth-from-dnssec-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12368
2026-07-08 21:08:51 +02:00
Ondřej Surý
205cd3509f Cover exact-name NODATA synthesis from a pending NSEC
The #5872 reproducer plants a covering NSEC that is rejected inside the
cache (find_coveringnsec), so it never reaches the trust check on the
exact-match NODATA branch of query_coveringnsec(). This adds a companion
case: an NSEC owned by the victim name itself, injected at pending trust
via a CD=1 query, is returned by the cache as a NODATA proof for the
exact node and must not be used to synthesize a NODATA that would deny
the victim's real A record.

Reuses the f004.test fixture with a victim-owned forged NSEC.

Assisted-by: Claude:claude-fable-5
(cherry picked from commit dc02732883)
2026-07-08 15:29:25 +02:00
Evan Hunt
b4d2a73e1d Merge NSEC synthesis tests
Merge the tests for "nsec_child_next" and "nsec_pending_cd" into
"nsec_synthesis".

(cherry picked from commit 91955ca087)
2026-07-08 15:29:25 +02:00
Alessio Podda
ffc281f029 Reproducer for #5887 out of zone NSEC-next syntheisis
Create the "nsec_child_next" system test.

Co-Authored-By: Evan Hunt <each@isc.org>
(cherry picked from commit 454bb99da4)
2026-07-08 15:29:25 +02:00
Alessio Podda
4b212c1a5f Reproducer for #5872 cache pending synthesis
Create the "nsec_pending_cd" system test.

Co-Authored-By: Matthijs Mekking <matthijs@isc.org>
(cherry picked from commit 760f63f147)
2026-07-08 15:29:25 +02:00
Alessio Podda
2795f4bece Reproducer for #5977 cache poison NSEC piggyback
Create a new "nsec_piggyback" system test.

Co-Authored-By: Matthijs Mekking <matthijs@isc.org>
(cherry picked from commit ace05a3cb8)
2026-07-08 15:29:25 +02:00
Evan Hunt
836825611d Don't synthesize negative responses with pending NSEC
If a cached record has not yet been validated and has trust
level pending, don't use it to synthesize negative responses.

Fixes: isc-projects/bind9#5872
Fixes: isc-projects/bind9#5887
Fixes: isc-projects/bind9#5977
(cherry picked from commit adb5c63e70)
2026-07-08 15:29:25 +02:00
Ondřej Surý
cd006ecf23 [9.20] fix: usr: Fix DNSSEC validation failures for names under an apex DNAME
DNSSEC validation could fail with SERVFAIL for names covered by a DNAME
at the apex of a signed zone, unless the zone's keys were already validated
in the cache. This regression was introduced by the recent fix for resolver
stalls on CNAME responses to DS queries.

Closes #6176

Backport of MR !12353

Merge branch 'backport-6176-validator-apex-dname-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12356
2026-07-08 13:02:32 +02:00
Ondřej Surý
b7178ff652
Add a system test resolving through a signed apex DNAME
The dnssec system test signs a DNAME-at-apex zone but only ever
queried the apex directly; nothing resolved a name under the DNAME
through the validating resolver, so a validator regression on that
path went unnoticed.

Assisted-by: Claude:claude-fable-5
(cherry picked from commit 38992e02bb)
2026-07-08 12:24:43 +02:00
Ondřej Surý
7ced319c66
Restrict the alias-chain deadlock check to chaining CNAMEs
check_deadlock() aborted any fetch whose name equals the owner of a
chaining rdataset, assuming nothing the validator needs can live at an
alias.  That is true for a CNAME, but a DNAME aliases only the names
below its owner: with a DNAME at a zone apex, the DNSKEY signing the
DNAME lives at the owner name itself, so every answer synthesized from
a signed apex DNAME failed validation whenever that key was not
already validated in the cache.

Chaining CNAMEs, including those synthesized from a DNAME, still cover
the self-join case the check was added for.

(cherry picked from commit 057ae0adb8)
2026-07-08 12:23:45 +02:00
Matthijs Mekking
3307a98c27 [9.20] new: test: Test multi-master dnssec-policy setup
Update the manual rollover system test with a multi-master setup.

Backport of MR !11268

Merge branch 'backport-matthijs-test-dnssec-policy-multimaster-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12360
2026-07-07 15:36:32 +00:00
Matthijs Mekking
dda2c57a28 Test multi-master dnssec-policy setup
Update the manual rollover test case with a multi-master setup.  In this
scenario, key files are generated, as well as rollovers are started
on one server (ns3) and key files are copied to the other server (ns4).

Add checks that the begin and end key states are the same.

(cherry picked from commit affe84e55b)
2026-07-07 14:59:08 +00:00
Arаm Sаrgsyаn
9baad48be0 [9.20] fix: dev: Include the IPv6 address's brackets in the parsed URL/URI host
The brackets are not included in the host component of the parsed
URL/URI. Change the parser to include the brackets.

Closes #6147

Backport of MR !12266

Merge branch 'backport-6147-isc_url_parse-ipv6-brackets-fix-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12362
2026-07-07 14:10:26 +00:00
Aram Sargsyan
19efc4be5a Include the brackets when parsing a URI with a IPv6 address
The brackets are not included in the host component of the parsed
URL/URI. Change the parser to include the brackets.

(cherry picked from commit f85d9f5ef3)
2026-07-07 13:24:33 +00:00
Arаm Sаrgsyаn
f4c8f08042 [9.20] fix: dev: Improve the input validation of the isc_url_parse() function
The isc_url_parse() function failed to check the input buffer's
length and assumed that it can't be bigger than UINT16_MAX, because
both the 'off' and 'len' fields of the 'isc_url_parser_t' structure
are uint16_t.

Add a check to not accept a buffer longer than 8192 octets.

Closes #6150

Backport of MR !12252

Merge branch 'backport-6150-isc_url_parse-buffer-size-check-fix-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12361
2026-07-07 13:21:10 +00:00
Aram Sargsyan
d39d0410d0 Limit allowed URL/URI size to 8192 bytes in the parser
RFC 9110 Section 4.1 recommends at least 8000 octets, and 65535
is too excessive. Limit the maximum length to 8192 octets.

(cherry picked from commit efa8ca2267)
2026-07-07 12:00:40 +00:00
Ondřej Surý
383f483d98 Add IPv6 and authority cases to the isc_url_t unit test
Cover IPv6 literal hosts (the brackets are stripped from the host, zone
identifiers are kept verbatim), userinfo, explicit ports and case
preservation, plus inputs that isc_url_parse() rejects although a generic
RFC 3986 parser would accept them: a '+' in the scheme, an IPvFuture
literal, and a percent-encoded port. The cases are drawn from the
Addressable URI test suite. The shared table runner is factored out so
both table-driven tests reuse it.

Assisted-by: Claude:claude-opus-4-8
(cherry picked from commit 874f34545f)
2026-07-07 12:00:40 +00:00
Ondřej Surý
bd8d5d2a52 Extend the isc_url_t unit test with RFC 3986 cases
Parse the absolute URIs from RFC 3986 section 5.4 and verify the
component split, and assert the input-length boundary (UINT16_MAX is
accepted, UINT16_MAX + 1 is rejected). isc_url_parse() splits request
targets but does not resolve relative references, so the dot-segments
in path/query/fragment are expected to survive verbatim.

Assisted-by: Claude:claude-opus-4-8
(cherry picked from commit 220a270930)
2026-07-07 12:00:40 +00:00
Aram Sargsyan
bf58c9d9d8 Add a unit test for isc_url_t
The test has some basic checks for the URL/URI parser.

(cherry picked from commit 3bd33a817a)
2026-07-07 11:37:22 +00:00
Aram Sargsyan
fe24f3249b Add a maximum length for isc_url_parse() input buffer
The isc_url_parse() function failed to check the input buffer's
length and assumed that it can't be bigger than UINT16_MAX, because
both the 'off' and 'len' fields of the 'isc_url_parser_t' structure
are uint16_t.

Add a check to not accept a buffer longer than UINT16_MAX.

(cherry picked from commit b878f82409)
2026-07-07 11:23:31 +00:00
Evan Hunt
c3733e12f9 [9.20] fix: usr: Unvalidated opt-out NSEC3 could be accepted in insecurity proof
When determining whether an insecure delegation is legitimate, NSEC3 opt-out records which had not yet passed validation could be used. This has been fixed.

Closes #5970

Backport of MR !12283

Merge branch 'backport-5970-pending-nsec3-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12358
2026-07-03 08:16:33 +00:00
Evan Hunt
b358cea3cb Merge "nsec3_wrong_zone" into "dnssec_nsec3"
These tests are similar in structure and topic, and can be merged.

(cherry picked from commit abd274c1fd)
2026-07-03 00:37:28 -07:00
Alessio Podda
ae1e30f963 Reproducer for #5970 acceptance of unvalidated NSEC3
Add "dnssec_nsec3" system test.

Co-Authored-By: Evan Hunt <each@isc.org>
(cherry picked from commit fdecacf07a)
2026-07-03 00:37:28 -07:00
Evan Hunt
c79ae4e8ca Unvalidated opt-out NSEC3 could be accepted in insecurity proof
Ignore NSEC3 records that failed in the sub-validator when determining
whether an insecure delegation is legitimate.

Fixes: isc-projects/bind9#5970
(cherry picked from commit 1bd458d3ba)
2026-07-03 00:37:28 -07:00
Evan Hunt
3e6cef2ac6 [9.20] fix: usr: Don't evict DNSSEC-validated cache data on a CD=1 NXDOMAIN
When a client sent a query with the checking-disabled (CD) bit set and the
answer was NXDOMAIN, the resolver cached that unvalidated negative response and
discarded any DNSSEC-validated records it already held for the same name, even
though the validated data was more trustworthy. A single such response -
including a forged one - could flush validated records from the cache and force
the resolver to fetch them again. The resolver now checks the trust level of the
existing data first and leaves the cache unchanged when it is already validated.

Closes #5877

Backport of MR !11946

Merge branch 'backport-5877-cd-nxdomain-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12344
2026-07-02 22:45:04 +00:00
Ondřej Surý
ec75f25f47 Add a system test for CD=1 NXDOMAIN cache protection
Cache a DNSSEC-validated A record, then make a CD=1 query elicit an
unvalidated NXDOMAIN for the name: the secure RRset must survive, and an
uncached-type query must not get the wrong RRset back.

Assisted-by: Claude:claude-opus-4-8
(cherry picked from commit ddb6cb5c93)
2026-07-02 15:04:19 -07:00
Evan Hunt
f1d218e898 Check for secure data before caching CD=1 NXDOMAIN
An unvalidated NXDOMAIN (e.g. from a CD=1 query) marked every RRset at
the name ancient without checking trust, evicting DNSSEC-validated data.
Keep the cache unchanged when any existing RRset is already secure.

dns_ncache_add() now returns DNS_R_UNCHANGED for the rejected add;
negcache() serves a matching cached negative or the queried type, else
SERVFAIL (never the unrelated RRset the add bound), and rctx_ncache()
forwards it so the fetch fails fast.

(cherry picked from commit a7a90eb9d8)
2026-07-02 15:04:19 -07:00
Mark Andrews
5c153b85e5 [9.20] fix: usr: Properly detect private records before copying
We were triggering an assertion when trying to copy a private record
to a buffer for modifying.  Extend the private type detection and
copy the contents after we have rejected invalid private records.

Closes #5857

Backport of MR !11816

Merge branch 'backport-5857-properly-detect-private-records-before-copying-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12340
2026-07-03 04:46:34 +10:00
Mark Andrews
998416777e Test oversized private record is properly ignored
(cherry picked from commit 5725c4191f)
2026-07-03 04:07:30 +10:00
Mark Andrews
f81a1cfa8e Add DNS_PRIVATE_BUFFERSIZE and use it
The size of a private records is 1 byte more than the corresponding
NSEC3PARAM record.

(cherry picked from commit 5d7387b185)
2026-07-03 04:07:30 +10:00
Mark Andrews
0136a1f4ca Properly detect private records before copying
We were triggering an assertion when trying to copy a private record
to a buffer for modifying.  Extend the private type detection and
copy the contents after we have rejected invalid private records.

(cherry picked from commit 7182a03b82)
2026-07-03 04:07:30 +10:00
Nicki Křížek
f11e61a98b [9.20] fix: test: Support serving signed child zone from its parent's nameserver
When a signed zone is served by the same nameserver instance as
its parent, the child's dnssec-signzone has already written
dsset-<child>. into that directory. Don't attempt to copy the dsset if
the destination and source files are the same.

Assisted-by: Claude:claude-opus-4-8

Backport of MR !12354

Merge branch 'backport-nicki/serve-signed-child-same-ns-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12355
2026-07-02 17:19:03 +02:00
Nicki Křížek
f7c2ac088e Support serving signed child zone from its parent's nameserver
When a signed zone is served by the same nameserver instance as
its parent, the child's dnssec-signzone has already written
dsset-<child>. into that directory. Don't attempt to copy the dsset if
the destination and source files are the same.

Assisted-by: Claude:claude-opus-4-8
(cherry picked from commit 246cca357b)
2026-07-02 14:42:43 +00:00
Nicki Křížek
c25dc44ccb [9.20] chg: test: Unify system test key and algorithm handling
This is a followup from https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/11807.

De-duplicates the key material handling and moves algorithm-related things into a dedicated shared module.

Backport of MR !12255

Merge branch 'backport-nicki/pytest-key-reconcile-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12351
2026-07-02 16:38:57 +02:00
Nicki Křížek
4a93ba83a9 Move algorithm definitions into a top-level isctest.algorithms module
The Algorithm type, the per-algorithm constants, and the ALL_ALGORITHMS*
lookup tables are general DNSSEC key definitions used across isctest
package and the tests. Move them into a dedicated module to separate
these from the environment-specific setup that remains in
isctest.vars.algorithms.

Assisted-by: Claude:claude-opus-4-8
(cherry picked from commit 4d76b7bd9e)
2026-07-02 15:45:49 +02:00
Nicki Křížek
9a420bde2f Add private_key support to all ZoneKey implementations
Extend the ZoneKeyFile to read the file-backed private key and return it
in a format suitable for use with dnspython. Add ZoneKey.private_key
property to unify the interface.

(cherry picked from commit ee73ba3bba)
2026-07-02 15:45:49 +02:00
Nicki Křížek
a7c9dfe169 Use the algorithm.number interface 2026-07-02 15:45:49 +02:00
Nicki Křížek
9d5b97db80 Add NSEC3RSASHA1 to list of algorithms
This algorithm is deprecated and not currently used in our system tests,
but it should be in the list of all algorithms.

(cherry picked from commit 596e41553c)
2026-07-02 15:45:49 +02:00
Nicki Křížek
cad0939602 Move dnskey method from kasp.Key to zone.FileZoneKey
Code move with one change - switch dnskey TTL from 300s (DEFAULT_TTL) to
3600s (DNSKEY_TTL).

Assisted-by: Claude:claude-opus-4-8
(cherry picked from commit 55cd4a1e11)
2026-07-02 15:45:49 +02:00
Nicki Křížek
df7e8cf6bb Merge kasp.Key functionality into zone.FileZoneKey
Make zone.FileZoneKey the single representation of a file-backed key
(typically generated by dnssec-keygen). Move the common key-related
functionality into zone.FileZoneKey, and extend that functionality in
kasp.Key to also add state and timing related operations on top. Remove
duplicate into_ta() function.

Note that is_ksk() is implemented differently for kasp.Key: with the
metadata file available, the KSK status is loaded from that file, as it
indicates the authoritative policy decision which makes the key a KSK.
In zone.FileZoneKey which doesn't work with the metadata file, the KSK
status if inferred from the DNSKEY SEP flag - the best information
available for that class.

Assisted-by: Claude:claude-opus-4-8
(cherry picked from commit 35fc5ce8b4)
2026-07-02 15:45:49 +02:00
Nicki Křížek
c5f4d66e73 Read DNSKEY TTL from kasp.Key.dnskey
Remove the redundant ttl() method. The DNSKEY RR already provides the
TTL.

(cherry picked from commit 9dc039f735)
2026-07-02 15:45:49 +02:00
Michał Kępień
2817844b80 [9.20] chg: test: Update AsyncDnsServer-related test cookbook parts
Add practical tips about specific handler classes.  Mention some good
practices and point developers at existing code written in the desired
manner.  Document common pitfalls.  Suggest preferred approaches for
splitting up complex response handling code.

Backport of MR !12260

Merge branch 'backport-michal/update-asyncdnsserver-related-test-cookbook-parts-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12352
2026-07-02 15:18:46 +02:00
Michał Kępień
3665c94e56
Move ans.py-related information to README.md
COOKBOOK.md is supposed to be minimal and heavy on examples, so move the
lengthy section about implementing custom ans.py servers from
COOKBOOK.md to README.md.

(cherry picked from commit edd765a092)
2026-07-02 15:17:03 +02:00
Michał Kępień
1072686f46
Update AsyncDnsServer-related test cookbook parts
Add practical tips about specific handler classes.  Mention some good
practices and point developers at existing code written in the desired
manner.  Document common pitfalls.  Suggest preferred approaches for
splitting up complex response handling code.

(cherry picked from commit a48e5cd98d)
2026-07-02 15:17:03 +02:00
Alessio Podda
cdbc5be8b0 [9.20] fix: usr: Reject external referrals from forwarders
Under `forward-first` policy in a forwarding zone BIND could accept NS above the forward zone apex from negative responses. This has been fixed.

ISC would like to thank Qifan Zhang, of Palo Alto Networks, for the report.

Closes #5937

Backport of MR !12154

Merge branch 'backport-5937-fix-forward-first-referral-bailiwick-v2-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12278
2026-07-02 12:26:26 +00:00
Alessio Podda
a0b2777ba5 Reject referrals from global forwarders
Reject referrals from root/global forwarders, where there is no narrower
forward-zone apex for name_external() to enforce.

(cherry picked from commit 18f4db8f1b)
2026-07-02 11:50:20 +00:00
Alessio Podda
4d97a40a97 Reject external referrals for forward zones
Apply the existing name_external() bailiwick check to NS RRsets
processed as referrals in rctx_authority_negative(), and enforce the
same check again in rctx_referral() before caching or following the
delegation.

This prevents a forward-first forwarder from installing a parent
zone-cut above the configured forward zone via an authority-section
NS RRset.

(cherry picked from commit 492d11fa39)
2026-07-02 11:50:20 +00:00
Alessio Podda
8e546f019f Add forward-first referral poisoning reproducer
Add a system test covering authority-section NS referrals returned by
configured forwarders under forward first.

The test verifies that a forwarder for fwd.hack cannot install the
parent hack zone cut and redirect resolution for the sibling zone
sibling.hack.

(cherry picked from commit ee34bbd208)
2026-07-02 11:50:20 +00:00
Ondřej Surý
8a8cc34a50 [9.20] fix: dev: Correct locator decoding for NID, L64, and L32 records
NID, L64, and L32 records were decoded incorrectly when converted into their
parsed structures, because the preference field was not skipped before the
locator.

Closes #6097

Backport of MR !12348

Merge branch 'backport-6097-nid-l64-l32-tostruct-consume-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12349
2026-07-02 13:31:51 +02:00
Ondřej Surý
4e6028883d Add NID/L64/L32 round-trip coverage to the rdata unit test
These types had no entries in the rdata test table, so the
tostruct/fromstruct round-trip in check_struct_conversions() never ran
against them -- which is why the missing preference consume in their
tostruct routines went unnoticed for years. Add text and wire vectors
for all three.

Assisted-by: Claude:claude-fable-5
(cherry picked from commit f28bea94e3)
2026-07-02 10:55:30 +00:00