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. */
|
* is explicitly specified. */
|
||||||
int rcode = (action == respip_always_nxdomain)?
|
int rcode = (action == respip_always_nxdomain)?
|
||||||
LDNS_RCODE_NXDOMAIN:LDNS_RCODE_NOERROR;
|
LDNS_RCODE_NXDOMAIN:LDNS_RCODE_NOERROR;
|
||||||
|
|
||||||
/* We should empty the answer section except for any preceding
|
/* We should empty the answer section except for any preceding
|
||||||
* CNAMEs (in that case rrset_id > 0). Type-ANY case is
|
* CNAMEs (in that case rrset_id > 0). Type-ANY case is
|
||||||
* special as noted in respip_data_answer(). */
|
* 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);
|
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
|
int
|
||||||
local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||||
struct query_info* qinfo, struct edns_data* edns,
|
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_redirect ||
|
||||||
lz_type == local_zone_inform_redirect ||
|
lz_type == local_zone_inform_redirect ||
|
||||||
lz_type == local_zone_always_nxdomain ||
|
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 static, reply nodata or nxdomain
|
||||||
* for redirect, reply nodata */
|
* for redirect, reply nodata */
|
||||||
/* no additional section processing,
|
/* 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 ||
|
int rcode = (ld || lz_type == local_zone_redirect ||
|
||||||
lz_type == local_zone_inform_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;
|
LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
|
||||||
|
rcode = lz_type == local_zone_truncate ? (rcode|BIT_TC) : rcode;
|
||||||
if(z->soa)
|
if(z->soa)
|
||||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||||
z->soa, 0, rcode);
|
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_nodata: return "always_nodata";
|
||||||
case local_zone_always_deny: return "always_deny";
|
case local_zone_always_deny: return "always_deny";
|
||||||
case local_zone_noview: return "noview";
|
case local_zone_noview: return "noview";
|
||||||
|
case local_zone_truncate: return "truncate";
|
||||||
case local_zone_invalid: return "invalid";
|
case local_zone_invalid: return "invalid";
|
||||||
}
|
}
|
||||||
return "badtyped";
|
return "badtyped";
|
||||||
|
|
@ -1800,6 +1814,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
|
||||||
*t = local_zone_always_deny;
|
*t = local_zone_always_deny;
|
||||||
else if(strcmp(type, "noview") == 0)
|
else if(strcmp(type, "noview") == 0)
|
||||||
*t = local_zone_noview;
|
*t = local_zone_noview;
|
||||||
|
else if(strcmp(type, "truncate") == 0)
|
||||||
|
*t = local_zone_truncate;
|
||||||
else if(strcmp(type, "nodefault") == 0)
|
else if(strcmp(type, "nodefault") == 0)
|
||||||
*t = local_zone_nodefault;
|
*t = local_zone_nodefault;
|
||||||
else return 0;
|
else return 0;
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,8 @@ enum localzone_type {
|
||||||
local_zone_always_deny,
|
local_zone_always_deny,
|
||||||
/** answer not from the view, but global or no-answer */
|
/** answer not from the view, but global or no-answer */
|
||||||
local_zone_noview,
|
local_zone_noview,
|
||||||
|
/** truncate the response; client should retry via tcp */
|
||||||
|
local_zone_truncate,
|
||||||
/** Invalid type, cannot be used to generate answer */
|
/** Invalid type, cannot be used to generate answer */
|
||||||
local_zone_invalid
|
local_zone_invalid
|
||||||
};
|
};
|
||||||
|
|
@ -556,6 +558,8 @@ enum respip_action {
|
||||||
respip_always_nodata = local_zone_always_nodata,
|
respip_always_nodata = local_zone_always_nodata,
|
||||||
/** answer with nodata response */
|
/** answer with nodata response */
|
||||||
respip_always_deny = local_zone_always_deny,
|
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
|
/* The rest of the values are only possible as
|
||||||
* access-control-tag-action */
|
* 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_PASSTHRU_ACTION: return local_zone_always_transparent;
|
||||||
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
|
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
|
||||||
case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect;
|
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_INVALID_ACTION: /* fallthrough */
|
||||||
case RPZ_TCP_ONLY_ACTION: /* fallthrough */
|
|
||||||
default: return local_zone_invalid;
|
default: return local_zone_invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -223,15 +223,15 @@ enum respip_action
|
||||||
rpz_action_to_respip_action(enum rpz_action a)
|
rpz_action_to_respip_action(enum rpz_action a)
|
||||||
{
|
{
|
||||||
switch(a) {
|
switch(a) {
|
||||||
case RPZ_NXDOMAIN_ACTION: return respip_always_nxdomain;
|
case RPZ_NXDOMAIN_ACTION: return respip_always_nxdomain;
|
||||||
case RPZ_NODATA_ACTION: return respip_always_nodata;
|
case RPZ_NODATA_ACTION: return respip_always_nodata;
|
||||||
case RPZ_DROP_ACTION: return respip_always_deny;
|
case RPZ_DROP_ACTION: return respip_always_deny;
|
||||||
case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
|
case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
|
||||||
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
|
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
|
||||||
case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
|
case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
|
||||||
case RPZ_INVALID_ACTION: /* fallthrough */
|
case RPZ_TCP_ONLY_ACTION: return respip_truncate;
|
||||||
case RPZ_TCP_ONLY_ACTION: /* fallthrough */
|
case RPZ_INVALID_ACTION: /* fallthrough */
|
||||||
default: return respip_invalid;
|
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_deny: return RPZ_DROP_ACTION;
|
||||||
case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
|
case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
|
||||||
case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
|
case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
|
||||||
|
case local_zone_truncate: return RPZ_TCP_ONLY_ACTION;
|
||||||
case local_zone_invalid:
|
case local_zone_invalid:
|
||||||
default:
|
default:
|
||||||
return RPZ_INVALID_ACTION;
|
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_deny: return RPZ_DROP_ACTION;
|
||||||
case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
|
case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
|
||||||
case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
|
case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
|
||||||
|
case respip_truncate: return RPZ_TCP_ONLY_ACTION;
|
||||||
case respip_invalid:
|
case respip_invalid:
|
||||||
default:
|
default:
|
||||||
return RPZ_INVALID_ACTION;
|
return RPZ_INVALID_ACTION;
|
||||||
|
|
@ -478,13 +480,17 @@ rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||||
char* rrstr;
|
char* rrstr;
|
||||||
int newzone = 0;
|
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",
|
verbose(VERB_ALGO, "RPZ: skipping unsupported action: %s",
|
||||||
rpz_action_to_string(a));
|
rpz_action_to_string(a));
|
||||||
free(dname);
|
free(dname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(a == RPZ_TCP_ONLY_ACTION) {
|
||||||
|
verbose(VERB_ALGO, "RPZ: insert qname trigger: tcp-only");
|
||||||
|
}
|
||||||
|
|
||||||
lock_rw_wrlock(&r->local_zones->lock);
|
lock_rw_wrlock(&r->local_zones->lock);
|
||||||
/* exact match */
|
/* exact match */
|
||||||
z = local_zones_find(r->local_zones, dname, dnamelen, dnamelabs,
|
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;
|
char* rrstr;
|
||||||
enum respip_action respa = rpz_action_to_respip_action(a);
|
enum respip_action respa = rpz_action_to_respip_action(a);
|
||||||
|
|
||||||
if(a == RPZ_TCP_ONLY_ACTION || a == RPZ_INVALID_ACTION ||
|
if(a == RPZ_INVALID_ACTION || respa == respip_invalid) {
|
||||||
respa == respip_invalid) {
|
|
||||||
verbose(VERB_ALGO, "RPZ: skipping unsupported action: %s",
|
verbose(VERB_ALGO, "RPZ: skipping unsupported action: %s",
|
||||||
rpz_action_to_string(a));
|
rpz_action_to_string(a));
|
||||||
return 0;
|
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))
|
if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
|
||||||
return 0;
|
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(&a->lock); /* not found in this auth_zone */
|
||||||
}
|
}
|
||||||
lock_rw_unlock(&az->rpz_lock);
|
lock_rw_unlock(&az->rpz_lock);
|
||||||
|
|
||||||
if(!z)
|
if(!z)
|
||||||
return 0; /* not holding auth_zone.lock anymore */
|
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);
|
lock_rw_unlock(&a->lock);
|
||||||
return !qinfo->local_alias;
|
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,
|
ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp,
|
||||||
0 /* no local data used */, lzt);
|
0 /* no local data used */, lzt);
|
||||||
if(r->log)
|
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 *.a.example.
|
||||||
*.e CNAME *.b.example.
|
*.e CNAME *.b.example.
|
||||||
drop CNAME rpz-drop.
|
drop CNAME rpz-drop.
|
||||||
|
tcp CNAME rpz-tcp-only.
|
||||||
TEMPFILE_END
|
TEMPFILE_END
|
||||||
|
|
||||||
stub-zone:
|
stub-zone:
|
||||||
|
|
@ -295,10 +296,45 @@ something.e.b.example. IN TXT "*.b.example. answer from upstream ns"
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
; deny zone
|
; 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
|
ENTRY_BEGIN
|
||||||
SECTION QUESTION
|
SECTION QUESTION
|
||||||
drop. IN TXT
|
tcp. IN TXT
|
||||||
ENTRY_END
|
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.
|
; no answer is checked at exit of testbound.
|
||||||
SCENARIO_END
|
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 .
|
16.0.0.10.10.rpz-ip CNAME .
|
||||||
24.0.10.10.10.rpz-ip CNAME rpz-drop.
|
24.0.10.10.10.rpz-ip CNAME rpz-drop.
|
||||||
32.10.10.10.10.rpz-ip CNAME rpz-passthru.
|
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 *.
|
32.zz.db8.2001.rpz-ip CNAME *.
|
||||||
48.zz.aa.db8.2001.rpz-ip CNAME .
|
48.zz.aa.db8.2001.rpz-ip CNAME .
|
||||||
64.zz.bb.aa.db8.2001.rpz-ip CNAME rpz-drop.
|
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
|
h. IN AAAA 2001:db8:aa:bb:cc::124
|
||||||
ENTRY_END
|
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
|
RANGE_END
|
||||||
|
|
||||||
STEP 1 QUERY
|
STEP 1 QUERY
|
||||||
|
|
@ -446,4 +457,21 @@ SECTION QUESTION
|
||||||
e. IN AAAA
|
e. IN AAAA
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
STEP 29 TIME_PASSES ELAPSE 12
|
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
|
SCENARIO_END
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue