Commit graph

7121 commits

Author SHA1 Message Date
Colin Vidal
ea2cb4e9df test for auth+res server and glues in delegation
When a resolver+auth server has a delegation on a local zone and has a
glue, the glue can only be for in-domain NS.

In this case, when the resolver is looking at the zonecut,
`dns_view_bestzonecut()` synthesizes a delegset from an NS rdataset
found in the local zone (the delegation inside auth zone), and ignores
the glues if any.

As a result, the delegset will contain a single delegation of type
DNS_DELEGTYPE_NS_NAMES, which leads to an ADB fetch. But it's actually an
in-memory fetch, because in this case, the fetch will immediately find
the A/AAAA glues from the local zone.

An alternative approach (not chosen here) would be to make
`dns_view_bestzonecut()`, when converting an NS rdataset into a
`dns_deleg_t`, check for glues for the delegation in the auth zone, and
add those in the `dns_deleg_t`. The delegation would be of type
DNS_DELEGTYPE_NS_GLUES which would avoid the ADB name lookup.

However, that's extra code, extra logic and complexities, for a lookup
that will be done in memory anyway, just a bit later. So for now, this
is not implemented that way.

The test is added, however, to confirm that there is no attempt from the
resolver to get the NS fron the child zone.
2026-03-30 20:41:13 +02:00
Evan Hunt
dc6202479f remove find_deepest_zonecut() from qpcache
because the cache no longer stores delegation (parent-side) NS rrsets,
and authoritative (child-side) NS rrsets don't affect recursion,
it no longer makes sense for qpcache_find() to look for NS rrsets
and return DNS_R_DELEGATION. that code has been removed.

the cache still does search for covering DNAME records. the
check_zonecut() function has been renamed to check_dname() for clarity.

related changes:
- one test case has been removed from the mirror system test, because it
  tested the behavior of a cached delegation.
- query_checkrrl() and rpz_rrset_find() have been updated so they no
  longer expect cache responses to have DNS_R_DELEGATION response codes.
2026-03-30 20:41:13 +02:00
Colin Vidal
f20a612ae7 system test for rndc dumpdb -cache and reload
Add system test which check the behavior of `rndc dumpdb -cache` as well
as the preservation of the delegation cache on server reload.
2026-03-30 20:41:13 +02:00
Evan Hunt
d2286d2633 prevent early termination of rpzrecurse test
add "|| ret=1" after calls to dig, so that dig failures won't
stop the test due to "set -e".
2026-03-30 20:41:13 +02:00
Evan Hunt
cd4a7a2d72 Fix fetchlimit test failure
When a referral lookup is triggered by a QMIN query, it should be
exempt from the fetches-per-zone limit just as the QMIN query itself
is.

Also restart the test server between the fetches-per-server and
fetches-per-zone tests so that leftover statistics from the former
do not pollute the latter.

Another fix is because zone spills and general query drops are no longer
in a strict >= relation (on a parent-centric resolver), so check that
both counters are non-zero instead.
2026-03-30 20:41:13 +02:00
Evan Hunt
d1ea49cef9 Fix chain system test for parent-centric resolver
The resolver now uses glue addresses from the parent side of a
zonecut without triggering an additional address lookup.  Update the
test involving a nameserver target name below a DNAME so that the
delegation does not use glue.
2026-03-30 20:41:13 +02:00
Colin Vidal
f2f9a97526 Do not cache NS from referral in negative responses
Stop storing the NS referral into the main cache when processing a
negative response.  These records are already cached in the delegation
database and are not needed elsewhere.

Update dnssec tests that relied on parent-side NS RRsets being
returned in recursive query responses.
2026-03-30 20:41:13 +02:00
Colin Vidal
6735613af3 Fix cacheclean system test for parent-centric resolver
The ADB flushtree test was failing because the test zone
(flushtest.example.) uses an in-domain nameserver with parent glue,
so the ADB cache was never populated.

