RPZ: implement stubs for rpz-tcp-only actions.

This commit is contained in:
mb 2020-10-29 15:58:13 +01:00
parent d104727c91
commit dd70c2ef9a
6 changed files with 111 additions and 18 deletions

View file

@ -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(). */

View file

@ -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;

View file

@ -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 */

View file

@ -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)

View file

@ -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

View file

@ -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