mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-08 23:32:05 -04:00
2605. [bug] Accept DS responses from delegation only zones.
[RT # 19296]
This commit is contained in:
parent
afb33f777a
commit
5422cf284f
3 changed files with 184 additions and 42 deletions
3
CHANGES
3
CHANGES
|
|
@ -1,3 +1,6 @@
|
|||
2605. [bug] Accept DS responses from delegation only zones.
|
||||
[RT # 19296]
|
||||
|
||||
2604. [func] Add support for DNS rebinding attack prevention through
|
||||
new options, deny-answer-addresses and
|
||||
deny-answer-aliases. Based on contributed code from
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
- PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
|
||||
<!-- File: $Id: Bv9ARM-book.xml,v 1.410 2009/05/29 22:22:36 jinmei Exp $ -->
|
||||
<!-- File: $Id: Bv9ARM-book.xml,v 1.411 2009/06/02 05:51:44 marka Exp $ -->
|
||||
<book xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<title>BIND 9 Administrator Reference Manual</title>
|
||||
|
||||
|
|
@ -4420,16 +4420,16 @@ category notify { null; };
|
|||
<entry colname="1">
|
||||
<para><command>delegation-only</command></para>
|
||||
</entry>
|
||||
<entry colname="2">
|
||||
<para>
|
||||
Delegation only. Logs queries that have
|
||||
been forced to NXDOMAIN as the result of a
|
||||
delegation-only zone or
|
||||
a <command>delegation-only</command> in a
|
||||
hint or stub zone declaration.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
<entry colname="2">
|
||||
<para>
|
||||
Delegation only. Logs queries that have been
|
||||
forced to NXDOMAIN as the result of a
|
||||
delegation-only zone or a
|
||||
<command>delegation-only</command> in a hint
|
||||
or stub zone declaration.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row rowsep="0">
|
||||
<entry colname="1">
|
||||
<para><command>edns-disabled</command></para>
|
||||
|
|
@ -5328,17 +5328,45 @@ badresp:1,adberr:0,findfail:0,valfail:0]
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<varlistentry id="root_delegation_only">
|
||||
<term><command>root-delegation-only</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Turn on enforcement of delegation-only in TLDs (top level domains) and root zones
|
||||
with an optional
|
||||
exclude list.
|
||||
Turn on enforcement of delegation-only in TLDs
|
||||
(top level domains) and root zones with an optional
|
||||
exclude list.
|
||||
</para>
|
||||
<para>
|
||||
DS queries are expected to be made to and be answered by
|
||||
delegation only zones. Such queries and responses are
|
||||
treated as a exception to delegation-only processing
|
||||
and are not converted to NXDOMAIN responses provided
|
||||
a CNAME is not discovered at the query name.
|
||||
</para>
|
||||
<para>
|
||||
If a delegation only zone server also serves a child
|
||||
zone it is not always possible to determine whether
|
||||
a answer comes from the delegation only zone or the
|
||||
child zone. SOA NS and DNSKEY records are apex
|
||||
only records and a matching response that contains
|
||||
these records or DS is treated as coming from a
|
||||
child zone. RRSIG records are also examined to see
|
||||
if they are signed by a child zone or not. The
|
||||
authority section is also examined to see if there
|
||||
is evidence that the answer is from the child zone.
|
||||
Answers that are determined to be from a child zone
|
||||
are not converted to NXDOMAIN responses. Despite
|
||||
all these checks there is still a possibility of
|
||||
false negatives when a child zone is being served.
|
||||
</para>
|
||||
<para>
|
||||
Similarly false positives can arise from empty nodes
|
||||
(no records at the name) in the delegation only zone
|
||||
when the query type is not ANY.
|
||||
</para>
|
||||
<para>
|
||||
Note some TLDs are not delegation only (e.g. "DE", "LV", "US"
|
||||
and "MUSEUM").
|
||||
Note some TLDs are not delegation only (e.g. "DE", "LV",
|
||||
"US" and "MUSEUM"). This list is not exhaustive.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
|
|
@ -9411,20 +9439,22 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
|
|||
</entry>
|
||||
<entry colname="2">
|
||||
<para>
|
||||
This is used to enforce the delegation-only
|
||||
status of infrastructure zones (e.g. COM, NET, ORG).
|
||||
Any answer that
|
||||
is received without an explicit or implicit delegation
|
||||
in the authority
|
||||
section will be treated as NXDOMAIN. This does not
|
||||
apply to the zone
|
||||
apex. This should not be applied to leaf zones.
|
||||
This is used to enforce the delegation-only
|
||||
status of infrastructure zones (e.g. COM,
|
||||
NET, ORG). Any answer that is received
|
||||
without an explicit or implicit delegation
|
||||
in the authority section will be treated
|
||||
as NXDOMAIN. This does not apply to the
|
||||
zone apex. This should not be applied to
|
||||
leaf zones.
|
||||
</para>
|
||||
<para>
|
||||
<varname>delegation-only</varname> has no
|
||||
effect on answers received
|
||||
from forwarders.
|
||||
effect on answers received from forwarders.
|
||||
</para>
|
||||
<para>
|
||||
See caveats in <xref linkend="root_delegation_only"/>.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
|
|
@ -9683,9 +9713,11 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
|
|||
<para>
|
||||
The flag only applies to hint and stub zones. If set
|
||||
to <userinput>yes</userinput>, then the zone will also be
|
||||
treated as if it
|
||||
is also a delegation-only type zone.
|
||||
treated as if it is also a delegation-only type zone.
|
||||
</para>
|
||||
<para>
|
||||
See caveats in <xref linkend="root_delegation_only"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: resolver.c,v 1.400 2009/05/29 23:47:49 tbox Exp $ */
|
||||
/* $Id: resolver.c,v 1.401 2009/06/02 05:51:44 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -471,6 +471,30 @@ valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
|
|||
return (result);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
rrsig_fromchildzone(fetchctx_t *fctx, dns_rdataset_t *rdataset) {
|
||||
dns_namereln_t namereln;
|
||||
dns_rdata_rrsig_t rrsig;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
int order;
|
||||
isc_result_t result;
|
||||
unsigned int labels;
|
||||
|
||||
for (result = dns_rdataset_first(rdataset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(rdataset)) {
|
||||
dns_rdataset_current(rdataset, &rdata);
|
||||
result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
namereln = dns_name_fullcompare(&rrsig.signer, &fctx->domain,
|
||||
&order, &labels);
|
||||
if (namereln == dns_namereln_subdomain)
|
||||
return (ISC_TRUE);
|
||||
dns_rdata_reset(&rdata);
|
||||
}
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {
|
||||
dns_name_t *name;
|
||||
|
|
@ -484,13 +508,43 @@ fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {
|
|||
return (ISC_FALSE);
|
||||
|
||||
/*
|
||||
* Look for BIND 8 style delegations.
|
||||
* Also look for answers to ANY queries where the duplicate NS RRset
|
||||
* may have been stripped from the authority section.
|
||||
* A DS RRset can appear anywhere in a zone, even for a delegation-only
|
||||
* zone. So a response to an explicit query for this type should be
|
||||
* excluded from delegation-only fixup.
|
||||
*
|
||||
* SOA, NS, and DNSKEY can only exist at a zone apex, so a postive
|
||||
* response to a query for these types can never violate the
|
||||
* delegation-only assumption: if the query name is below a
|
||||
* zone cut, the response should normally be a referral, which should
|
||||
* be accepted; if the query name is below a zone cut but the server
|
||||
* happens to have authority for the zone of the query name, the
|
||||
* response is a (non-referral) answer. But this does not violate
|
||||
* delegation-only because the query name must be in a different zone
|
||||
* due to the "apex-only" nature of these types. Note that if the
|
||||
* remote server happens to have authority for a child zone of a
|
||||
* delegation-only zone, we may still incorrectly "fix" the response
|
||||
* with NXDOMAIN for queries for other types. Unfortunately it's
|
||||
* generally impossible to differentiate this case from violation of
|
||||
* the delegation-only assumption. Once the resolver learns the
|
||||
* correct zone cut, possibly via a separate query for an "apex-only"
|
||||
* type, queries for other types will be resolved correctly.
|
||||
*
|
||||
* A query for type ANY will be accepted if it hits an exceptional
|
||||
* type above in the answer section as it should be from a child
|
||||
* zone.
|
||||
*
|
||||
* Also accept answers with RRSIG records from the child zone.
|
||||
* Direct queries for RRSIG records should not be answered from
|
||||
* the parent zone.
|
||||
*/
|
||||
|
||||
if (message->counts[DNS_SECTION_ANSWER] != 0 &&
|
||||
(fctx->type == dns_rdatatype_ns ||
|
||||
fctx->type == dns_rdatatype_any)) {
|
||||
fctx->type == dns_rdatatype_ds ||
|
||||
fctx->type == dns_rdatatype_soa ||
|
||||
fctx->type == dns_rdatatype_any ||
|
||||
fctx->type == dns_rdatatype_rrsig ||
|
||||
fctx->type == dns_rdatatype_dnskey)) {
|
||||
result = dns_message_firstname(message, DNS_SECTION_ANSWER);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
name = NULL;
|
||||
|
|
@ -499,10 +553,32 @@ fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {
|
|||
for (rdataset = ISC_LIST_HEAD(name->list);
|
||||
rdataset != NULL;
|
||||
rdataset = ISC_LIST_NEXT(rdataset, link)) {
|
||||
type = rdataset->type;
|
||||
if (type != dns_rdatatype_ns)
|
||||
if (!dns_name_equal(name, &fctx->name))
|
||||
continue;
|
||||
if (dns_name_issubdomain(name, domain))
|
||||
type = rdataset->type;
|
||||
/*
|
||||
* RRsig from child?
|
||||
*/
|
||||
if (type == dns_rdatatype_rrsig &&
|
||||
rrsig_fromchildzone(fctx, rdataset))
|
||||
return (ISC_FALSE);
|
||||
/*
|
||||
* Direct query for apex records or DS.
|
||||
*/
|
||||
if (fctx->type == type &&
|
||||
(type == dns_rdatatype_ds ||
|
||||
type == dns_rdatatype_ns ||
|
||||
type == dns_rdatatype_soa ||
|
||||
type == dns_rdatatype_dnskey))
|
||||
return (ISC_FALSE);
|
||||
/*
|
||||
* Indirect query for apex records or DS.
|
||||
*/
|
||||
if (fctx->type == dns_rdatatype_any &&
|
||||
(type == dns_rdatatype_ns ||
|
||||
type == dns_rdatatype_ds ||
|
||||
type == dns_rdatatype_soa ||
|
||||
type == dns_rdatatype_dnskey))
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
result = dns_message_nextname(message,
|
||||
|
|
@ -510,7 +586,14 @@ fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Look for referral. */
|
||||
/*
|
||||
* A NODATA response to a DS query?
|
||||
*/
|
||||
if (fctx->type == dns_rdatatype_ds &&
|
||||
message->counts[DNS_SECTION_ANSWER] == 0)
|
||||
return (ISC_FALSE);
|
||||
|
||||
/* Look for referral or indication of answer from child zone? */
|
||||
if (message->counts[DNS_SECTION_AUTHORITY] == 0)
|
||||
goto munge;
|
||||
|
||||
|
|
@ -525,13 +608,37 @@ fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {
|
|||
if (type == dns_rdatatype_soa &&
|
||||
dns_name_equal(name, domain))
|
||||
keep_auth = ISC_TRUE;
|
||||
|
||||
if (type != dns_rdatatype_ns &&
|
||||
type != dns_rdatatype_soa)
|
||||
type != dns_rdatatype_soa &&
|
||||
type != dns_rdatatype_rrsig)
|
||||
continue;
|
||||
if (dns_name_equal(name, domain))
|
||||
goto munge;
|
||||
if (dns_name_issubdomain(name, domain))
|
||||
|
||||
if (type == dns_rdatatype_rrsig) {
|
||||
if (rrsig_fromchildzone(fctx, rdataset))
|
||||
return (ISC_FALSE);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* NS or SOA records. */
|
||||
if (dns_name_equal(name, domain)) {
|
||||
/*
|
||||
* If a query for ANY causes a negative
|
||||
* response, we can be sure that this is
|
||||
* an empty node. For other type of queries
|
||||
* we cannot differentiate an empty node
|
||||
* from a node that just doesn't have that
|
||||
* type of record. We only accept the former
|
||||
* case.
|
||||
*/
|
||||
if (message->counts[DNS_SECTION_ANSWER] == 0 &&
|
||||
fctx->type == dns_rdatatype_any)
|
||||
return (ISC_FALSE);
|
||||
} else if (dns_name_issubdomain(name, domain)) {
|
||||
/* Referral or answer from child zone. */
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
}
|
||||
result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue