Commit Graph
9268 Commits
Author SHA1 Message Date
Matthijs Mekking 3dff3eac0a Fix tsan errors
When working internally on the zone, we can access the zone's
variables directly.
2024-01-25 14:48:07 +01:00
Matthijs Mekking 18b566ccea Refactor findzonekeys
Move dns_dnssec_findzonekeys from the dnssec.{c,h} source code to
zone.{c,h} (the header file already commented that this should be done
inside dns_zone_t).

Alter the function in such a way, that keys are searched for in the
key stores if a 'dnssec-policy' (kasp) is attached to the zone,
otherwise keep using the zone's key-directory.
2024-01-25 14:48:07 +01:00
Matthijs Mekking 80387532cd Use dst_key's directory when writing key files
When writing key files to disk, use the internally stored directory.

Add an access function 'dst_key_directory()'.

Most calls to keymgr functions no longer need to provide the
key-directory value. Only 'dns_keymgr_run' still needs access to
the zone's key-directory in case the key-store is set to the built-in
key-directory.
2024-01-25 14:47:43 +01:00
Matthijs Mekking 0701a140d3 Add directory to dst_key structure
Store key directory when reading the key from file. This is the
directory it was read from and can be used when saving the key back
to disk.
2024-01-25 14:41:25 +01:00
Matthijs Mekking 9081426313 Refactor findmatchingkeys and keylistfromrdataset
Refactor dns_dnssec_findmatchingkeys and dns_dnssec_keylistfromrdataset
to take into account the key store directories in case the zone is using
dnssec-policy (kasp). Add 'kasp' and 'keystores' parameters.

This requires the keystorelist to be stored inside the zone structure.

The calls to these functions in the DNSSEC tools can use NULL as the
kasp value, as dnssec-signzone does not (yet) support dnssec-policy,
and key collision is checked inside the directory where it is created.
2024-01-25 14:41:25 +01:00
Matthijs Mekking f096472eb4 Create private keys with PKCS#11 object
If there is a keystore configured with a PKCS#11 URI, zones that
are using a dnssec-policy that uses such a keystore should create keys
via the PKCS#11 interface. Those keys are generally stored inside an
HSM.

Some changes to the code are required, to store the engine reference
into the keystore.
2024-01-25 14:41:25 +01:00
Matthijs Mekking d795710541 Add object parameter to dst_key_generate()
Add a parameter to store a possible PKCS#11 object that can later be used to
identify a key with a PKCS#11 URI string (RFC 7512).
2024-01-25 14:41:25 +01:00
Matthijs Mekking ffc41d1b14 Store key store reference instead of name
When creating the kasp structure, instead of storing the name of the
key store on keys, store a reference to the key store object instead.

This requires to build the keystore list prior to creating the kasp
structures, in the dnssec tools, the check code and the server code.

We will create a builtin keystore called "key-directory" which means
use the zone's key-directory as the key store.

