Merge branch 'rpz' of https://github.com/magenbluten/unbound into magenbluten-rpz

Conflict fixed for rpz.disabled check added.
This commit is contained in:
W.C.A. Wijngaards 2021-01-14 12:11:29 +01:00
commit cdb60adcdc
18 changed files with 2724 additions and 273 deletions

View file

@ -1380,7 +1380,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
goto send_reply; goto send_reply;
} }
if(worker->env.auth_zones && if(worker->env.auth_zones &&
rpz_apply_qname_trigger(worker->env.auth_zones, rpz_callback_from_worker_request(worker->env.auth_zones,
&worker->env, &qinfo, &edns, c->buffer, worker->scratchpad, &worker->env, &qinfo, &edns, c->buffer, worker->scratchpad,
repinfo, acladdr->taglist, acladdr->taglen, &worker->stats)) { repinfo, acladdr->taglist, acladdr->taglen, &worker->stats)) {
regional_free_all(worker->scratchpad); regional_free_all(worker->scratchpad);

View file

@ -2471,6 +2471,17 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
/* Add the current set of unused targets to our queue. */ /* Add the current set of unused targets to our queue. */
delegpt_add_unused_targets(iq->dp); delegpt_add_unused_targets(iq->dp);
{ /* apply rpz triggers at query time */
struct dns_msg* forged_response = rpz_callback_from_iterator_module(qstate, iq);
if(forged_response != NULL) {
qstate->ext_state[id] = module_finished;
qstate->return_rcode = FLAGS_GET_RCODE(forged_response->rep->flags);
qstate->return_msg = forged_response;
next_state(iq, FINISHED_STATE);
return 0;
}
}
/* Select the next usable target, filtering out unsuitable targets. */ /* Select the next usable target, filtering out unsuitable targets. */
target = iter_server_selection(ie, qstate->env, iq->dp, target = iter_server_selection(ie, qstate->env, iq->dp,
iq->dp->name, iq->dp->namelen, iq->qchase.qtype, iq->dp->name, iq->dp->namelen, iq->qchase.qtype,
@ -2660,6 +2671,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
{ {
int dnsseclame = 0; int dnsseclame = 0;
enum response_type type; enum response_type type;
iq->num_current_queries--; iq->num_current_queries--;
if(!inplace_cb_query_response_call(qstate->env, qstate, iq->response)) if(!inplace_cb_query_response_call(qstate->env, qstate, iq->response))

View file

@ -483,8 +483,8 @@ respip_views_apply_cfg(struct views* vs, struct config_file* cfg,
* This function returns the copied rrset key on success, and NULL on memory * This function returns the copied rrset key on success, and NULL on memory
* allocation failure. * allocation failure.
*/ */
static struct ub_packed_rrset_key* struct ub_packed_rrset_key*
copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region) respip_copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region)
{ {
struct ub_packed_rrset_key* ck = regional_alloc(region, struct ub_packed_rrset_key* ck = regional_alloc(region,
sizeof(struct ub_packed_rrset_key)); sizeof(struct ub_packed_rrset_key));
@ -635,43 +635,6 @@ respip_addr_lookup(const struct reply_info *rep, struct respip_set* rs,
return NULL; return NULL;
} }
/*
* Create a new reply_info based on 'rep'. The new info is based on
* the passed 'rep', but ignores any rrsets except for the first 'an_numrrsets'
* RRsets in the answer section. These answer rrsets are copied to the
* new info, up to 'copy_rrsets' rrsets (which must not be larger than
* 'an_numrrsets'). If an_numrrsets > copy_rrsets, the remaining rrsets array
* entries will be kept empty so the caller can fill them later. When rrsets
* are copied, they are shallow copied. The caller must ensure that the
* copied rrsets are valid throughout its lifetime and must provide appropriate
* mutex if it can be shared by multiple threads.
*/
static struct reply_info *
make_new_reply_info(const struct reply_info* rep, struct regional* region,
size_t an_numrrsets, size_t copy_rrsets)
{
struct reply_info* new_rep;
size_t i;
/* create a base struct. we specify 'insecure' security status as
* the modified response won't be DNSSEC-valid. In our faked response
* the authority and additional sections will be empty (except possible
* EDNS0 OPT RR in the additional section appended on sending it out),
* so the total number of RRsets is an_numrrsets. */
new_rep = construct_reply_info_base(region, rep->flags,
rep->qdcount, rep->ttl, rep->prefetch_ttl,
rep->serve_expired_ttl, an_numrrsets, 0, 0, an_numrrsets,
sec_status_insecure);
if(!new_rep)
return NULL;
if(!reply_info_alloc_rrset_keys(new_rep, NULL, region))
return NULL;
for(i=0; i<copy_rrsets; i++)
new_rep->rrsets[i] = rep->rrsets[i];
return new_rep;
}
/** /**
* See if response-ip or tag data should override the original answer rrset * See if response-ip or tag data should override the original answer rrset
* (which is rep->rrsets[rrset_id]) and if so override it. * (which is rep->rrsets[rrset_id]) and if so override it.
@ -730,7 +693,7 @@ respip_data_answer(enum respip_action action,
"response-ip redirect with tag data [%d] %s", "response-ip redirect with tag data [%d] %s",
tag, (tag<num_tags?tagname[tag]:"null")); tag, (tag<num_tags?tagname[tag]:"null"));
/* use copy_rrset() to 'normalize' memory layout */ /* use copy_rrset() to 'normalize' memory layout */
rp = copy_rrset(&r, region); rp = respip_copy_rrset(&r, region);
if(!rp) if(!rp)
return -1; return -1;
} }
@ -743,7 +706,7 @@ respip_data_answer(enum respip_action action,
* rename the dname for other actions than redirect. This is because * rename the dname for other actions than redirect. This is because
* response-ip-data isn't associated to any specific name. */ * response-ip-data isn't associated to any specific name. */
if(rp == data) { if(rp == data) {
rp = copy_rrset(rp, region); rp = respip_copy_rrset(rp, region);
if(!rp) if(!rp)
return -1; return -1;
rp->rk.dname = rep->rrsets[rrset_id]->rk.dname; rp->rk.dname = rep->rrsets[rrset_id]->rk.dname;
@ -807,7 +770,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(). */
@ -1209,7 +1171,7 @@ respip_merge_cname(struct reply_info* base_rep,
if(!new_rep) if(!new_rep)
return 0; return 0;
for(i=0,j=base_rep->an_numrrsets; i<tgt_rep->an_numrrsets; i++,j++) { for(i=0,j=base_rep->an_numrrsets; i<tgt_rep->an_numrrsets; i++,j++) {
new_rep->rrsets[j] = copy_rrset(tgt_rep->rrsets[i], region); new_rep->rrsets[j] = respip_copy_rrset(tgt_rep->rrsets[i], region);
if(!new_rep->rrsets[j]) if(!new_rep->rrsets[j])
return 0; return 0;
} }

View file

@ -294,4 +294,7 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
*/ */
void void
respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node); respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node);
struct ub_packed_rrset_key*
respip_copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region);
#endif /* RESPIP_RESPIP_H */ #endif /* RESPIP_RESPIP_H */

View file

@ -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,9 +1557,11 @@ 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;
if(z->soa) rcode = lz_type == local_zone_truncate ? (rcode|BIT_TC) : rcode;
if(z != NULL && 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);
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode, local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
@ -1605,7 +1618,7 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
* does not, then we should make this noerror/nodata */ * does not, then we should make this noerror/nodata */
if(ld && ld->rrsets) { if(ld && ld->rrsets) {
int rcode = LDNS_RCODE_NOERROR; int rcode = LDNS_RCODE_NOERROR;
if(z->soa) if(z != NULL && 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);
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode, local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
@ -1804,6 +1817,7 @@ const char* local_zone_type2str(enum localzone_type t)
case local_zone_always_deny: return "always_deny"; case local_zone_always_deny: return "always_deny";
case local_zone_always_null: return "always_null"; case local_zone_always_null: return "always_null";
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";
@ -1843,6 +1857,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
*t = local_zone_always_null; *t = local_zone_always_null;
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;

View file

@ -101,6 +101,8 @@ enum localzone_type {
local_zone_always_null, local_zone_always_null,
/** 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
}; };
@ -559,6 +561,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 */

View file

@ -1177,6 +1177,22 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
m->s.env->mesh->num_reply_addrs--; m->s.env->mesh->num_reply_addrs--;
} }
static inline int
mesh_is_rpz_respip_tcponly_action(struct mesh_state const* m)
{
struct respip_action_info const* respip_info = m->s.respip_action_info;
return respip_info == NULL
? 0
: (respip_info->rpz_used
&& !respip_info->rpz_disabled
&& respip_info->action == respip_truncate);
}
static inline int
mesh_is_udp(struct mesh_reply const* r) {
return r->query_reply.c->type == comm_udp;
}
/** /**
* Send reply to mesh reply entry * Send reply to mesh reply entry
* @param m: mesh state to send it for. * @param m: mesh state to send it for.
@ -1204,6 +1220,11 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
* null stops the mesh state remove and thus * null stops the mesh state remove and thus
* reply_list modification and accounting */ * reply_list modification and accounting */
struct mesh_reply* rlist = m->reply_list; struct mesh_reply* rlist = m->reply_list;
/* rpz: apply actions */
rcode = mesh_is_udp(r) && mesh_is_rpz_respip_tcponly_action(m)
? (rcode|BIT_TC) : rcode;
/* examine security status */ /* examine security status */
if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) || if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
m->s.env->cfg->ignore_cd) && rep && m->s.env->cfg->ignore_cd) && rep &&

File diff suppressed because it is too large Load diff

View file

@ -83,6 +83,27 @@ enum rpz_action {
RPZ_CNAME_OVERRIDE_ACTION, /* RPZ CNAME action override*/ RPZ_CNAME_OVERRIDE_ACTION, /* RPZ CNAME action override*/
}; };
struct clientip_synthesized_rrset{
struct regional* region;
struct rbtree_type entries;
lock_rw_type lock; /* lock on the respip tree */
};
struct clientip_synthesized_rr {
/** node in address tree */
struct addr_tree_node node;
/** lock on the node item */
lock_rw_type lock;
/** tag bitlist */
uint8_t* taglist;
/** length of the taglist (in bytes) */
size_t taglen;
/** action for this address span */
enum rpz_action action;
/** "local data" for this node */
struct local_rrset* data;
};
/** /**
* RPZ containing policies. Pointed to from corresponding auth-zone. Part of a * RPZ containing policies. Pointed to from corresponding auth-zone. Part of a
* linked list to keep configuration order. Iterating or changing the linked * linked list to keep configuration order. Iterating or changing the linked
@ -92,6 +113,9 @@ enum rpz_action {
struct rpz { struct rpz {
struct local_zones* local_zones; struct local_zones* local_zones;
struct respip_set* respip_set; struct respip_set* respip_set;
struct clientip_synthesized_rrset* client_set;
struct clientip_synthesized_rrset* ns_set;
struct local_zones* nsdname_zones;
uint8_t* taglist; uint8_t* taglist;
size_t taglistlen; size_t taglistlen;
enum rpz_action action_override; enum rpz_action action_override;
@ -151,11 +175,14 @@ void rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
* @param stats: worker stats struct * @param stats: worker stats struct
* @return: 1 if client answer is ready, 0 to continue resolving * @return: 1 if client answer is ready, 0 to continue resolving
*/ */
int rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env, int rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
struct regional* temp, struct comm_reply* repinfo, struct regional* temp, struct comm_reply* repinfo,
uint8_t* taglist, size_t taglen, struct ub_server_stats* stats); uint8_t* taglist, size_t taglen, struct ub_server_stats* stats);
struct iter_qstate;
struct dns_msg* rpz_callback_from_iterator_module(struct module_qstate*, struct iter_qstate*);
/** /**
* Delete RPZ * Delete RPZ
* @param r: RPZ struct to delete * @param r: RPZ struct to delete

257
testdata/rpz_clientip.rpl vendored Normal file
View file

@ -0,0 +1,257 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
access-control: 192.0.0.0/8 allow
rpz:
name: "rpz.example.com."
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN example.com.
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz.example.com.
3600 IN NS ns2.rpz.example.com.
$ORIGIN rpz.example.com.
24.0.0.0.192.rpz-client-ip CNAME .
24.0.1.0.192.rpz-client-ip CNAME *.
24.0.2.0.192.rpz-client-ip CNAME rpz-drop.
24.0.3.0.192.rpz-client-ip CNAME rpz-passthru.
24.0.4.0.192.rpz-client-ip CNAME rpz-tcp-only.
24.0.5.0.192.rpz-client-ip A 127.0.0.1
24.0.5.0.192.rpz-client-ip TXT "42"
TEMPFILE_END
stub-zone:
name: "a."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test RPZ client ip triggers
RANGE_BEGIN 0 100
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a. IN NS
SECTION ANSWER
a. IN NS ns.a.
SECTION ADDITIONAL
ns.a IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
a.a. IN TXT "upstream txt rr a.a."
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a.a. IN A
SECTION ANSWER
a.a. IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a.a. IN AAAA
SECTION ANSWER
a.a. IN AAAA 2001:db8::123
ENTRY_END
RANGE_END
; unrelated client ip address -- passthru
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.a. IN TXT
ENTRY_END
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
a.a. IN TXT "upstream txt rr a.a."
ENTRY_END
; should be NXDOMAIN
STEP 20 QUERY ADDRESS 192.0.0.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.a. IN TXT
ENTRY_END
STEP 21 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR AA RD RA NXDOMAIN
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
ENTRY_END
; should be NODATA
STEP 30 QUERY ADDRESS 192.0.1.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.a. IN TXT
ENTRY_END
STEP 31 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR AA RD RA NOERROR
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
ENTRY_END
; should be PASSTHRU
STEP 40 QUERY ADDRESS 192.0.3.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.a. IN TXT
ENTRY_END
STEP 41 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
a.a. IN TXT "upstream txt rr a.a."
ENTRY_END
; should be TRUNCATED
STEP 50 QUERY ADDRESS 192.0.4.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.a. IN TXT
ENTRY_END
STEP 51 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR AA TC RD RA NOERROR
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
ENTRY_END
; should not be TRUNCATED via TCP
STEP 52 QUERY ADDRESS 192.0.4.1
ENTRY_BEGIN
MATCH TCP
REPLY RD
SECTION QUESTION
a.a. IN TXT
ENTRY_END
STEP 53 CHECK_ANSWER
ENTRY_BEGIN
MATCH all TCP
REPLY QR RD RA NOERROR
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
a.a. IN TXT "upstream txt rr a.a."
ENTRY_END
; should be synthesized
STEP 60 QUERY ADDRESS 192.0.5.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.a. IN A
ENTRY_END
STEP 61 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR AA RD RA NOERROR
SECTION QUESTION
a.a. IN A
SECTION ANSWER
a.a. IN A 127.0.0.1
ENTRY_END
; should be synthesized
STEP 62 QUERY ADDRESS 192.0.5.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.a. IN TXT
ENTRY_END
STEP 63 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR AA RD RA NOERROR
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
a.a. IN TXT "42"
ENTRY_END
; should be synthesized NODATA
STEP 64 QUERY ADDRESS 192.0.5.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.a. IN AAAA
ENTRY_END
STEP 65 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR AA RD RA NOERROR
SECTION QUESTION
a.a. IN AAAA
ENTRY_END
; should be DROPPED
STEP 90 QUERY ADDRESS 192.0.2.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.a. IN TXT
ENTRY_END
SCENARIO_END

388
testdata/rpz_nsdname.rpl vendored Normal file
View file

@ -0,0 +1,388 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
access-control: 192.0.0.0/8 allow
rpz:
name: "rpz.example.com."
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN example.com.
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz.example.com.
3600 IN NS ns2.rpz.example.com.
$ORIGIN rpz.example.com.
gotham.aa.rpz-nsdname CNAME .
gotham.bb.rpz-nsdname CNAME *.
gotham.cc.rpz-nsdname CNAME rpz-drop.
gotham.com.rpz-nsdname CNAME rpz-passthru.
gotham.dd.rpz-nsdname CNAME rpz-tcp-only.
gotham.ff.rpz-nsdname A 127.0.0.1
gotham.ff.rpz-nsdname TXT "42"
TEMPFILE_END
stub-zone:
name: "."
stub-addr: 1.1.1.1
CONFIG_END
SCENARIO_BEGIN Test RPZ nsip triggers
; . --------------------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 1.1.1.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS ns.root.
SECTION ADDITIONAL
ns.root IN A 1.1.1.1
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN A
SECTION AUTHORITY
com. IN NS ns1.com.
SECTION ADDITIONAL
ns1.com. IN A 8.8.8.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
aa. IN A
SECTION AUTHORITY
aa. IN NS ns1.aa.
SECTION ADDITIONAL
ns1.aa. IN A 8.8.0.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
bb. IN A
SECTION AUTHORITY
bb. IN NS ns1.bb.
SECTION ADDITIONAL
ns1.bb. IN A 8.8.1.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
cc. IN A
SECTION AUTHORITY
cc. IN NS ns1.cc.
SECTION ADDITIONAL
ns1.cc. IN A 8.8.2.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
dd. IN A
SECTION AUTHORITY
dd. IN NS ns1.dd.
SECTION ADDITIONAL
ns1.dd. IN A 8.8.3.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
ee. IN A
SECTION AUTHORITY
ee. IN NS ns1.ee.
SECTION ADDITIONAL
ns1.ee. IN A 8.8.5.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
ff. IN A
SECTION AUTHORITY
ff. IN NS ns1.ff.
SECTION ADDITIONAL
ns1.ff. IN A 8.8.6.8
ENTRY_END
RANGE_END
; com. -----------------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 8.8.8.8
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS ns1.com.
SECTION ADDITIONAL
ns1.com. IN A 8.8.8.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
gotham.com. IN A
SECTION AUTHORITY
gotham.com. IN NS ns1.gotham.com.
SECTION ADDITIONAL
ns1.gotham.com. IN A 192.0.6.1
ENTRY_END
RANGE_END
; aa. ------------------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 8.8.0.8
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
aa. IN NS
SECTION ANSWER
aa. IN NS ns1.aa.
SECTION ADDITIONAL
ns1.aa. IN A 8.8.0.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
gotham.aa. IN A
SECTION AUTHORITY
gotham.aa. IN NS ns1.gotham.aa.
SECTION ADDITIONAL
ns1.gotham.aa. IN A 192.0.0.1
ENTRY_END
RANGE_END
; bb. ------------------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 8.8.1.8
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
bb. IN NS
SECTION ANSWER
bb. IN NS ns1.bb.
SECTION ADDITIONAL
ns1.bb. IN A 8.8.1.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
gotham.bb. IN A
SECTION AUTHORITY
gotham.bb. IN NS ns1.gotham.bb.
SECTION ADDITIONAL
ns1.gotham.bb. IN A 192.0.1.1
ENTRY_END
RANGE_END
; ff. ------------------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 8.8.6.8
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ff. IN NS
SECTION ANSWER
ff. IN NS ns1.ff.
SECTION ADDITIONAL
ns1.ff. IN A 8.8.6.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
gotham.ff. IN A
SECTION AUTHORITY
gotham.ff. IN NS ns1.gotham.ff.
SECTION ADDITIONAL
ns1.gotham.ff. IN A 192.0.5.1
ENTRY_END
RANGE_END
; ns1.gotham.com. ------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 192.0.6.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
gotham.com. IN A
SECTION ANSWER
gotham.com. IN A 192.0.6.2
ENTRY_END
RANGE_END
; ns1.gotham.aa. -------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 192.0.0.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
gotham.aa. IN A
SECTION ANSWER
gotham.aa. IN A 192.0.0.2
ENTRY_END
RANGE_END
; ns1.gotham.bb. -------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 192.0.1.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
gotham.bb. IN A
SECTION ANSWER
gotham.bb. IN A 192.0.1.2
ENTRY_END
RANGE_END
; ns1.gotham.ff. -------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 192.0.5.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
gotham.ff. IN A
SECTION ANSWER
gotham.ff. IN A 192.0.5.2
ENTRY_END
RANGE_END
; ----------------------------------------------------------------------------
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
gotham.com. IN A
ENTRY_END
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
gotham.com. IN A
SECTION ANSWER
gotham.com. IN A 192.0.6.2
ENTRY_END
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
gotham.aa. IN A
ENTRY_END
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
gotham.aa. IN A
SECTION ANSWER
ENTRY_END
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
gotham.bb. IN A
ENTRY_END
STEP 21 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
gotham.bb. IN A
SECTION ANSWER
ENTRY_END
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
gotham.ff. IN A
ENTRY_END
STEP 31 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
gotham.ff. IN A
SECTION ANSWER
gotham.ff. IN A 127.0.0.1
ENTRY_END
SCENARIO_END

388
testdata/rpz_nsip.rpl vendored Normal file
View file

@ -0,0 +1,388 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
access-control: 192.0.0.0/8 allow
rpz:
name: "rpz.example.com."
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN example.com.
rpz 3600 IN SOA ns1.rpz.gotham.com. hostmaster.rpz.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz.example.com.
3600 IN NS ns2.rpz.example.com.
$ORIGIN rpz.example.com.
24.0.0.0.192.rpz-nsip CNAME .
24.0.1.0.192.rpz-nsip CNAME *.
24.0.2.0.192.rpz-nsip CNAME rpz-drop.
24.0.3.0.192.rpz-nsip CNAME rpz-passthru.
24.0.4.0.192.rpz-nsip CNAME rpz-tcp-only.
24.0.5.0.192.rpz-nsip A 127.0.0.1
24.0.5.0.192.rpz-nsip TXT "42"
TEMPFILE_END
stub-zone:
name: "."
stub-addr: 1.1.1.1
CONFIG_END
SCENARIO_BEGIN Test RPZ nsip triggers
; . --------------------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 1.1.1.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS ns.root.
SECTION ADDITIONAL
ns.root IN A 1.1.1.1
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN A
SECTION AUTHORITY
com. IN NS ns1.com.
SECTION ADDITIONAL
ns1.com. IN A 8.8.8.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
aa. IN A
SECTION AUTHORITY
aa. IN NS ns1.aa.
SECTION ADDITIONAL
ns1.aa. IN A 8.8.0.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
bb. IN A
SECTION AUTHORITY
bb. IN NS ns1.bb.
SECTION ADDITIONAL
ns1.bb. IN A 8.8.1.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
cc. IN A
SECTION AUTHORITY
cc. IN NS ns1.cc.
SECTION ADDITIONAL
ns1.cc. IN A 8.8.2.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
dd. IN A
SECTION AUTHORITY
dd. IN NS ns1.dd.
SECTION ADDITIONAL
ns1.dd. IN A 8.8.3.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
ee. IN A
SECTION AUTHORITY
ee. IN NS ns1.ee.
SECTION ADDITIONAL
ns1.ee. IN A 8.8.5.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
ff. IN A
SECTION AUTHORITY
ff. IN NS ns1.ff.
SECTION ADDITIONAL
ns1.ff. IN A 8.8.6.8
ENTRY_END
RANGE_END
; com. -----------------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 8.8.8.8
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS ns1.com.
SECTION ADDITIONAL
ns1.com. IN A 8.8.8.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
gotham.com. IN A
SECTION AUTHORITY
gotham.com. IN NS ns1.gotham.com.
SECTION ADDITIONAL
ns1.gotham.com. IN A 192.0.6.1
ENTRY_END
RANGE_END
; aa. ------------------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 8.8.0.8
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
aa. IN NS
SECTION ANSWER
aa. IN NS ns1.aa.
SECTION ADDITIONAL
ns1.aa. IN A 8.8.0.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
gotham.aa. IN A
SECTION AUTHORITY
gotham.aa. IN NS ns1.gotham.aa.
SECTION ADDITIONAL
ns1.gotham.aa. IN A 192.0.0.1
ENTRY_END
RANGE_END
; bb. ------------------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 8.8.1.8
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
bb. IN NS
SECTION ANSWER
bb. IN NS ns1.bb.
SECTION ADDITIONAL
ns1.bb. IN A 8.8.1.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
gotham.bb. IN A
SECTION AUTHORITY
gotham.bb. IN NS ns1.gotham.bb.
SECTION ADDITIONAL
ns1.gotham.bb. IN A 192.0.1.1
ENTRY_END
RANGE_END
; ff. ------------------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 8.8.6.8
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ff. IN NS
SECTION ANSWER
ff. IN NS ns1.ff.
SECTION ADDITIONAL
ns1.ff. IN A 8.8.6.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
gotham.ff. IN A
SECTION AUTHORITY
gotham.ff. IN NS ns1.gotham.ff.
SECTION ADDITIONAL
ns1.gotham.ff. IN A 192.0.5.1
ENTRY_END
RANGE_END
; ns1.gotham.com. ------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 192.0.6.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
gotham.com. IN A
SECTION ANSWER
gotham.com. IN A 192.0.6.2
ENTRY_END
RANGE_END
; ns1.gotham.aa. -------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 192.0.0.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
gotham.aa. IN A
SECTION ANSWER
gotham.aa. IN A 192.0.0.2
ENTRY_END
RANGE_END
; ns1.gotham.bb. -------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 192.0.1.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
gotham.bb. IN A
SECTION ANSWER
gotham.bb. IN A 192.0.1.2
ENTRY_END
RANGE_END
; ns1.gotham.ff. -------------------------------------------------------------
RANGE_BEGIN 0 100
ADDRESS 192.0.5.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
gotham.ff. IN A
SECTION ANSWER
gotham.ff. IN A 192.0.5.2
ENTRY_END
RANGE_END
; ----------------------------------------------------------------------------
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
gotham.com. IN A
ENTRY_END
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
gotham.com. IN A
SECTION ANSWER
gotham.com. IN A 192.0.6.2
ENTRY_END
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
gotham.aa. IN A
ENTRY_END
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
gotham.aa. IN A
SECTION ANSWER
ENTRY_END
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
gotham.bb. IN A
ENTRY_END
STEP 21 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
gotham.bb. IN A
SECTION ANSWER
ENTRY_END
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
gotham.ff. IN A
ENTRY_END
STEP 31 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
gotham.ff. IN A
SECTION ANSWER
gotham.ff. IN A 127.0.0.1
ENTRY_END
SCENARIO_END

View file

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

117
testdata/rpz_qname_tcponly.rpl vendored Normal file
View file

@ -0,0 +1,117 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
rpz:
name: "rpz.example.com."
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN example.com.
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz.example.com.
3600 IN NS ns2.rpz.example.com.
$ORIGIN rpz.example.com.
a.a CNAME rpz-passthru.
b.a CNAME rpz-tcp-only.
TEMPFILE_END
stub-zone:
name: "a."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test RPZ qname trigger and tcp-only action
RANGE_BEGIN 0 100
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a. IN NS
SECTION ANSWER
a. IN NS ns.a.
SECTION ADDITIONAL
ns.a IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
a.a. IN TXT "upstream txt rr a.a."
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
b.a. IN TXT
SECTION ANSWER
b.a. IN TXT "upstream txt rr b.a."
ENTRY_END
RANGE_END
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.a. IN TXT
ENTRY_END
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
a.a. IN TXT "upstream txt rr a.a."
ENTRY_END
STEP 20 QUERY
ENTRY_BEGIN
MATCH UDP
REPLY RD
SECTION QUESTION
b.a. IN TXT
ENTRY_END
STEP 21 CHECK_ANSWER
ENTRY_BEGIN
MATCH all UDP
REPLY QR AA TC RD RA NOERROR
SECTION QUESTION
b.a. IN TXT
SECTION ANSWER
ENTRY_END
STEP 30 QUERY
ENTRY_BEGIN
MATCH TCP
REPLY RD
SECTION QUESTION
b.a. IN TXT
ENTRY_END
STEP 31 CHECK_ANSWER
ENTRY_BEGIN
MATCH all TCP
REPLY QR RD RA NOERROR
SECTION QUESTION
b.a. IN TXT
SECTION ANSWER
b.a. IN TXT "upstream txt rr b.a."
ENTRY_END
SCENARIO_END

View file

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

207
testdata/rpz_respip_tcponly.rpl vendored Normal file
View file

@ -0,0 +1,207 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
rpz:
name: "rpz.example.com."
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN example.com.
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz.example.com.
3600 IN NS ns2.rpz.example.com.
$ORIGIN rpz.example.com.
8.0.0.0.10.rpz-ip CNAME *.
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.
TEMPFILE_END
stub-zone:
name: "."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test RPZ response IP address trigger and tcp-only action
RANGE_BEGIN 0 100
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS ns.
SECTION ADDITIONAL
ns. IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a. IN A
SECTION ANSWER
a. IN A 10.0.0.123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
b. IN A
SECTION ANSWER
b. IN A 10.1.0.123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
c. IN A
SECTION ANSWER
c. IN A 10.11.0.123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
d. IN A
SECTION ANSWER
d. IN A 10.10.0.123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
f. IN A
SECTION ANSWER
f. IN A 10.10.10.10
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
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a. IN A
ENTRY_END
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
a. IN A
SECTION ANSWER
ENTRY_END
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
b. IN A
ENTRY_END
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
b. IN A
SECTION ANSWER
ENTRY_END
STEP 13 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d. IN A
ENTRY_END
STEP 14 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
d. IN A
SECTION ANSWER
ENTRY_END
STEP 17 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
f. IN A
ENTRY_END
STEP 18 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
f. IN A
SECTION ANSWER
f. IN A 10.10.10.10
ENTRY_END
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
STEP 40 QUERY
ENTRY_BEGIN
MATCH TCP
REPLY RD
SECTION QUESTION
y. IN A
ENTRY_END
STEP 41 CHECK_ANSWER
ENTRY_BEGIN
MATCH all TCP
REPLY QR RD RA NOERROR
SECTION QUESTION
y. IN A
SECTION ANSWER
y. IN A 10.1.1.1
ENTRY_END
SCENARIO_END

View file

@ -164,6 +164,32 @@ reply_info_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc,
return 1; return 1;
} }
struct reply_info *
make_new_reply_info(const struct reply_info* rep, struct regional* region,
size_t an_numrrsets, size_t copy_rrsets)
{
struct reply_info* new_rep;
size_t i;
/* create a base struct. we specify 'insecure' security status as
* the modified response won't be DNSSEC-valid. In our faked response
* the authority and additional sections will be empty (except possible
* EDNS0 OPT RR in the additional section appended on sending it out),
* so the total number of RRsets is an_numrrsets. */
new_rep = construct_reply_info_base(region, rep->flags,
rep->qdcount, rep->ttl, rep->prefetch_ttl,
rep->serve_expired_ttl, an_numrrsets, 0, 0, an_numrrsets,
sec_status_insecure);
if(!new_rep)
return NULL;
if(!reply_info_alloc_rrset_keys(new_rep, NULL, region))
return NULL;
for(i=0; i<copy_rrsets; i++)
new_rep->rrsets[i] = rep->rrsets[i];
return new_rep;
}
/** find the minimumttl in the rdata of SOA record */ /** find the minimumttl in the rdata of SOA record */
static time_t static time_t
soa_find_minttl(struct rr_parse* rr) soa_find_minttl(struct rr_parse* rr)

