mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
RPZ: implement stubs for rpz-tcp-only actions.
This commit is contained in:
parent
d104727c91
commit
dd70c2ef9a
6 changed files with 111 additions and 18 deletions
|
|
@ -807,7 +807,6 @@ respip_nodata_answer(uint16_t qtype, enum respip_action action,
|
|||
* is explicitly specified. */
|
||||
int rcode = (action == respip_always_nxdomain)?
|
||||
LDNS_RCODE_NXDOMAIN:LDNS_RCODE_NOERROR;
|
||||
|
||||
/* We should empty the answer section except for any preceding
|
||||
* CNAMEs (in that case rrset_id > 0). Type-ANY case is
|
||||
* special as noted in respip_data_answer(). */
|
||||
|
|
|
|||
|
|
@ -1514,6 +1514,15 @@ local_zone_does_not_cover(struct local_zone* z, struct query_info* qinfo,
|
|||
return (lr == NULL);
|
||||
}
|
||||
|
||||
static inline int
|
||||
local_zone_is_udp_query(struct comm_reply* repinfo) {
|
||||
return repinfo != NULL
|
||||
? (repinfo->c != NULL
|
||||
? repinfo->c->type == comm_udp
|
||||
: 0)
|
||||
: 0;
|
||||
}
|
||||
|
||||
int
|
||||
local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns,
|
||||
|
|
@ -1536,7 +1545,9 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
|||
lz_type == local_zone_redirect ||
|
||||
lz_type == local_zone_inform_redirect ||
|
||||
lz_type == local_zone_always_nxdomain ||
|
||||
lz_type == local_zone_always_nodata) {
|
||||
lz_type == local_zone_always_nodata ||
|
||||
(lz_type == local_zone_truncate
|
||||
&& local_zone_is_udp_query(repinfo))) {
|
||||
/* for static, reply nodata or nxdomain
|
||||
* for redirect, reply nodata */
|
||||
/* no additional section processing,
|
||||
|
|
@ -1546,8 +1557,10 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
|||
*/
|
||||
int rcode = (ld || lz_type == local_zone_redirect ||
|
||||
lz_type == local_zone_inform_redirect ||
|
||||
lz_type == local_zone_always_nodata)?
|
||||
lz_type == local_zone_always_nodata ||
|
||||
lz_type == local_zone_truncate)?
|
||||
LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
|
||||
rcode = lz_type == local_zone_truncate ? (rcode|BIT_TC) : rcode;
|
||||
if(z->soa)
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
z->soa, 0, rcode);
|
||||
|
|
@ -1763,6 +1776,7 @@ const char* local_zone_type2str(enum localzone_type t)
|
|||
case local_zone_always_nodata: return "always_nodata";
|
||||
case local_zone_always_deny: return "always_deny";
|
||||
case local_zone_noview: return "noview";
|
||||
case local_zone_truncate: return "truncate";
|
||||
case local_zone_invalid: return "invalid";
|
||||
}
|
||||
return "badtyped";
|
||||
|
|
@ -1800,6 +1814,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
|
|||
*t = local_zone_always_deny;
|
||||
else if(strcmp(type, "noview") == 0)
|
||||
*t = local_zone_noview;
|
||||
else if(strcmp(type, "truncate") == 0)
|
||||
*t = local_zone_truncate;
|
||||
else if(strcmp(type, "nodefault") == 0)
|
||||
*t = local_zone_nodefault;
|
||||
else return 0;
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ enum localzone_type {
|
|||
local_zone_always_deny,
|
||||
/** answer not from the view, but global or no-answer */
|
||||
local_zone_noview,
|
||||
/** truncate the response; client should retry via tcp */
|
||||
local_zone_truncate,
|
||||
/** Invalid type, cannot be used to generate answer */
|
||||
local_zone_invalid
|
||||
};
|
||||
|
|
@ -556,6 +558,8 @@ enum respip_action {
|
|||
respip_always_nodata = local_zone_always_nodata,
|
||||
/** answer with nodata response */
|
||||
respip_always_deny = local_zone_always_deny,
|
||||
/** RPZ: truncate answer in order to force switch to tcp */
|
||||
respip_truncate = local_zone_truncate,
|
||||
|
||||
/* The rest of the values are only possible as
|
||||
* access-control-tag-action */
|
||||
|
|
|
|||
|
|
@ -213,8 +213,8 @@ rpz_action_to_localzone_type(enum rpz_action a)
|
|||
case RPZ_PASSTHRU_ACTION: return local_zone_always_transparent;
|
||||
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
|
||||
case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect;
|
||||
case RPZ_TCP_ONLY_ACTION: return local_zone_truncate;
|
||||
case RPZ_INVALID_ACTION: /* fallthrough */
|
||||
case RPZ_TCP_ONLY_ACTION: /* fallthrough */
|
||||
default: return local_zone_invalid;
|
||||
}
|
||||
}
|
||||
|
|
@ -223,15 +223,15 @@ enum respip_action
|
|||
rpz_action_to_respip_action(enum rpz_action a)
|
||||
{
|
||||
switch(a) {
|
||||
case RPZ_NXDOMAIN_ACTION: return respip_always_nxdomain;
|
||||
case RPZ_NODATA_ACTION: return respip_always_nodata;
|
||||
case RPZ_DROP_ACTION: return respip_always_deny;
|
||||
case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
|
||||
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
|
||||
case RPZ_NXDOMAIN_ACTION: return respip_always_nxdomain;
|
||||
case RPZ_NODATA_ACTION: return respip_always_nodata;
|
||||
case RPZ_DROP_ACTION: return respip_always_deny;
|
||||
case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
|
||||
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
|
||||
case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
|
||||
case RPZ_INVALID_ACTION: /* fallthrough */
|
||||
case RPZ_TCP_ONLY_ACTION: /* fallthrough */
|
||||
default: return respip_invalid;
|
||||
case RPZ_TCP_ONLY_ACTION: return respip_truncate;
|
||||
case RPZ_INVALID_ACTION: /* fallthrough */
|
||||
default: return respip_invalid;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -244,6 +244,7 @@ localzone_type_to_rpz_action(enum localzone_type lzt)
|
|||
case local_zone_always_deny: return RPZ_DROP_ACTION;
|
||||
case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
|
||||
case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
|
||||
case local_zone_truncate: return RPZ_TCP_ONLY_ACTION;
|
||||
case local_zone_invalid:
|
||||
default:
|
||||
return RPZ_INVALID_ACTION;
|
||||
|
|
@ -259,6 +260,7 @@ respip_action_to_rpz_action(enum respip_action a)
|
|||
case respip_always_deny: return RPZ_DROP_ACTION;
|
||||
case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
|
||||
case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
|
||||
case respip_truncate: return RPZ_TCP_ONLY_ACTION;
|
||||
case respip_invalid:
|
||||
default:
|
||||
return RPZ_INVALID_ACTION;
|
||||
|
|
@ -478,13 +480,17 @@ rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
|||
char* rrstr;
|
||||
int newzone = 0;
|
||||
|
||||
if(a == RPZ_TCP_ONLY_ACTION || a == RPZ_INVALID_ACTION) {
|
||||
if(a == RPZ_INVALID_ACTION) {
|
||||
verbose(VERB_ALGO, "RPZ: skipping unsupported action: %s",
|
||||
rpz_action_to_string(a));
|
||||
free(dname);
|
||||
return;
|
||||
}
|
||||
|
||||
if(a == RPZ_TCP_ONLY_ACTION) {
|
||||
verbose(VERB_ALGO, "RPZ: insert qname trigger: tcp-only");
|
||||
}
|
||||
|
||||
lock_rw_wrlock(&r->local_zones->lock);
|
||||
/* exact match */
|
||||
z = local_zones_find(r->local_zones, dname, dnamelen, dnamelabs,
|
||||
|
|
@ -550,13 +556,16 @@ rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
|||
char* rrstr;
|
||||
enum respip_action respa = rpz_action_to_respip_action(a);
|
||||
|
||||
if(a == RPZ_TCP_ONLY_ACTION || a == RPZ_INVALID_ACTION ||
|
||||
respa == respip_invalid) {
|
||||
if(a == RPZ_INVALID_ACTION || respa == respip_invalid) {
|
||||
verbose(VERB_ALGO, "RPZ: skipping unsupported action: %s",
|
||||
rpz_action_to_string(a));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(a == RPZ_TCP_ONLY_ACTION) {
|
||||
verbose(VERB_ALGO, "RPZ: insert respip trigger: tcp-only");
|
||||
}
|
||||
|
||||
if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
|
||||
return 0;
|
||||
|
||||
|
|
@ -984,6 +993,7 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
|
|||
lock_rw_unlock(&a->lock); /* not found in this auth_zone */
|
||||
}
|
||||
lock_rw_unlock(&az->rpz_lock);
|
||||
|
||||
if(!z)
|
||||
return 0; /* not holding auth_zone.lock anymore */
|
||||
|
||||
|
|
@ -1032,7 +1042,7 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
|
|||
lock_rw_unlock(&a->lock);
|
||||
return !qinfo->local_alias;
|
||||
}
|
||||
|
||||
verbose(VERB_ALGO, "xxxxxx repinfo=%p is_udp=%d", repinfo, repinfo->c->type == comm_udp);
|
||||
ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp,
|
||||
0 /* no local data used */, lzt);
|
||||
if(r->log)
|
||||
|
|
|
|||
40
testdata/rpz_qname.rpl
vendored
40
testdata/rpz_qname.rpl
vendored
|
|
@ -38,6 +38,7 @@ d TXT "local data 2nd zone"
|
|||
e CNAME *.a.example.
|
||||
*.e CNAME *.b.example.
|
||||
drop CNAME rpz-drop.
|
||||
tcp CNAME rpz-tcp-only.
|
||||
TEMPFILE_END
|
||||
|
||||
stub-zone:
|
||||
|
|
@ -295,10 +296,45 @@ something.e.b.example. IN TXT "*.b.example. answer from upstream ns"
|
|||
ENTRY_END
|
||||
|
||||
; deny zone
|
||||
STEP 90 QUERY
|
||||
;STEP 90 QUERY
|
||||
;ENTRY_BEGIN
|
||||
;SECTION QUESTION
|
||||
;drop. IN TXT
|
||||
;ENTRY_END
|
||||
|
||||
; tcp-only action
|
||||
|
||||
STEP 95 QUERY
|
||||
ENTRY_BEGIN
|
||||
SECTION QUESTION
|
||||
drop. IN TXT
|
||||
tcp. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 96 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RA AA TC NOERROR
|
||||
SECTION QUESTION
|
||||
tcp. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 97 QUERY
|
||||
ENTRY_BEGIN
|
||||
MATCH TCP
|
||||
SECTION QUESTION
|
||||
tcp. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 98 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all TCP
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
tcp. IN TXT
|
||||
SECTION ANSWER
|
||||
tcp. IN TXT "local tcp data 2nd zone"
|
||||
ENTRY_END
|
||||
|
||||
; no answer is checked at exit of testbound.
|
||||
SCENARIO_END
|
||||
|
|
|
|||
28
testdata/rpz_respip.rpl
vendored
28
testdata/rpz_respip.rpl
vendored
|
|
@ -20,6 +20,7 @@ $ORIGIN rpz.example.com.
|
|||
16.0.0.10.10.rpz-ip CNAME .
|
||||
24.0.10.10.10.rpz-ip CNAME rpz-drop.
|
||||
32.10.10.10.10.rpz-ip CNAME rpz-passthru.
|
||||
32.1.1.1.10.rpz-ip CNAME rpz-tcp-only.
|
||||
32.zz.db8.2001.rpz-ip CNAME *.
|
||||
48.zz.aa.db8.2001.rpz-ip CNAME .
|
||||
64.zz.bb.aa.db8.2001.rpz-ip CNAME rpz-drop.
|
||||
|
|
@ -217,6 +218,16 @@ SECTION ANSWER
|
|||
h. IN AAAA 2001:db8:aa:bb:cc::124
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
y. IN A
|
||||
SECTION ANSWER
|
||||
y. IN A 10.1.1.1
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
|
|
@ -446,4 +457,21 @@ SECTION QUESTION
|
|||
e. IN AAAA
|
||||
ENTRY_END
|
||||
STEP 29 TIME_PASSES ELAPSE 12
|
||||
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
y. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 31 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR TC RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
y. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
|
|
|||
Loading…
Reference in a new issue