- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- File: $Id: Bv9ARM-book.xml,v 1.241.18.108 2009/04/02 15:31:18 jreed Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.241.18.109 2009/06/02 06:04:40 marka Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
</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.
+ 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>
</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>
</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>
<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>
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.284.18.89 2009/05/11 02:36:58 tbox Exp $ */
+/* $Id: resolver.c,v 1.284.18.90 2009/06/02 06:04:40 marka Exp $ */
/*! \file */
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;
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;
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,
}
}
- /* 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;
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);
}