Add a new zone with an out-of-domain nameserver to force an ADB
lookup and ensure the flushtree test exercises the intended code
path.
2026-03-30 20:41:13 +02:00
Colin Vidal
009fa6173d Simplify resolver delegation expiry test
Remove the dynamic NS update loop from the delegation expiry test.
With the delegation DB, it is sufficient to wait for the delegation
to expire (after 5 seconds) and verify that names below the removed
zone return NXDOMAIN.
2026-03-30 20:41:13 +02:00
Evan Hunt
8d3df06100 Fix tests for parent-centric resolver behavior
In 'additional', pre-cache the A RRset for ns1.rt.example so the
additional-data handling in the cache can be tested; previously this
was cached as part of resolution, but now must be queried explicitly.

In 'cookie', pre-cache an NS to prevent a QMIN query from distorting
log results and causing a test failure.

In 'resolver', increase the expected query count in the timeout test.
2026-03-30 20:41:13 +02:00
Colin Vidal
1ff19bd43d Fix qmin test with parent-centric resolver
Remove expected queries for ns2 addresses (and ns.b.stale.) from the
qmin system test.  The parent-centric resolver no longer attempts to
get the child-side NS of the delegation, so these queries do not
occur.
2026-03-30 20:41:13 +02:00
Colin Vidal
355e762e69 update camp system test max-query-count
As named is now parent-centric, the global query count can be lower (in
particular for queries which has a long delegation chain), as the
resolver doesn't proactively resolve an NS name when a glue is provided
by the parent-side of a zonecut.

Update camp system test to lower the max-query-count of ns9, to ensure
the max-query-count limit enforcement is still working.
2026-03-30 20:41:13 +02:00
Colin Vidal
35e19ee660 Add system test for minimal-responses behaviour
Add the 'minimalresponses' system test in order to cover the multiple
combinations of server 'minimal-responses' configurations and contexts
(resolver, auth only, etc.) when filling the ANSWER, AUTHORITY and
ADDITIONAL sections.
2026-03-30 20:41:13 +02:00
Evan Hunt
12e5113100 Make the RD flag optional in isctest.query()
Add an 'rd' parameter (default True) to isctest.query.create() so
that non-recursive queries can be sent with rd=False.
2026-03-30 20:41:13 +02:00
Evan Hunt
a9883483ef Remove dns_db_findzonecut()
This function is no longer used and has been removed, along with its
implementation in qpcache.
2026-03-30 20:41:13 +02:00
Evan Hunt
3704cf42eb Don't use dns_db_findzonecut() in query_addbestns()
Previously, when answering from the cache, and when minimal-responses
was not set, we added the best known zone cut to the authority section
of the response message, using dns_db_findzonecut() to look it up in
the DNS cache.  Since the DNS cache will no longer be used to store
parent-side NS RRsets, it will now be possible for an ancestor node
to be used as the zone cut, leading to the wrong NS record being
included.

There are various ways we could correct this:

1. Use dns_deleg_lookup() instead of dns_db_findzonecut() to find the
   zone cut. But currently, the deleg database stores only the server
   addresses for the delegation, not the full NS RRset; this would need
   to be changed.
2. Look up <name>/NS whenever we cache a referral; that way we'll get
   the child-side NS RRset and cache that, and we can retrieve it when
   building the response.

But the solution chosen here is simply not to look up the NS record
when answering from the cache, effectively making "minimal-responses
yes;" mandatory for queries answered from the cache.

