processing RPZ review feedback

This commit is contained in:
Ralph Dolmans 2019-11-22 12:56:24 +08:00
parent f3dfb4d537
commit bbb737ca5a
8 changed files with 54 additions and 24 deletions

View file

@ -1009,12 +1009,15 @@ remote-control:
# Response Policy Zones # Response Policy Zones
# RPZ policies. Applied in order of configuration. QNAME and Response IP # RPZ policies. Applied in order of configuration. QNAME and Response IP
# Address trigger are the only supported triggers. Supported actions are: # Address trigger are the only supported triggers. Supported actions are:
# NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. Polices can be loaded from # NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. Policies can be loaded from
# file or using zone transfer. The respip module needs to be added to the # file, using zone transfer, or using HTTP. The respip module needs to be added
# module-config, e.g.: module-config: "respip validator iterator". # to the module-config, e.g.: module-config: "respip validator iterator".
# rpz: # rpz:
# name: "rpz.example.com" # name: "rpz.example.com"
# zonefile: "rpz.example.com" # zonefile: "rpz.example.com"
# master: 192.0.2.0
# allow-notify: 192.0.2.0/32
# url: http://www.example.com/rpz.example.org.zone
# rpz-action-override: cname # rpz-action-override: cname
# rpz-cname-override: www.example.org # rpz-cname-override: www.example.org
# rpz-log: yes # rpz-log: yes

View file

@ -660,6 +660,11 @@ Number of queries that got an answer that contained EDNS client subnet data.
Number of queries answered from the edns client subnet cache. These are Number of queries answered from the edns client subnet cache. These are
counted as cachemiss by the main counters, but hit the client subnet counted as cachemiss by the main counters, but hit the client subnet
specific cache, after getting processed by the edns client subnet module. 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.
.SH "FILES" .SH "FILES"
.TP .TP
.I @ub_conf_file@ .I @ub_conf_file@

View file

@ -2100,6 +2100,17 @@ Name of the authority zone.
Where to download a copy of the zone from, with AXFR and IXFR. Multiple Where to download a copy of the zone from, with AXFR and IXFR. Multiple
masters can be specified. They are all tried if one fails. masters can be specified. They are all tried if one fails.
.TP .TP
.B url: \fI<url to zonefile>
Where to download a zonefile for the zone. With http or https. An example
for the url is "http://www.example.com/example.org.zone". Multiple url
statements can be given, they are tried in turn. If only urls are given
the SOA refresh timer is used to wait for making new downloads. If also
masters are listed, the masters are first probed with UDP SOA queries to
see if the SOA serial number has changed, reducing the number of downloads.
If none of the urls work, the masters are tried with IXFR and AXFR.
For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
to authenticate the connection.
.TP
.B allow\-notify: \fI<IP address or host name or netblockIP/prefix> .B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
With allow\-notify you can specify additional sources of notifies. With allow\-notify you can specify additional sources of notifies.
When notified, the server attempts to first probe and then zone transfer. When notified, the server attempts to first probe and then zone transfer.
@ -2122,7 +2133,7 @@ The CNAME target domain to use if the cname action is configured for
\fBrpz\-action\-override\fR. \fBrpz\-action\-override\fR.
.TP .TP
.B rpz\-log: \fI<yes or no> .B rpz\-log: \fI<yes or no>
Log all applied RPZ actions. Default is no. Log all applied RPZ actions for this RPZ zone. Default is no.
.TP .TP
.B rpz\-log\-name: \fI<name> .B rpz\-log\-name: \fI<name>
Specify a string to be part of the log line, for easy referencing. Specify a string to be part of the log line, for easy referencing.

View file