The check code changes, because now the keystore is looked up before
creating the kasp structure (and if the keystore is not found, this
is an error). Instead of looking up the keystore after all
'dnssec-policy' clauses have been read.
2024-01-25 14:41:25 +01:00
Matthijs Mekking 594d4a81f1 Check if key-store exists
Add checkconf check to ensure that the used key-store in the keys
section exists. Error if that is not the case. We also don't allow
the special keyword 'key-directory' as that is internally used to
signal that the zone's key-directory should be used.
2024-01-25 14:38:12 +01:00
Matthijs Mekking f837bb2af8 Parse key-store config
Add the code that actually stores the key-store configuration into
structures, also store the reference into the kasp key.
2024-01-25 14:38:11 +01:00
Matthijs Mekking 3a86c07422 Add code for creating keystore from config
Add code for configuring keystore objects. Add this to the "kaspconf"
code, as it is related to 'dnssec-policy' and it is too small to create
a separate file for it.
2024-01-25 14:38:11 +01:00
Matthijs Mekking 0284482687 Add code to store key-stores
New files to define a structure and functions for dealing with
key-stores.
2024-01-25 14:38:11 +01:00
Mark Andrews 1b6f70076a Extend dns_message_setopt to clear the opt record
Use NULL to signal that the opt record, if any, set on the
message be removed.
2024-01-23 10:47:31 +11:00
Mark Andrews 8f0f6d05e9 Add minimal EDNS UL option support
This is defined in draft-ietf-dnssd-update-lease.  This adds the
ability to display the option and teaches dig about the name 'UL'.
2024-01-23 10:47:31 +11:00
Artem Boldariev eb924e460b Integrate TLS cipher suites support into BIND
This commit makes BIND use the new 'cipher-suites' option from the
'tls' statement.
2024-01-12 13:27:59 +02:00
Matthijs MekkingandMark Andrews b770740b44 Write new DNSKEY TTL to key file
When the current DNSKEY TTL does not match the one from the policy,
write the new TTL to disk.
2024-01-03 12:09:11 +11:00
Mark Andrews 27e74b2e4b Only create private records for DNSKEYs that have changed
We don't need to create private records for DNSKEY records that
have only had their TTL's changed.
2024-01-03 12:09:11 +11:00
Mark Andrews d601a90ea3 sync_secure_db failed to handle some TTL changes
If the DNSKEY, CDNSKEY or CDS RRset had different TTLs then the
filtering of these RRset resulted in dns_diff_apply failing with
"not exact". Identify tuple pairs that are just TTL changes and
allow them through the filter.
2024-01-03 12:09:11 +11:00
Mark Andrews 21be35c54e Use the current CDS and CDNSKEY TTLs
When adding new CDS and CDNSKEY records use the existing RRset
TTL if they already exist.
2024-01-03 12:09:11 +11:00
Mark Andrews dcb7799061 Update the DNSKEY, CDNSKEY and CDS TTLs to match dnskey-ttl
If the TTLs of the DNSKEY, CDNSKEY and CDS do not match the
dnskey-ttl update them by removing all records and re-adding
them with the correct TTL.
2024-01-03 12:09:11 +11:00
Michał Kępień 9cf1f39b54 Silence a scan-build warning in dns_rbt_addname()
Clang Static Analyzer is unable to grasp that when dns_rbt_addnode()
returns ISC_R_EXISTS, it always sets the pointer passed to it via its
'nodep' parameter to a non-NULL value.  Add an extra safety check in the
conditional expression used in dns_rbt_addname() to silence that
warning.
2023-12-22 19:27:37 +01:00
Evan Hunt ea9a8cb392 prevent an infinite loop in fix_iterator()
it was possible for fix_iterator() to get stuck in a loop while
trying to find the predecessor of a missing node. this has been
fixed and a regression test has been added.
2023-12-21 09:18:30 -08:00
Evan Hunt 84f79cd164 fix_iterator() could produce incoherent iterator stacks
the fix_iterator() function moves an iterator so that it points
to the predecessor of the searched-for name when that name doesn't
exist in the database. the tests only checked the correctness of
the top of the stack, however, and missed some cases where interior
branches in the stack could be missing or duplicated. in these
cases, the iterator would produce inconsistent results when walked.

the predecessors test case in qp_test has been updated to walk
each iterator to the end and ensure that the expected number of
nodes are found.
2023-12-21 09:18:30 -08:00
Mark Andrews 0509351e92 Update the NSEC3PARAM TTL to match the SOA minimum
When building NSEC3 chains update the NSEC3PARAM TTL to match
the SOA minimum.  Delete all records using the old TTL then
re-add them using the new TTL.
2023-12-21 20:12:09 +11:00
Mark Andrews f3ae88d84e Don't delete the NSEC3PARAM immediately
Wait until the new NSEC or NSEC3 chain is generated then it should
be deleted.
2023-12-21 20:12:09 +11:00
Mark Andrews a3d0476d17 Don't look for KSK status here and squash memory leak
Just remove the key from  consideration as it is being removed.

The old code could leak a key reference as dst_free_key was not
called every time we continued. This simplification will address
this as well.
2023-12-21 09:18:45 +11:00
Mark Andrews 6ccb93884d dns_request_cancel needs to be callable from any thread
Check the tid and cancel the request immediately or pass it to the
appropriate loop for processing.  Call request->cb directly from
req_sendevent as it is now always called with the correct tid.
2023-12-21 08:11:59 +11:00
Michał Kępień efcba4dd23 Do not destroy IXFR journal in xfrin_end()
The xfrin_end() function is run when a zone transfer is finished or
canceled.  One of the actions it takes for incremental transfers (IXFR)
is calling dns_journal_destroy() on the zone journal structure that is
stored in the relevant zone transfer context (xfr->ixfr.journal).  That
immediately invalidates that structure as it is not reference-counted.
However, since the changes present in the IXFR stream are applied to the
journal asynchronously (via isc_work_enqueue()), it is possible that
some zone changes may still be in the process of being written to the
journal by the time xfrin_end() destroys the relevant structure.  Such a
scenario leads to crashes.

