mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-09 08:12:54 -05:00
- Fix queries for nameservers under a stub leaking to the internet.
git-svn-id: file:///svn/unbound/trunk@4154 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
893159454f
commit
1db056b19c
3 changed files with 103 additions and 11 deletions
|
|
@ -1,6 +1,7 @@
|
|||
12 May 2017: Wouter
|
||||
- Adjust servfail by iterator to not store in cache when serve-expired
|
||||
is enabled, to avoid overwriting useful information there.
|
||||
- Fix queries for nameservers under a stub leaking to the internet.
|
||||
|
||||
9 May 2017: Ralph
|
||||
- Add 'c' to getopt() in testbound.
|
||||
|
|
|
|||
|
|
@ -1576,28 +1576,26 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
|
||||
/** see if last resort is possible - does config allow queries to parent */
|
||||
static int
|
||||
can_have_last_resort(struct module_env* env, struct delegpt* dp,
|
||||
struct iter_qstate* iq)
|
||||
can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen,
|
||||
uint16_t qclass)
|
||||
{
|
||||
struct delegpt* fwddp;
|
||||
struct iter_hints_stub* stub;
|
||||
int labs = dname_count_labels(nm);
|
||||
/* do not process a last resort (the parent side) if a stub
|
||||
* or forward is configured, because we do not want to go 'above'
|
||||
* the configured servers */
|
||||
if(!dname_is_root(dp->name) && (stub = (struct iter_hints_stub*)
|
||||
name_tree_find(&env->hints->tree, dp->name, dp->namelen,
|
||||
dp->namelabs, iq->qchase.qclass)) &&
|
||||
if(!dname_is_root(nm) && (stub = (struct iter_hints_stub*)
|
||||
name_tree_find(&env->hints->tree, nm, nmlen, labs, qclass)) &&
|
||||
/* has_parent side is turned off for stub_first, where we
|
||||
* are allowed to go to the parent */
|
||||
stub->dp->has_parent_side_NS) {
|
||||
verbose(VERB_QUERY, "configured stub servers failed -- returning SERVFAIL");
|
||||
return 0;
|
||||
}
|
||||
if((fwddp = forwards_find(env->fwds, dp->name, iq->qchase.qclass)) &&
|
||||
if((fwddp = forwards_find(env->fwds, nm, qclass)) &&
|
||||
/* has_parent_side is turned off for forward_first, where
|
||||
* we are allowed to go to the parent */
|
||||
fwddp->has_parent_side_NS) {
|
||||
verbose(VERB_QUERY, "configured forward servers failed -- returning SERVFAIL");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
|
@ -1624,9 +1622,11 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
verbose(VERB_ALGO, "No more query targets, attempting last resort");
|
||||
log_assert(iq->dp);
|
||||
|
||||
if(!can_have_last_resort(qstate->env, iq->dp, iq)) {
|
||||
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
|
||||
iq->qchase.qclass)) {
|
||||
/* fail -- no more targets, no more hope of targets, no hope
|
||||
* of a response. */
|
||||
verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL");
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(!iq->dp->has_parent_side_NS && dname_is_root(iq->dp->name)) {
|
||||
|
|
@ -1711,6 +1711,19 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
/* see if we can issue queries to get nameserver addresses */
|
||||
/* this lookup is not randomized, but sequential. */
|
||||
for(ns = iq->dp->nslist; ns; ns = ns->next) {
|
||||
/* if this nameserver is at a delegation point, but that
|
||||
* delegation point is a stub and we cannot go higher, skip*/
|
||||
if( ((ie->supports_ipv6 && !ns->done_pside6) ||
|
||||
(ie->supports_ipv4 && !ns->done_pside4)) &&
|
||||
!can_have_last_resort(qstate->env, ns->name, ns->namelen,
|
||||
iq->qchase.qclass)) {
|
||||
log_nametypeclass(VERB_ALGO, "cannot pside lookup ns "
|
||||
"because it is also a stub/forward,",
|
||||
ns->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
|
||||
if(ie->supports_ipv6) ns->done_pside6 = 1;
|
||||
if(ie->supports_ipv4) ns->done_pside4 = 1;
|
||||
continue;
|
||||
}
|
||||
/* query for parent-side A and AAAA for nameservers */
|
||||
if(ie->supports_ipv6 && !ns->done_pside6) {
|
||||
/* Send the AAAA request. */
|
||||
|
|
|
|||
82
testdata/iter_stub_leak.rpl
vendored
82
testdata/iter_stub_leak.rpl
vendored
|
|
@ -8,6 +8,9 @@ stub-zone:
|
|||
stub-zone:
|
||||
name: "example.com"
|
||||
stub-addr: 10.0.1.1
|
||||
stub-zone:
|
||||
name: "example.net"
|
||||
stub-addr: 10.0.5.1
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test stub zone leaking to the internet on last resort fallback
|
||||
|
|
@ -18,7 +21,7 @@ RANGE_BEGIN 0 100
|
|||
|
||||
; root prime
|
||||
ENTRY_BEGIN
|
||||
MATCH
|
||||
MATCH qname qtype
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
|
|
@ -45,6 +48,7 @@ subzone.example.com. IN A
|
|||
SECTION AUTHORITY
|
||||
subzone.example.com. IN NS sub-ns1.example.com.
|
||||
subzone.example.com. IN NS sub-ns2.example.com.
|
||||
subzone.example.com. IN NS example.net.
|
||||
SECTION ADDITIONAL
|
||||
sub-ns1.example.com. IN A 10.0.2.3
|
||||
sub-ns2.example.com. IN A 10.0.2.4
|
||||
|
|
@ -92,6 +96,44 @@ ENTRY_END
|
|||
|
||||
RANGE_END
|
||||
|
||||
; stub server for example.net
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 10.0.5.1
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode question
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.net. IN NS
|
||||
SECTION ANSWER
|
||||
example.net. IN NS ns.example.net.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.net. IN A 10.0.5.1
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode question
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.net. IN A
|
||||
SECTION ANSWER
|
||||
example.net. IN A 10.0.5.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode question
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.net. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
example.net. 300 SOA master.example.net etc 1 2 3 4 300
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
; stub server for subzone.example.com
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 10.0.2.3
|
||||
|
|
@ -120,16 +162,52 @@ SECTION ANSWER
|
|||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; stub server for subzone.example.com
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 10.0.5.4
|
||||
; match anything, servfail
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR SERVFAIL
|
||||
SECTION QUESTION
|
||||
subzone.example.com. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
||||
; fetch the delegation point for example.net in cache.
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.net. IN NS
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.net. IN NS
|
||||
SECTION ANSWER
|
||||
example.net. IN NS ns.example.net.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.net. IN A 10.0.5.1
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
whatever.subzone.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
; the query should not leak subzone ns queries to the internet
|
||||
STEP 10 CHECK_ANSWER
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
|
|
|
|||
Loading…
Reference in a new issue