System tests have been updated as needed, so they no longer expect
NS RRsets in the authority section of recursive responses.
2026-03-30 20:41:13 +02:00
Aram Sargsyan
357331f886 Revert NTA flush on expire
Flushing the name when NTA expires causes problems for the ongoing
resolving process. Do not flush the name from the cache. Instead,
the resolver should do the flushing (this is planned to be merged
next).
2026-03-30 18:27:35 +00:00
Ondřej Surý
bac40394d5 Fix update-policy per-type max quota bypass via counter desynchronization
The prescan and main update loops in DNS UPDATE processing both used the
same counter to index the maxbytype[] quota array.  The prescan loop
always incremented the counter, but the main loop had 14 continue paths
that skipped the increment.  This allowed an authenticated DDNS client to
craft an UPDATE message with padding records (e.g. CNAME+A pairs that
trigger CNAME-conflict skips) to shift the counter and read wrong quota
entries, bypassing per-type record limits entirely.

Fix by incrementing the counter unconditionally at the start of each
iteration in the main loop.
2026-03-28 10:07:49 +01:00
Aram Sargsyan
b82966000e Test an empty APL record as catalog zone ACL
Test that named can process an empty APL record as a valid catalog
zone ACL.
2026-03-27 12:00:21 +00:00
Mark Andrews
f5d90117ec Test that delv +cookie and delv +nocookie work 2026-03-26 11:18:26 +11:00
Michał Kępień
48bf3d3e65
Rename "nsec3-delegation" to "nsec3_delegation"
The "nsec3-delegation" test was added in a release branch, before commit
67aca1f8c6 introduced the current system
test naming convention.  Rename the test to comply with that convention.
2026-03-25 15:36:17 +01:00
Michał Kępień
b0fc0e31c5 Merge tag 'v9.21.20' 2026-03-25 14:23:41 +00:00
Colin Vidal
2130d4fecc remove legacy NS processing limit check
Commit `604d8f0b967563b0ba9dcd4f09559fdd9e21dfbe` introduced during 9.19
development cycle a check to ensure the resolver never attempts to
lookup more than 20 NS names. This limit was introduced by
`3a44097fd6c6c260765b628cd1d2c9cb7efb0b2a` as part of the CVE-2022-2795.

However, this test relies on the fact that, at the time, the NS names
were processed in a specific order in the nameserver, as this snip from
the log (from a build on `604d8f0` branch) running the test illustrates:

```
24-Mar-2026 21:19:46.346 dispatch 0x7fdaa722d200: success, length == 19956, addr = 0x7fdaa0a7c102
24-Mar-2026 21:19:46.346 dispatch 0x7fdaa722d200: got valid DNS message header, /QR 1, id 14328
24-Mar-2026 21:19:46.346 dispatch 0x7fdaa722d200: search for response in bucket 7213: success
24-Mar-2026 21:19:46.354 received packet from 10.53.0.3#5300
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id:  14328
;; flags: qr aa; QUESTION: 1, ANSWER: 0, AUTHORITY: 999, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
; COOKIE: baf16b0241efc700
;; QUESTION SECTION:
;large-referral.example.net.	IN	A

;; AUTHORITY SECTION:
;large-referral.example.net. 300	IN	NS	ns1.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns2.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns3.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns4.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns5.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns6.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns7.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns8.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns9.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns10.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns11.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns12.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns13.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns14.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns15.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns16.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns17.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns18.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns19.fake.redirect.com.
;large-referral.example.net. 300	IN	NS	ns20.fake.redirect.com.
```

This is not true anymore, as the NS are in a random order. Moreover,
commit `3c33e7d9370006b1599e3d99c0d5fa6a6dad7979` introduced the
randomization of the selection of the NS names to lookup, which make the
test potentially unreliable, as it now doesn't mean anything to check
the nameserver does not query `ns21.fake.redirect.com.`, as it could be
the first one, or in any position form the randomized list.

Another test has been added in commit
`c67b52684f11652b07afaa75a917f6f0355dbca6` which test both the
randomization of the NS name to be looked up, as well as the upper bound
limit of NS  name lookup to be done.