Fix by not destroying the zone journal structure until the entire zone
transfer context is destroyed.  xfrin_destroy() already conditionally
calls dns_journal_destroy() and when the former is called, all
asynchronous work for a given zone transfer process is guaranteed to be
complete.
2023-12-20 17:21:14 +01:00
Matthijs Mekking 16f2c811e3 Revert "Remove kasp mutex lock"
This reverts commit 634c80ea12.
2023-12-20 08:30:44 +00:00
Mark Andrews c896e07277 Log what change generated a 'not exact' error 2023-12-20 01:56:38 +11:00
Matthijs Mekking 634c80ea12 Remove kasp mutex lock
Multiple zones should be able to read the same key and signing policy
at the same time. Since writing the kasp lock only happens during
reconfiguration, and the complete kasp list is being replaced, there
is actually no need for a lock. Reference counting ensures that a kasp
structure is not destroyed when still being attached to one or more
zones.

This significantly improves the load configuration time.
2023-12-19 14:53:51 +01:00
Mark Andrews 6066e41948 Use 'now' rather than 'inception' in 'add_sigs'
When kasp support was added 'inception' was used as a proxy for
'now' and resulted in signatures not being generated or the wrong
signatures being generated.  'inception' is the time to be set
in the signatures being generated and is usually in the past to
allow for clock skew.  'now' determines what keys are to be used
for signing.
2023-12-19 11:21:46 +11:00
Michał Kępień 2a3b6d1406 Fix reference counting in do_nsfetch()
Each function queuing a do_nsfetch() call using isc_async_run() is
expected to increase the given zone's internal reference count
(zone->irefs), which is then correspondingly decreased in either
do_nsfetch() itself (when the dns_resolver_createfetch() fails) or in
nsfetch_done() (when recursion is finished).

However, do_nsfetch() can also return early if either the zone itself or
the relevant view's resolver object is being shut down.  In that case,
do_nsfetch() simply returns without decreasing the internal reference
count for the zone.  This leaves a dangling zone reference around, which
leads to hangs during named shutdown.

Fix by executing the same cleanup code for early returns from
do_nsfetch() as for a failed dns_resolver_createfetch() call in that
function as the reference count will not be decreased in nsfetch_done()
in any of these cases.
2023-12-18 11:33:43 +01:00
Aram Sargsyan 791a046cc7 Use atomic store operations instead of atomic initialize
The atomic_init() function makes sense to use with structure's
members when creating a new instance of a strucutre. In other
places, use atomic store operations instead, in order to avoid
data races.
2023-12-15 09:56:44 +00:00
Matthijs MekkingandEvan Hunt 21867f200a Refactor getpred code
Move the code to find the predecessor into one function, as it is shares
quite some similarities: In both cases we first need to find the
immediate predecessor/successor, then we need to find the immediate
predecessor if the iterator is not already pointing at it.
2023-12-11 21:01:29 +00:00
Matthijs MekkingandEvan Hunt ab8a0c4b5a and fix yet another dns_qp_lookup() iterator bug
This one is similar to the bug when searching for a key, reaching a
dead-end branch that doesn't match, because the branch offset point
is after the point where the search key differs.

This fixes the case where we are multiple levels deep. In other
words, we had a more-than-one matches *after* the point where the
search key differs.

For example, consider the following qp-trie:

branch: "[e]", "[m]":
 - leaf: "a.b.c.d.e"
 - branch: "moo[g]", "moo[k]", "moo[n]":
   - leaf: "moog"
   - branch: "mook[e]", "mook[o]"
     - leaf: "mooker"
     - leaf: "mooko"
   - leaf: "moon"

If searching for a key "monky", we would reach the branch with
twigs "moo[k]" and "moo[n]". The key matches on the 'k' on offset=4,
and reaches the branch with twigs "mook[e]" and "mook[o]". This time
we cannot find a twig that matches our key at offset=5, there is no
twig for 'y'. The closest name we found was "mooker".

