Commit graph

44477 commits

Author SHA1 Message Date
Ondřej Surý
4fa5b6a95a
Test that a fresh negative cache entry is not refreshed
The existing serve-stale tests all use negative answers with a two
second TTL, because they are there to exercise stale data.  Nothing
covered the far more common case of a negative answer that is still
fresh, which is how the needless refresh went unnoticed.

ans2 grows a NODATA and an NXDOMAIN name backed by a SOA with a 600
second TTL and MINIMUM, so the cached entry cannot go stale while the
test runs, and the test counts the queries that reach ans2: priming the
cache may send one, the repeated client queries must send none.

Assisted-by: Claude:claude-opus-4-8
(cherry picked from commit 60b3cc0eca)
2026-07-10 12:07:08 +02:00
Ondřej Surý
4afd5b0462
Only refresh negative cache entries that are actually stale
query_ncache() always passed a NULL rdataset to query_stale_refresh(),
which reads NULL as "this RRset is stale".  NULL is only meaningful for
the DNS64 caller, whose rdataset has already been detached by the time
the answer is turned into an NXDOMAIN; everywhere else a perfectly fresh
negative cache entry was taken for a stale one.

With stale-answer-client-timeout 0 the staleness check is the only gate
left on the refresh, so every client query for a cached NXDOMAIN or
NODATA name started another fetch and negative caching stopped having
any effect.

(cherry picked from commit 4821290c31)
2026-07-10 12:07:08 +02:00
Michał Kępień
f3230783c2 chg: doc: Set up version for BIND 9.20.26
Merge branch 'michal/set-up-version-for-bind-9.20.26' into 'bind-9.20'

See merge request isc-projects/bind9!12383
2026-07-10 10:38:15 +02:00
Michał Kępień
17457add58
Update BIND version to 9.20.26-dev 2026-07-10 10:36:36 +02:00
Ondřej Surý
87397c823d [9.20] fix: dev: Print the full OID in PRIVATEOID key comments
The OID in the "; alg = ..." comment of a PRIVATEOID key was truncated to sixteen characters.

Closes #6092

Backport of MR !12377

Merge branch 'backport-6092-fix-PRIVATEOID-output-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!12378
2026-07-09 17:01:06 +02:00
Ondřej Surý
6a268314ed Print the full OID in PRIVATEOID key comments
The OID printed in the "; alg = ..." comment of a PRIVATEOID KEY,
DNSKEY, CDNSKEY or RKEY record was truncated to sixteen characters:
1.2.840.113549.1.1.11 came out as 1.2.840.113549.1.  Only the comment
was ever affected, never the record itself.

(cherry picked from commit 4ba4b3bd8f)
2026-07-09 14:24:18 +00:00
Nicki Křížek
b6bfa444e5 fix: dev: Require secure trust for covering NSEC in the RBT cache
The guard against synthesizing negative answers from a pending NSEC
(#5977) was only added to the QP cache's find_coveringnsec(); the RBT
cache database kept binding any covering NSEC regardless of trust.  On
builds configured with --with-cachedb=rbt this lets a piggy-backed,
unvalidated NSEC drive a synthesized NXDOMAIN, reviving the cache
poisoning that was fixed for the default cache.

query_coveringnsec() only verifies the covering NSEC's trust on its
NODATA path; the NXDOMAIN path relies on the database returning a
secure record.  Require the NSEC and its RRSIG to be dns_trust_secure
in find_coveringnsec(), matching the QP cache.

Closes #5977

Merge branch '5977-rbt-cachedb-covering-nsec-secure-trust' into 'bind-9.20'

See merge request isc-projects/bind9!12374
2026-07-09 13:14:00 +02:00
Nicki Křížek
e675db2e49 Require secure trust for covering NSEC in the RBT cache
The guard against synthesizing negative answers from a pending NSEC
(#5977) was only added to the QP cache's find_coveringnsec(); the RBT
cache database kept binding any covering NSEC regardless of trust.  On
builds configured with --with-cachedb=rbt this lets a piggy-backed,
unvalidated NSEC drive a synthesized NXDOMAIN, reviving the cache
poisoning that was fixed for the default cache.

query_coveringnsec() only verifies the covering NSEC's trust on its
NODATA path; the NXDOMAIN path relies on the database returning a
secure record.  Require the NSEC and its RRSIG to be dns_trust_secure
in find_coveringnsec(), matching the QP cache.

Assisted-by: Claude:claude-opus-4-8
2026-07-09 08:55:01 +00:00
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