For all those reasons, this specific legacy check is now removed.
2026-03-25 01:09:28 +00:00
Evan Hunt
2393be779c remove -C option from dnssec-keygen and dnssec-keyfromlabel
The -C option, introduced in BIND 9.7, caused a backward-compatible
key to be generated, using private key format version 1.2, omitting the
creation date and other timing metadata. This made it possible to
generate keys that could be loaded by older versions of BIND.

Those older versions having reached end of life many years ago, the
option can now be removed, along with the "dnssec-settime -f" option,
which caused old-style keys to be upgraded.
2026-03-24 02:17:57 -07:00
Evan Hunt
ae67c1851d rpz_rrset_find() now recurses on ISC_R_NOTFOUND
previously, rpz_rrset_find() behaved differently depending on whether
a cache lookup returned DNS_R_DELEGATION or ISC_R_NOTFOUND.  the former
indicates the presence of a cached NS rrset, and the latter indicates
that the cache is cold or that all NS rrsets above the query name have
expired. both results indicate that the caller should recurse, but
rpz_rrset_find() only recursed in the case of DNS_R_DELEGATION.

the nsip-wait-recurse and nsdname-wait-recurse test cases in the
rpzrecurse system test were dependent on this misbehavior. the test
server was configured with a lame delegation, so that recursion always
failed, but once the lame delegation was expired due to a zero TTL, the
cache returned ISC_R_NOTFOUND, which caused the recursion not to be
attempted. the test seemed to be observing a delay before recursion
succeeded, but it was actually observing a delay before recursion was
skipped. fixing this bug caused the test to fail.

the test server has now been reconfigured so that recursion succeeds
after a delay, instead of failing. now we're able to test that
we're waiting for the successful completion of recursion.
2026-03-23 12:30:16 -07:00
Ondřej Surý
c503b6eee8
Add regression test for TOCTOU race in DNS UPDATE SSU handling
Race rndc reconfig (toggling between allow-update and update-policy)
against a stream of DNS UPDATEs for 5 seconds and verify that named
does not crash.

Before the fix, the race between send_update() and update_action()
reading the SSU table independently could trigger an assertion
failure (INSIST) when the zone's update policy changed between the
two reads.
2026-03-23 11:10:48 +01:00
Aram Sargsyan
ce98b71eb4
Check that cached data is flushed when NTA expires 2026-03-19 00:12:59 +01:00
Nicki Křížek
67aca1f8c6 Rename all system test to use underscore
All system tests previously using a hyphen have been renamed to use
underscore instead. A couple of symlinks were corrected and one path in
`nsec3-answer` adjusted accordingly.
2026-03-18 14:32:33 +01:00
Nicki Křížek
9f4c1d1993 Use underscore for system test names
Change the convention for system test directory names to always use an
underscore rather than a hyphen. Names using underscore are valid python
package names and can be used with standard `import` facilities in
python, which allows easier code reuse.

The temporary directories for test execution and their convenience
symlinks have been switched to using hyphens rather than underscores to
keep the pytest collection, filtering and .gitignore working as
expected.
2026-03-18 14:32:33 +01:00
Matthijs Mekking
46e98295bb
Remove LDMB checks from system tests
Now that LMDB is required, there is no need to check if the feature is
enabled in the system tests.
2026-03-18 11:02:33 +01:00
Ondřej Surý
7f8b972a3d
Remove NZF support, make LMDB required for new zone storage
Drop the NZF (New Zone File) fallback for persisting runtime zone
configurations, making LMDB (NZD) the only storage backend. This
removes all #ifdef HAVE_LMDB conditionals, the meson 'lmdb' option,
and the NZF-related functions. LMDB is now a mandatory build
dependency.