Note that on a branch it can't detect it is on a dead branch because the
key is not encapsulated in a branch node.

In the previous code we considered "mooker" to be the successor of
"monky" and so we needed to the predecessor of "mooker" to find the
predecessor for "monky". However, since the search key alread differed
before entering this branch, this is not enough. We would be left with
"moog" as the predecessor of "monky", while in this example "a.b.c.d.e"
is the actual predecessor.

Instead, we need to go up a level, find the predecessor and check
again if we are on the right branch, and repeat the process until we
are.

Unit tests to cover the scenario are now added.
2023-12-11 21:01:29 +00:00
Matthijs MekkingandEvan Hunt 276bdcf5cf and fix another dns_qp_lookup() iterator bug
There was yet another edge case in which an iterator could be
positioned at the wrong node after dns_qp_lookup(). When searching for
a key, it's possible to reach a leaf that matches at the given offset,
but because the offset point is *after* the point where the search key
differs from the leaf's contents, we are now at the wrong leaf.

In other words, the bug fixed the previous commit for dead-end branches
must also be applied on matched leaves.

For example, if searching for the key "monpop", we could reach a branch
containing "moop" and "moor". the branch offset point - i.e., the point
after which the branch's leaves differ from each other - is the
fourth character ("p" or "r"). The search key matches the fourth
character "p", and takes that twig to the next node (which can be
a branch for names starting with "moop", or could be a leaf node for
"moop").

The old code failed to detect this condition, and would have
incorrectly left the iterator pointing at some successor, and not
at the predecessor of the "moop".

To find the right predecessor in this case, we need to get to the
previous branch and get the previous from there.

This has been fixed and the unit test now includes several new
scenarios for testing search names that match and unmatch on the
offset but have a different character before the offset.
2023-12-11 21:01:29 +00:00
Mark Andrews 7e462c2b26 Also cleanup the space for the rbt nodes
As we are in overmem state we want to free more memory than we are
adding so we need to add in an allowance for the rbtnodes that may
have been added and the names stored with them.  There is the node
for the owner name and a possible ENT node if there was a node split.
2023-12-07 02:59:04 +00:00
Mark Andrews 5e8f0e9ceb Process the combined LRU lists in LRU order
Only cleanup headers that are less than equal to the rbt's last_used
time.  Adjust the rbt's last_used time when the target cleaning was
not achieved to the oldest value of the remaining set of headers.

When updating delegating NS and glue records last_used was not being
updated when it should have been.

When adding zero TTL records to the tail of the LRU lists set
last_used to rbtdb->last_used + 1 rather than now.  This appoximately
preserves the lists LRU order.
2023-12-07 02:59:04 +00:00
Evan Hunt 7d05590a6f clean up client.c
- make dns_client_startresolve() static since it's only used internally
- remove outdated comments
2023-12-06 17:31:38 -08:00
Evan Hunt 50dd6aad34 remove unused functions in dns_master
dns_master_dumpnode() and dns_master_dumpnodetostream() were
never used and can be removed.
2023-12-06 17:31:38 -08:00
Evan Hunt 66496d550b remove resolver-retry-interval and resolver-nonbackoff-tries
fully remove these options and mark them as ancient.
2023-12-06 11:54:59 -08:00
Evan Hunt 60a33ae6bb fix another dns_qp_lookup() iterator bug
there was another edge case in which an iterator could be positioned at
the wrong node after dns_qp_lookup().  when searching for a key, it's
possible to reach a dead-end branch that doesn't match, because the
branch offset point is *after* the point where the search key differs
from the branch's contents.

for example, if searching for the key "mop", we could reach a branch
containing "moon" and "moor". the branch offset point - i.e., the
point after which the branch's leaves differ from each other - is the
fourth character ("n" or "r"). however, both leaves differ from the
search key at position *three* ("o" or "p"). the old code failed to
detect this condition, and would have incorrectly left the iterator
pointing at some lower value and not at "moor".

this has been fixed and the unit test now includes this scenario.
2023-12-06 11:03:30 -08:00
Evan Hunt 8612902476 fix dns_qp_lookup() iterator bug
in some cases it was possible for the iterator to be positioned in the
wrong place by dns_qp_lookup(). previously, when a leaf node was found
which matched the search key at its parent branch's offset point, but
did not match after that point, the code incorrectly assumed the leaf
it had found was a successor to the searched-for name, and stepped the
iterator back to find a predecessor.  however, it was possible for the
non-matching leaf to be the predecessor, in which case stepping the
iterator back was wrong.