@ -55,7 +55,7 @@
int int
context_finalize(struct ub_ctx* ctx) context_finalize(struct ub_ctx* ctx)
{ {
int is_rpz; int is_rpz = 0;
struct config_file* cfg = ctx->env->cfg; struct config_file* cfg = ctx->env->cfg;
verbosity = cfg->verbosity; verbosity = cfg->verbosity;
if(ctx_logfile_overridden && !ctx->logfile_override) { if(ctx_logfile_overridden && !ctx->logfile_override) {

View file

@ -845,10 +845,11 @@ static int
respip_use_rpz(struct resp_addr* raddr, struct rpz* r, respip_use_rpz(struct resp_addr* raddr, struct rpz* r,
enum respip_action* action, enum respip_action* action,
struct ub_packed_rrset_key** data, int* rpz_log, char** log_name, struct ub_packed_rrset_key** data, int* rpz_log, char** log_name,
int* rpz_cname_override, struct regional* region) int* rpz_cname_override, struct regional* region, int* is_rpz)
{ {
if(r->action_override == RPZ_DISABLED_ACTION) { if(r->action_override == RPZ_DISABLED_ACTION) {
return 0; *is_rpz = 0;
return 1;
} }
else if(r->action_override == RPZ_NO_OVERRIDE_ACTION) else if(r->action_override == RPZ_NO_OVERRIDE_ACTION)
*action = raddr->action; *action = raddr->action;
@ -861,7 +862,9 @@ respip_use_rpz(struct resp_addr* raddr, struct rpz* r,
} }
*rpz_log = r->log; *rpz_log = r->log;
if(r->log_name) if(r->log_name)
*log_name = regional_strdup(region, r->log_name); if(!(*log_name = regional_strdup(region, r->log_name)))
return 0;
*is_rpz = 1;
return 1; return 1;
} }
@ -945,12 +948,16 @@ respip_rewrite_reply(const struct query_info* qinfo,
if(raddr) { if(raddr) {
if(!respip_use_rpz(raddr, r, &action, &data, if(!respip_use_rpz(raddr, r, &action, &data,
&rpz_log, &log_name, &rpz_cname_override, &rpz_log, &log_name, &rpz_cname_override,
region)) { region, &rpz_used)) {
log_err("out of memory");
lock_rw_unlock(&raddr->lock);
return 0;
}
if(!rpz_used) {
lock_rw_unlock(&raddr->lock); lock_rw_unlock(&raddr->lock);
raddr = NULL; raddr = NULL;
actinfo->rpz_disabled++; actinfo->rpz_disabled++;
} }
rpz_used = 1;
} }
} }
} }
@ -1263,7 +1270,7 @@ respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
unsigned port; unsigned port;
struct respip_addr_info* respip_addr = respip_actinfo->addrinfo; struct respip_addr_info* respip_addr = respip_actinfo->addrinfo;
size_t txtlen = 0; size_t txtlen = 0;
char* actionstr = NULL; const char* actionstr = NULL;
if(local_alias) if(local_alias)
qname = local_alias->rrset->rk.dname; qname = local_alias->rrset->rk.dname;
@ -1277,12 +1284,12 @@ respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen, "%s", txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen, "%s",
"RPZ applied "); "RPZ applied ");
if(respip_actinfo->rpz_cname_override) if(respip_actinfo->rpz_cname_override)
actionstr = strdup( actionstr = rpz_action_to_string(
rpz_action_to_string(RPZ_CNAME_OVERRIDE_ACTION)); RPZ_CNAME_OVERRIDE_ACTION);
else else
actionstr = strdup(rpz_action_to_string( actionstr = rpz_action_to_string(
respip_action_to_rpz_action( respip_action_to_rpz_action(
respip_actinfo->action))); respip_actinfo->action));
} }
if(respip_actinfo->log_name) { if(respip_actinfo->log_name) {
txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen, txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen,
@ -1291,7 +1298,5 @@ respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
snprintf(txt+txtlen, sizeof(txt)-txtlen, snprintf(txt+txtlen, sizeof(txt)-txtlen,
"%s/%d %s %s@%u", respip, respip_addr->net, "%s/%d %s %s@%u", respip, respip_addr->net,
(actionstr) ? actionstr : "inform", srcip, port); (actionstr) ? actionstr : "inform", srcip, port);
if(actionstr)
free(actionstr);
log_nametypeclass(0, txt, qname, qtype, qclass); log_nametypeclass(0, txt, qname, qtype, qclass);
} }

View file

@ -270,7 +270,7 @@ respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage*
socklen_t addrlen, int net, int create, const char* ipstr); socklen_t addrlen, int net, int create, const char* ipstr);
/** /**
* Add RR to resp_addr's RRset. Create RRset is not existing. * Add RR to resp_addr's RRset. Create RRset if not existing.
* @param region: region to alloc RR(set). * @param region: region to alloc RR(set).
* @param raddr: resp_addr containing RRset. Must hold write lock. * @param raddr: resp_addr containing RRset. Must hold write lock.
* @param rrtype: RR type. * @param rrtype: RR type.
@ -290,7 +290,7 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
/** /**
* Delete resp_addr node from tree. * Delete resp_addr node from tree.
* @param set: struct containing tree. Must hold write lock. * @param set: struct containing tree. Must hold write lock.
* @param node: node to delete. Must hold write lock. * @param node: node to delete. Not locked.
*/ */
void void
respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node); respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node);

View file

@ -791,12 +791,9 @@ rpz_remove_response_ip_trigger(struct rpz* r, uint8_t* dname, enum rpz_action a,
delete_respip = rpz_rrset_delete_rr(node, rr_type, rdatawl, delete_respip = rpz_rrset_delete_rr(node, rr_type, rdatawl,
rdatalen); rdatalen);
} }
if(delete_respip) { lock_rw_unlock(&node->lock);
/* delete + reset parent pointers */ if(delete_respip)
respip_sockaddr_delete(r->respip_set, node); respip_sockaddr_delete(r->respip_set, node);
} else {
lock_rw_unlock(&node->lock);
}
lock_rw_unlock(&r->respip_set->lock); lock_rw_unlock(&r->respip_set->lock);
} }

View file

@ -62,6 +62,7 @@
#include "daemon/stats.h" #include "daemon/stats.h"
#include "sldns/wire2str.h" #include "sldns/wire2str.h"
#include "sldns/pkthdr.h" #include "sldns/pkthdr.h"
#include "services/rpz.h"
#ifdef HAVE_SYS_IPC_H #ifdef HAVE_SYS_IPC_H
#include "sys/ipc.h" #include "sys/ipc.h"
@ -372,6 +373,14 @@ static void print_extended(struct ub_stats_info* s)
PR_UL("rrset.cache.count", s->svr.rrset_cache_count); PR_UL("rrset.cache.count", s->svr.rrset_cache_count);
PR_UL("infra.cache.count", s->svr.infra_cache_count); PR_UL("infra.cache.count", s->svr.infra_cache_count);
PR_UL("key.cache.count", s->svr.key_cache_count); PR_UL("key.cache.count", s->svr.key_cache_count);
/* applied RPZ actions */
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++) {
if((enum rpz_action)s->svr.rpz_action[i] == RPZ_NO_OVERRIDE_ACTION)
continue;
if(inhibit_zero && s->svr.rpz_action[i] == 0)
continue;
PR_UL_SUB("num.rpz.action", rpz_action_to_string(i), s->svr.rpz_action[i]);
}
#ifdef USE_DNSCRYPT #ifdef USE_DNSCRYPT
PR_UL("dnscrypt_shared_secret.cache.count", PR_UL("dnscrypt_shared_secret.cache.count",
s->svr.shared_secret_cache_count); s->svr.shared_secret_cache_count);