View file

@ -382,6 +382,21 @@ struct reply_info* reply_info_copy(struct reply_info* rep,
int reply_info_alloc_rrset_keys(struct reply_info* rep, int reply_info_alloc_rrset_keys(struct reply_info* rep,
struct alloc_cache* alloc, struct regional* region); struct alloc_cache* alloc, struct regional* region);
/*
* Create a new reply_info based on 'rep'. The new info is based on
* the passed 'rep', but ignores any rrsets except for the first 'an_numrrsets'
* RRsets in the answer section. These answer rrsets are copied to the
* new info, up to 'copy_rrsets' rrsets (which must not be larger than
* 'an_numrrsets'). If an_numrrsets > copy_rrsets, the remaining rrsets array
* entries will be kept empty so the caller can fill them later. When rrsets
* are copied, they are shallow copied. The caller must ensure that the
* copied rrsets are valid throughout its lifetime and must provide appropriate
* mutex if it can be shared by multiple threads.
*/
struct reply_info *
make_new_reply_info(const struct reply_info* rep, struct regional* region,
size_t an_numrrsets, size_t copy_rrsets);
/** /**
* Copy a parsed rrset into given key, decompressing and allocating rdata. * Copy a parsed rrset into given key, decompressing and allocating rdata.
* @param pkt: packet for decompression * @param pkt: packet for decompression