(for example: a branch contains "aba" and "abcd", and we are searching
for "abcde". we step down to the twig matching the letter "c" in
position 3. "abcd" is the predecessor of "abcde", so the iterator is
already correctly positioned, but because the twig was an exact match,
we would have moved it back one step to "aba".)

this previously went unnoticed due to a mistake in the qp_test unit
test, which had the wrong expected result for the test case that should
have detected the error. both the code and the test have been fixed.
2023-12-06 11:03:30 -08:00
Evan Hunt 947bc0a432 add an iterator argument to dns_qp_lookup()
the 'predecessor' argument to dns_qp_lookup() turns out not to
be sufficient for our needs: the predecessor node in a QP database
could have become "empty" (for the current version) because of an
update or because cache data expired, and in that case the caller
would have to iterate more than one step back to find the predecessor
node that it needs.

it may also be necessary for a caller to iterate forward, in
order to determine whether a node has any children.

for both of these reasons, we now replace the 'predecessor'
argument with an 'iter' argument. if set, this points to memory
with enough space for a dns_qpiter object.

when an exact match is found by the lookup, the iterator will be
pointing to the matching node. if not, it will be pointing to the
lexical predecessor of the nae that was searched for.

a dns_qpiter_current() method has been added for examining
the current value of the iterator without moving it in either
direction.
2023-12-06 11:03:30 -08:00
Artem Boldariev b109fa9192 Fix TLS certs store deletion on concurrent access
During initialisation or reconfiguration, it is possible that multiple
threads are trying to create a TLS context and associated data (like
TLS certs store) concurrently. In some cases, a thread might be too
late to add newly created data to the TLS contexts cache, in which
case it needs to be discarded. In the code that handles that case, it
was not taken into account that, in some cases, the TLS certs store
could not have been created or should not be deleted, as it is being
managed by the TLS contexts cache already. Deleting the store in such
cases might lead to crashes.

This commit fixes the issue.
2023-12-06 16:01:20 +02:00
Artem Boldariev 5ed3a76f9d BIND: Add 'allow-proxy' and 'allow-proxy-on' options
The main intention of PROXY protocol is to pass endpoints information
to a back-end server (in our case - BIND). That means that it is a
valid way to spoof endpoints information, as the addresses and ports
extracted from PROXYv2 headers, from the point of view of BIND, are
used instead of the real connection addresses.

Of course, an ability to easily spoof endpoints information can be
considered a security issue when used uncontrollably. To resolve that,
we introduce 'allow-proxy' and 'allow-proxy-on' ACL options. These are
the only ACL options in BIND that work with real PROXY connections
addresses, allowing a DNS server operator to specify from what clients
and on which interfaces he or she is willing to accept PROXY
headers. By default, for security reasons we do not allow to accept
them.
2023-12-06 15:15:25 +02:00
Artem Boldariev eb52015db1 Stream DNS: add PROXY over TLS support
This commit extends Stream DNS with PROXY over TLS support.
2023-12-06 15:15:25 +02:00
Artem Boldariev e97903ca14 Add PROXY support to Stream DNS
This commit makes it possible to use Stream DNS on top of PROXY Stream
either directly or indirectly (in the case when TLS is involved).
2023-12-06 15:15:24 +02:00
Matthijs Mekking ff4201e388 Lower the maximum allowed NSEC3 iterations to 50
BIND 9 will now treat the response as insecure when processing NSEC3
records with iterations larger than 50.

Earlier, we limited the number of iterations to 150 (in #2445).

RFC 9276 says: Because there has been a large growth of open (public)
DNSSEC validating resolvers that are subject to compute resource
constraints when handling requests from anonymous clients, this
document recommends that validating resolvers reduce their iteration
count limits over time. Specifically, validating resolver operators and
validating resolver software implementers are encouraged to continue
evaluating NSEC3 iteration count deployment trends and lower their
acceptable iteration limits over time.

After evaluation, we decided that the next major BIND release should
lower the maximum allowed NSEC3 iterations to 50, which should be
fine for 99,87% of the domain names.
2023-12-05 14:58:58 +00:00