The named-nzd2nzf tool is now always built.
2026-03-18 11:02:33 +01:00
Matthijs Mekking
900127c460 Test showzone and modzone on configured zone
Add test cases for 'rndc showzone' and 'rndc modzone' on a zone
that was configured in named.conf. This should not crash.
2026-03-16 15:18:39 +01:00
Ondřej Surý
613a93478b
Add system test using SIG(0) and ACL matching
This adds a system test to verify that asynchronous SIG(0)
validation correctly retains the ACL environment and network
addresses of the caller, preventing unauthorized ACL bypass
when evaluating match-clients and match-destinations.
2026-03-13 13:47:17 +01:00
Aram Sargsyan
ab77b3dffa
Test sending a TKEY query with deletion and unrecognized modes
This new test sends two signed TKEY queries, one in delegation
mode and one in an unrecognized mode to check that named
correctly processes them.

Co-authored-by: Nicki Křížek <nicki@isc.org>
2026-03-13 13:38:07 +01:00
Nicki Křížek
a338e254be
Test excessive RRSIG(NSEC) in signed zones
Trigger a memory leak by adding extra RRSIG(NSEC) to a signed zone which
exceeds the resolver's configured max-records-per-type limit.
2026-03-13 13:18:48 +01:00
Nicki Křížek
9bc14a89f1
Reproducer for CVE-2026-1519
When a validating resolver processes a delegation from a DNSSEC-signed
zone which uses too many NSEC3 iterations, it should cease the attempt
to validate due to an NSEC3 iteration limit being exceeded and fall back
to insecure.
2026-03-13 13:03:33 +01:00
Nicki Křížek
495be0bb9e Disable statschannel RTT tests on FreeBSD
These tests rely on somewhat precise timing, as they test that answers
arrive in a particular latency bucket within the statschannel stats.
These tests are affected by various timing and network issues on our
FreeBSD CI runners and the results are very unstable. Skip these on
FreeBSD entirely.
2026-03-10 15:36:10 +01:00
Michal Nowak
77a7430a5f
Bump xfer timeout to 30 seconds
Enabling ans6 responses and xfr-and-reconfig zone reload sometimes takes
more time on FreeBSD than the default timeout allows; bump it to 30
seconds.
2026-03-10 12:39:14 +01:00
Nicki Křížek
a22e03f71b Log dnspython queries after .to_wire() is called
Some dns message modifications like TSIG happen only after .to_wire() is
called on the message. To ensure there isn't a discrepancy between what
has been logged and what has been sent, log the query after
dns.query.udp() is executed (which calls .to_wire() on the message).

Co-Authored-By: Štěpán Balážik <stepan@isc.org>
2026-03-09 09:54:12 +01:00
Ondřej Surý
c1ba80169c
Introduce max-delegation-servers configuration option
Make the maximum number of processed delegation nameservers configurable
via the new 'max-delegation-servers' option (default: 13), replacing the
hardcoded NS_PROCESSING_LIMIT (20).

The default is reduced to 13 to precisely match the maximum number of
root servers that can fit into a classic 512-byte UDP payload.  This
provides a natural, historically sound cap that mitigates resource
exhaustion and amplification attacks from artificially inflated or
misconfigured delegations.

The configuration option is strictly bounded between 1 and 100 to ensure
resolver stability.
2026-03-04 16:13:49 +01:00
Colin Vidal
d8f46b09a7 add checkconf test with key defined inside a view
A configuration where a key was defined inside a view, then used in a
`primary` statement wasn't covered. This is now fixed.
2026-02-28 17:11:02 -08:00
Aram Sargsyan
165a776137 Add RTT statistics tests both for XML and JSON outputs
Add a resolver instance "ns4" in the statschannel test and a "ans5"
instance which adds latency to the queries delegeated to it from the
resolver.

Make queries which add latency, and compare the expected values to
the values received from the statistics channel.
2026-02-26 14:00:10 +00:00
Colin Vidal
5274e764c4
Add test coverage for nameserver processing limits
Introduce a new system test (nsprocessinglimit) to verify that the
resolver strictly respects outgoing network fetch quotas when presented
with heavily delegated, unresponsive zones.

