mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-02-02 19:59:28 -05:00
commit
74f1f0addd
24 changed files with 3321 additions and 300 deletions
|
|
@ -1355,7 +1355,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||
goto send_reply;
|
||||
}
|
||||
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,
|
||||
repinfo, acladdr->taglist, acladdr->taglen, &worker->stats)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
|
|
|
|||
|
|
@ -1152,10 +1152,11 @@ remote-control:
|
|||
# dnstap-log-forwarder-response-messages: no
|
||||
|
||||
# Response Policy Zones
|
||||
# RPZ policies. Applied in order of configuration. QNAME and Response IP
|
||||
# Address trigger are the only supported triggers. Supported actions are:
|
||||
# NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. Policies can be loaded from
|
||||
# file, using zone transfer, or using HTTP. The respip module needs to be added
|
||||
# RPZ policies. Applied in order of configuration. QNAME, Response IP
|
||||
# Address, nsdname, nsip and clientip triggers are supported. Supported
|
||||
# actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp-only
|
||||
# and drop. Policies can be loaded from a file, or using zone
|
||||
# transfer, or using HTTP. The respip module needs to be added
|
||||
# to the module-config, e.g.: module-config: "respip validator iterator".
|
||||
# rpz:
|
||||
# name: "rpz.example.com"
|
||||
|
|
|
|||
|
|
@ -684,8 +684,8 @@ specific cache, after getting processed by the edns client subnet module.
|
|||
.TP
|
||||
.I num.rpz.action.<rpz_action>
|
||||
Number of queries answered using configured RPZ policy, per RPZ action type.
|
||||
Possible actions are: nxdomain, nodata, passthru, drop, local_data, disabled,
|
||||
and cname_override.
|
||||
Possible actions are: nxdomain, nodata, passthru, drop, tcp\-only, local\-data,
|
||||
disabled, and cname\-override.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I @ub_conf_file@
|
||||
|
|
|
|||
|
|
@ -2516,10 +2516,49 @@ with a different name. RPZ clauses are applied in order of configuration. The
|
|||
\fBrespip\fR module needs to be added to the \fBmodule-config\fR, e.g.:
|
||||
\fBmodule-config: "respip validator iterator"\fR.
|
||||
.P
|
||||
Only the QNAME and Response IP Address triggers are supported. The supported RPZ
|
||||
actions are: NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. RPZ QNAME triggers
|
||||
are applied after
|
||||
\fBlocal-zones\fR and before \fBauth-zones\fR.
|
||||
QNAME, Response IP Address, nsdname, nsip and clientip triggers are supported.
|
||||
Supported actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp\-only
|
||||
and drop. RPZ QNAME triggers are applied after \fBlocal\-zones\fR and
|
||||
before \fBauth\-zones\fR.
|
||||
.P
|
||||
The rpz zone is formatted with a SOA start record as usual. The items in
|
||||
the zone are entries, that specify what to act on (the trigger) and what to
|
||||
do (the action). The trigger to act on is recorded in the name, the action
|
||||
to do is recorded as the resource record. The names all end in the zone
|
||||
name, so you could type the trigger names without a trailing dot in the
|
||||
zonefile.
|
||||
.P
|
||||
An example RPZ record, that answers example.com with NXDOMAIN
|
||||
.nf
|
||||
example.com CNAME .
|
||||
.fi
|
||||
.P
|
||||
The triggers are encoded in the name on the left
|
||||
.nf
|
||||
name query name
|
||||
netblock.rpz-client-ip client IP address
|
||||
netblock.rpz-ip response IP address in the answer
|
||||
name.rpz-nsdname nameserver name
|
||||
netblock.rpz-nsip nameserver IP address
|
||||
.fi
|
||||
The netblock is written as <netblocklen>.<ip address in reverse>.
|
||||
For IPv6 use 'zz' for '::'. Specify individual addresses with scope length
|
||||
of 32 or 128. For example, 24.10.100.51.198.rpz-ip is 198.51.100.10/24 and
|
||||
32.10.zz.db8.2001.rpz-ip is 2001:db8:0:0:0:0:0:10/32.
|
||||
.P
|
||||
The actions are specified with the record on the right
|
||||
.nf
|
||||
CNAME . nxdomain reply
|
||||
CNAME *. nodata reply
|
||||
CNAME rpz-passthru. do nothing, allow to continue
|
||||
CNAME rpz-drop. the query is dropped
|
||||
CNAME rpz-tcp-only. answer over TCP
|
||||
A 192.0.2.1 answer with this IP address
|
||||
.fi
|
||||
Other records like AAAA, TXT and other CNAMEs (not rpz-..) can also be used to
|
||||
answer queries with that content.
|
||||
.P
|
||||
The RPZ zones can be configured in the config file with these settings in the \fBrpz:\fR block.
|
||||
.TP
|
||||
.B name: \fI<zone name>
|
||||
Name of the authority zone.
|
||||
|
|
|
|||
|
|
@ -2529,6 +2529,23 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
/* Add the current set of unused targets to our queue. */
|
||||
delegpt_add_unused_targets(iq->dp);
|
||||
|
||||
if(qstate->env->auth_zones) {
|
||||
/* 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;
|
||||
iq->response = forged_response;
|
||||
next_state(iq, FINISHED_STATE);
|
||||
if(!iter_prepend(iq, qstate->return_msg, qstate->region)) {
|
||||
log_err("rpz, prepend rrsets: out of memory");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Select the next usable target, filtering out unsuitable targets. */
|
||||
target = iter_server_selection(ie, qstate->env, iq->dp,
|
||||
iq->dp->name, iq->dp->namelen, iq->qchase.qtype,
|
||||
|
|
@ -2719,6 +2736,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
{
|
||||
int dnsseclame = 0;
|
||||
enum response_type type;
|
||||
|
||||
iq->num_current_queries--;
|
||||
|
||||
if(!inplace_cb_query_response_call(qstate->env, qstate, iq->response))
|
||||
|
|
@ -3062,6 +3080,39 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
/* set the current request's qname to the new value. */
|
||||
iq->qchase.qname = sname;
|
||||
iq->qchase.qname_len = snamelen;
|
||||
if(qstate->env->auth_zones) {
|
||||
/* apply rpz qname triggers after cname */
|
||||
struct dns_msg* forged_response =
|
||||
rpz_callback_from_iterator_cname(qstate, iq);
|
||||
while(forged_response && reply_find_rrset_section_an(
|
||||
forged_response->rep, iq->qchase.qname,
|
||||
iq->qchase.qname_len, LDNS_RR_TYPE_CNAME,
|
||||
iq->qchase.qclass)) {
|
||||
/* another cname to follow */
|
||||
if(!handle_cname_response(qstate, iq, forged_response,
|
||||
&sname, &snamelen)) {
|
||||
errinf(qstate, "malloc failure, CNAME info");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->qchase.qname = sname;
|
||||
iq->qchase.qname_len = snamelen;
|
||||
forged_response =
|
||||
rpz_callback_from_iterator_cname(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;
|
||||
iq->response = forged_response;
|
||||
next_state(iq, FINISHED_STATE);
|
||||
if(!iter_prepend(iq, qstate->return_msg, qstate->region)) {
|
||||
log_err("rpz after cname, prepend rrsets: out of memory");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
qstate->return_msg->qinfo = qstate->qinfo;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* Clear the query state, since this is a query restart. */
|
||||
iq->deleg_msg = NULL;
|
||||
iq->dp = NULL;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "respip/respip.h"
|
||||
#include "services/view.h"
|
||||
#include "sldns/rrdef.h"
|
||||
#include "util/data/dname.h"
|
||||
|
||||
|
||||
/** Subset of resp_addr.node, used for inform-variant logging */
|
||||
|
|
@ -483,8 +484,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
|
||||
* allocation failure.
|
||||
*/
|
||||
static struct ub_packed_rrset_key*
|
||||
copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region)
|
||||
struct ub_packed_rrset_key*
|
||||
respip_copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region)
|
||||
{
|
||||
struct ub_packed_rrset_key* ck = regional_alloc(region,
|
||||
sizeof(struct ub_packed_rrset_key));
|
||||
|
|
@ -602,7 +603,7 @@ rdata2sockaddr(const struct packed_rrset_data* rd, uint16_t rtype, size_t i,
|
|||
*/
|
||||
static struct resp_addr*
|
||||
respip_addr_lookup(const struct reply_info *rep, struct respip_set* rs,
|
||||
size_t* rrset_id)
|
||||
size_t* rrset_id, size_t* rr_id)
|
||||
{
|
||||
size_t i;
|
||||
struct resp_addr* ra;
|
||||
|
|
@ -625,6 +626,7 @@ respip_addr_lookup(const struct reply_info *rep, struct respip_set* rs,
|
|||
&ss, addrlen);
|
||||
if(ra) {
|
||||
*rrset_id = i;
|
||||
*rr_id = j;
|
||||
lock_rw_rdlock(&ra->lock);
|
||||
lock_rw_unlock(&rs->lock);
|
||||
return ra;
|
||||
|
|
@ -635,43 +637,6 @@ respip_addr_lookup(const struct reply_info *rep, struct respip_set* rs,
|
|||
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
|
||||
* (which is rep->rrsets[rrset_id]) and if so override it.
|
||||
|
|
@ -730,7 +695,7 @@ respip_data_answer(enum respip_action action,
|
|||
"response-ip redirect with tag data [%d] %s",
|
||||
tag, (tag<num_tags?tagname[tag]:"null"));
|
||||
/* use copy_rrset() to 'normalize' memory layout */
|
||||
rp = copy_rrset(&r, region);
|
||||
rp = respip_copy_rrset(&r, region);
|
||||
if(!rp)
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -743,7 +708,7 @@ respip_data_answer(enum respip_action action,
|
|||
* rename the dname for other actions than redirect. This is because
|
||||
* response-ip-data isn't associated to any specific name. */
|
||||
if(rp == data) {
|
||||
rp = copy_rrset(rp, region);
|
||||
rp = respip_copy_rrset(rp, region);
|
||||
if(!rp)
|
||||
return -1;
|
||||
rp->rk.dname = rep->rrsets[rrset_id]->rk.dname;
|
||||
|
|
@ -807,7 +772,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(). */
|
||||
|
|
@ -907,7 +871,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
|||
size_t tag_datas_size;
|
||||
struct view* view = NULL;
|
||||
struct respip_set* ipset = NULL;
|
||||
size_t rrset_id = 0;
|
||||
size_t rrset_id = 0, rr_id = 0;
|
||||
enum respip_action action = respip_none;
|
||||
int tag = -1;
|
||||
struct resp_addr* raddr = NULL;
|
||||
|
|
@ -948,7 +912,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
|||
lock_rw_rdlock(&view->lock);
|
||||
if(view->respip_set) {
|
||||
if((raddr = respip_addr_lookup(rep,
|
||||
view->respip_set, &rrset_id))) {
|
||||
view->respip_set, &rrset_id, &rr_id))) {
|
||||
/** for per-view respip directives the action
|
||||
* can only be direct (i.e. not tag-based) */
|
||||
action = raddr->action;
|
||||
|
|
@ -962,7 +926,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
|||
}
|
||||
}
|
||||
if(!raddr && (raddr = respip_addr_lookup(rep, ipset,
|
||||
&rrset_id))) {
|
||||
&rrset_id, &rr_id))) {
|
||||
action = (enum respip_action)local_data_find_tag_action(
|
||||
raddr->taglist, raddr->taglen, ctaglist, ctaglen,
|
||||
tag_actions, tag_actions_size,
|
||||
|
|
@ -976,7 +940,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
|||
if(!r->taglist || taglist_intersect(r->taglist,
|
||||
r->taglistlen, ctaglist, ctaglen)) {
|
||||
if((raddr = respip_addr_lookup(rep,
|
||||
r->respip_set, &rrset_id))) {
|
||||
r->respip_set, &rrset_id, &rr_id))) {
|
||||
if(!respip_use_rpz(raddr, r, &action, &data,
|
||||
&rpz_log, &log_name, &rpz_cname_override,
|
||||
region, &rpz_used)) {
|
||||
|
|
@ -987,6 +951,21 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
|||
return 0;
|
||||
}
|
||||
if(rpz_used) {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t ss_len = 0;
|
||||
char nm[256], ip[256];
|
||||
char qn[255+1];
|
||||
if(!rdata2sockaddr(rep->rrsets[rrset_id]->entry.data, ntohs(rep->rrsets[rrset_id]->rk.type), rr_id, &ss, &ss_len))
|
||||
snprintf(ip, sizeof(ip), "invalidRRdata");
|
||||
else
|
||||
addr_to_str(&ss, ss_len, ip, sizeof(ip));
|
||||
dname_str(qinfo->qname, qn);
|
||||
addr_to_str(&raddr->node.addr,
|
||||
raddr->node.addrlen,
|
||||
nm, sizeof(nm));
|
||||
verbose(VERB_ALGO, "respip: rpz response-ip trigger %s/%d on %s %s with action %s", nm, raddr->node.net, qn, ip, rpz_action_to_string(respip_action_to_rpz_action(action)));
|
||||
}
|
||||
/* break to make sure 'a' stays pointed
|
||||
* to used auth_zone, and keeps lock */
|
||||
break;
|
||||
|
|
@ -1209,7 +1188,7 @@ respip_merge_cname(struct reply_info* base_rep,
|
|||
if(!new_rep)
|
||||
return 0;
|
||||
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])
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -294,4 +294,7 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
|
|||
*/
|
||||
void
|
||||
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 */
|
||||
|
|
|
|||
|
|
@ -1950,6 +1950,17 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** find the apex SOA RRset, if it exists */
|
||||
struct auth_rrset* auth_zone_get_soa_rrset(struct auth_zone* z)
|
||||
{
|
||||
struct auth_data* apex;
|
||||
struct auth_rrset* soa;
|
||||
apex = az_find_name(z, z->name, z->namelen);
|
||||
if(!apex) return NULL;
|
||||
soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA);
|
||||
return soa;
|
||||
}
|
||||
|
||||
/** find serial number of zone or false if none */
|
||||
int
|
||||
auth_zone_get_serial(struct auth_zone* z, uint32_t* serial)
|
||||
|
|
|
|||
|
|
@ -636,6 +636,9 @@ int auth_zones_startprobesequence(struct auth_zones* az,
|
|||
/** read auth zone from zonefile. caller must lock zone. false on failure */
|
||||
int auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg);
|
||||
|
||||
/** find the apex SOA RRset, if it exists. NULL if no SOA RRset. */
|
||||
struct auth_rrset* auth_zone_get_soa_rrset(struct auth_zone* z);
|
||||
|
||||
/** find serial number of zone or false if none (no SOA record) */
|
||||
int auth_zone_get_serial(struct auth_zone* z, uint32_t* serial);
|
||||
|
||||
|
|
|
|||
|
|
@ -1570,6 +1570,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,
|
||||
|
|
@ -1592,7 +1601,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,
|
||||
|
|
@ -1602,9 +1613,11 @@ 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;
|
||||
if(z->soa && z->soa_negative)
|
||||
rcode = (lz_type == local_zone_truncate ? (rcode|BIT_TC) : rcode);
|
||||
if(z != NULL && z->soa && z->soa_negative)
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
z->soa_negative, 0, rcode);
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
|
||||
|
|
@ -1661,7 +1674,7 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
|||
* does not, then we should make this noerror/nodata */
|
||||
if(ld && ld->rrsets) {
|
||||
int rcode = LDNS_RCODE_NOERROR;
|
||||
if(z->soa && z->soa_negative)
|
||||
if(z != NULL && z->soa && z->soa_negative)
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
z->soa_negative, 0, rcode);
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
|
||||
|
|
@ -1860,6 +1873,7 @@ const char* local_zone_type2str(enum localzone_type t)
|
|||
case local_zone_always_deny: return "always_deny";
|
||||
case local_zone_always_null: return "always_null";
|
||||
case local_zone_noview: return "noview";
|
||||
case local_zone_truncate: return "truncate";
|
||||
case local_zone_invalid: return "invalid";
|
||||
}
|
||||
return "badtyped";
|
||||
|
|
@ -1899,6 +1913,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
|
|||
*t = local_zone_always_null;
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ enum localzone_type {
|
|||
local_zone_always_null,
|
||||
/** 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
|
||||
};
|
||||
|
|
@ -563,6 +565,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 */
|
||||
|
|
|
|||
|
|
@ -1183,6 +1183,22 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||
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
|
||||
* @param m: mesh state to send it for.
|
||||
|
|
@ -1210,6 +1226,11 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||
* null stops the mesh state remove and thus
|
||||
* reply_list modification and accounting */
|
||||
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 */
|
||||
if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
|
||||
m->s.env->cfg->ignore_cd) && rep &&
|
||||
|
|
|
|||
1750
services/rpz.c
1750
services/rpz.c
File diff suppressed because it is too large
Load diff
|
|
@ -50,6 +50,7 @@
|
|||
#include "sldns/sbuffer.h"
|
||||
#include "daemon/stats.h"
|
||||
#include "respip/respip.h"
|
||||
struct iter_qstate;
|
||||
|
||||
/**
|
||||
* RPZ triggers, only the QNAME trigger is currently supported in Unbound.
|
||||
|
|
@ -83,6 +84,27 @@ enum rpz_action {
|
|||
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
|
||||
* linked list to keep configuration order. Iterating or changing the linked
|
||||
|
|
@ -92,6 +114,9 @@ enum rpz_action {
|
|||
struct rpz {
|
||||
struct local_zones* local_zones;
|
||||
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;
|
||||
size_t taglistlen;
|
||||
enum rpz_action action_override;
|
||||
|
|
@ -151,11 +176,34 @@ void rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
|
|||
* @param stats: worker stats struct
|
||||
* @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 regional* temp, struct comm_reply* repinfo,
|
||||
uint8_t* taglist, size_t taglen, struct ub_server_stats* stats);
|
||||
|
||||
/**
|
||||
* Callback to process when the iterator module is about to send queries.
|
||||
* Checks for nsip and nsdname triggers.
|
||||
* @param qstate: the query state.
|
||||
* @param iq: iterator module query state.
|
||||
* @return NULL if nothing is done. Or a new message with the contents from
|
||||
* the rpz, based on the delegation point. It is allocated in the
|
||||
* qstate region.
|
||||
*/
|
||||
struct dns_msg* rpz_callback_from_iterator_module(struct module_qstate* qstate,
|
||||
struct iter_qstate* iq);
|
||||
|
||||
/**
|
||||
* Callback to process when the iterator module has followed a cname.
|
||||
* There can be a qname trigger for the new query name.
|
||||
* @param qstate: the query state.
|
||||
* @param iq: iterator module query state.
|
||||
* @return NULL if nothing is done. Or a new message with the contents from
|
||||
* the rpz, based on the iq.qchase. It is allocated in the qstate region.
|
||||
*/
|
||||
struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* qstate,
|
||||
struct iter_qstate* iq);
|
||||
|
||||
/**
|
||||
* Delete RPZ
|
||||
* @param r: RPZ struct to delete
|
||||
|
|
|
|||
264
testdata/rpz_clientip.rpl
vendored
Normal file
264
testdata/rpz_clientip.rpl
vendored
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
; config options
|
||||
server:
|
||||
module-config: "respip validator iterator"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: no
|
||||
minimal-responses: 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
|
||||
SECTION ADDITIONAL
|
||||
rpz.example.com. 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. ( 1379078166 28800 7200 604800 7200 )
|
||||
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"
|
||||
SECTION ADDITIONAL
|
||||
rpz.example.com. 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. ( 1379078166 28800 7200 604800 7200 )
|
||||
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
|
||||
SECTION ADDITIONAL
|
||||
rpz.example.com. 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. ( 1379078166 28800 7200 604800 7200 )
|
||||
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
|
||||
390
testdata/rpz_nsdname.rpl
vendored
Normal file
390
testdata/rpz_nsdname.rpl
vendored
Normal file
|
|
@ -0,0 +1,390 @@
|
|||
; 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."
|
||||
rpz-log: yes
|
||||
rpz-log-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.
|
||||
ns1.gotham.aa.rpz-nsdname CNAME .
|
||||
ns1.gotham.bb.rpz-nsdname CNAME *.
|
||||
ns1.gotham.cc.rpz-nsdname CNAME rpz-drop.
|
||||
ns1.gotham.com.rpz-nsdname CNAME rpz-passthru.
|
||||
ns1.gotham.dd.rpz-nsdname CNAME rpz-tcp-only.
|
||||
ns1.gotham.ff.rpz-nsdname A 127.0.0.1
|
||||
ns1.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 AA 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 AA NOERROR
|
||||
SECTION QUESTION
|
||||
gotham.ff. IN A
|
||||
SECTION ANSWER
|
||||
gotham.ff. IN A 127.0.0.1
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
408
testdata/rpz_nsip.rpl
vendored
Normal file
408
testdata/rpz_nsip.rpl
vendored
Normal file
|
|
@ -0,0 +1,408 @@
|
|||
; 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."
|
||||
rpz-log: yes
|
||||
rpz-log-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 AA 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 AA NOERROR
|
||||
SECTION QUESTION
|
||||
gotham.ff. IN A
|
||||
SECTION ANSWER
|
||||
gotham.ff. IN A 127.0.0.1
|
||||
ENTRY_END
|
||||
|
||||
; again with more cache items
|
||||
STEP 40 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
gotham.ff. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 41 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
gotham.ff. IN A
|
||||
SECTION ANSWER
|
||||
gotham.ff. IN A 127.0.0.1
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
104
testdata/rpz_qname.rpl
vendored
104
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:
|
||||
|
|
@ -46,12 +47,15 @@ stub-zone:
|
|||
stub-zone:
|
||||
name: "example."
|
||||
stub-addr: 10.20.30.50
|
||||
stub-zone:
|
||||
name: "tcp."
|
||||
stub-addr: 10.20.30.60
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test all support RPZ action for QNAME trigger
|
||||
|
||||
; a.
|
||||
RANGE_BEGIN 0 100
|
||||
RANGE_BEGIN 0 1000
|
||||
ADDRESS 10.20.30.40
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
|
|
@ -88,7 +92,7 @@ ENTRY_END
|
|||
RANGE_END
|
||||
|
||||
; example.
|
||||
RANGE_BEGIN 0 100
|
||||
RANGE_BEGIN 0 1000
|
||||
ADDRESS 10.20.30.50
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
|
|
@ -122,6 +126,42 @@ SECTION ANSWER
|
|||
something.e.b.example. IN TXT "*.b.example. answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
f.example. IN TXT
|
||||
SECTION ANSWER
|
||||
f.example. IN CNAME d.
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
; tcp.
|
||||
RANGE_BEGIN 0 1000
|
||||
ADDRESS 10.20.30.60
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
tcp. IN NS
|
||||
SECTION ANSWER
|
||||
tcp. IN NS ns.example.
|
||||
SECTION ADDITIONAL
|
||||
ns.tcp IN A 10.20.30.60
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
tcp. IN TXT
|
||||
SECTION ANSWER
|
||||
tcp. IN TXT "tcp. answer from upstream ns"
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 10 QUERY
|
||||
|
|
@ -295,10 +335,66 @@ 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
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
drop. IN TXT
|
||||
tcp. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 96 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA TC NOERROR
|
||||
SECTION QUESTION
|
||||
tcp. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 97 QUERY
|
||||
ENTRY_BEGIN
|
||||
MATCH TCP
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
tcp. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 98 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all TCP
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
tcp. IN TXT
|
||||
SECTION ANSWER
|
||||
tcp. IN TXT "tcp. answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
; check if the name after the CNAME has the qname trigger applied to it.
|
||||
STEP 100 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
f.example. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 101 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
f.example. IN TXT
|
||||
SECTION ANSWER
|
||||
f.example. IN CNAME d.
|
||||
d. IN TXT "local data 2nd zone"
|
||||
ENTRY_END
|
||||
|
||||
; no answer is checked at exit of testbound.
|
||||
SCENARIO_END
|
||||
|
|
|
|||
117
testdata/rpz_qname_tcponly.rpl
vendored
Normal file
117
testdata/rpz_qname_tcponly.rpl
vendored
Normal 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
|
||||
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
|
||||
|
|
|
|||
207
testdata/rpz_respip_tcponly.rpl
vendored
Normal file
207
testdata/rpz_respip_tcponly.rpl
vendored
Normal 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
|
||||
|
|
@ -166,6 +166,32 @@ reply_info_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc,
|
|||
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 */
|
||||
static time_t
|
||||
soa_find_minttl(struct rr_parse* rr)
|
||||
|
|
|
|||
|
|
@ -382,6 +382,21 @@ struct reply_info* reply_info_copy(struct reply_info* rep,
|
|||
int reply_info_alloc_rrset_keys(struct reply_info* rep,
|
||||
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.
|
||||
* @param pkt: packet for decompression
|
||||
|
|
|
|||
|
|
@ -61,6 +61,13 @@ typedef uint64_t rrset_id_type;
|
|||
* updated on encoding in a reply. This flag is not expected to be set in
|
||||
* cached data. */
|
||||
#define PACKED_RRSET_FIXEDTTL 0x80000000
|
||||
/** This rrset is from RPZ. It is not real, it is synthesized data to block
|
||||
* access. The flag makes lookups, from cache in iterator, ignore the fake
|
||||
* items and only use actual data. Eg. when the iterator looksup NS, CNAME,
|
||||
* A and AAAA types, it then gets items without this flag that are the
|
||||
* actual network. But messages with these records in it can be stored in
|
||||
* the cache and retrieved for a reply. */
|
||||
#define PACKED_RRSET_RPZ 0x8
|
||||
|
||||
/** number of rrs and rrsets for integer overflow protection. More than
|
||||
* this is not really possible (64K packet has much less RRs and RRsets) in
|
||||
|
|
@ -88,6 +95,7 @@ struct packed_rrset_key {
|
|||
* o PACKED_RRSET_PARENT_SIDE
|
||||
* o PACKED_RRSET_SOA_NEG
|
||||
* o PACKED_RRSET_FIXEDTTL (not supposed to be cached)
|
||||
* o PACKED_RRSET_RPZ
|
||||
*/
|
||||
uint32_t flags;
|
||||
/** the rrset type in network format */
|
||||
|
|
|
|||
Loading…
Reference in a new issue