This test acts as a regression check for the recent Fisher-Yates nameserver
selection refactor.  It sets up an authoritative server delegating a zone
to 23 distinct nameservers (all pointing to unresponsive loopback IPs).

Using dnstap, the test forces a resolution failure and verifies that:
1. The resolver successfully traverses the zone delegation path.
2. The resolver caps the outgoing network queries to the delegated
   nameservers exactly at the processing limit (20 fetches), ensuring
   array boundaries and dynamic fetch quotas are strictly enforced without
   crashing or hanging.
2026-02-26 06:57:54 +01:00
Colin Vidal
c67b52684f system test covering NS randomization
Add randomizens system test which ensures that NS are randomly selected.
The test relies of the fact that `getaddresses_allowed()` logic won't
allow to query more than 3 NS at the top-level. The `example.` zone has
4 NS and the 3 formers are lame. As a result, if the resolved doesn't
randomize the NS selection, it will only quiery the 3 formers, which
won't give an answer, and fails. With randomization enabled, there is a
chance that the resolver queries the fourth NS, and gets the result.
2026-02-25 09:31:14 +01:00
Ondřej Surý
a82773ea89 Add system tests that imports invalid SKR file
Try to import invalid SKR file and observe whether the named is still
alive.  This test only triggers under ASAN.
2026-02-24 19:44:57 +01:00
Ondřej Surý
7b737bc1c4
Add tests for NSEC3 invalid length
Adds a static system test that fails to load an NSEC3 record with an
invalid next part length.  Additionally, introduces a dynamic test using
a crafted authoritative DNS proxy to inject invalid NSEC3 records on the
fly to test runtime behavior.
2026-02-24 14:57:58 +01:00
Mark Andrews
3801d0ebbf
Enforce NSEC3 record consistency
NSEC3 hashes are required to fit within a single DNS label.  Since there
are 5 bits per label byte without pad characters, the maximum hash size
is floor(63*5/8) (39 bytes).

This patch enforces this maximum length for unknown algorithms, while
strictly enforcing the exact expected digest length for known algorithms
like SHA-1.
2026-02-24 14:57:22 +01:00
Ondřej Surý
46f15f4f9d
Add test for mixed unsupported DS records
Add a system test that has one invalid DS record with supported
algorithm and one unsupported DS record.  Both DNSKEY and A queries must
fail with SERVFAIL.
2026-02-23 19:53:48 +01:00
Ondřej Surý
f983a64152
Fail DNSKEY validation when supported but invalid DS is found
A regression was introduced when adding the EDE code for unsupported
DNSKEY and DS algorithms.  When the parent has both supported and
unsupported algorithm in the DS record, the validator would treat the
supported DS algorithm as insecure when validating DNSKEY records
instead of BOGUS.  This has not security impact as the rest of the child
zone correctly ends with BOGUS status, but it is incorrect and thus the
regression has been fixed.
2026-02-23 11:34:43 +01:00
Matthijs Mekking
c32de7df95 Test serve-stale with upstream zones and CNAMEs
Three variants of YWH-PGM40640-56: Stale/Wrong DNS Data Served via
CNAME Flag Leak (DNS_DBFIND_STALEOK persistence) are presented in
GitLab issue #5751. All these variants have been converted to system
tests.

Variant 1 forwards source.stale to another server, that provides a
CNAME record, while the resolver is authoritative for target.stale.
The CNAME points to a non-existing name. A stale CNAME record should
result in a stale NXDOMAIN (instead of SERVFAIL).

Variant 2 forwards both source.stale and target.stale to other servers.
This time the CNAME points to an A RRset. If the source.stale server
is not available (and stale-answer-client-timeout is off), the cached
CNAME should be followed and pick up the fresh RRset (instead of the
stale A RRset).

Variant 3 is similar to variant 2, but this time the CNAME points to
a non-existing name again. After flushing the target, BIND should
return a stale NXDOMAIN (instead of SERVFAIL).
2026-02-23 08:07:12 +01:00