# 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. Polices can be loaded from
-# file or using zone transfer. The respip module needs to be added to the
-# module-config, e.g.: module-config: "respip validator iterator".
+# 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
+# to the module-config, e.g.: module-config: "respip validator iterator".
# rpz:
# name: "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-cname-override: www.example.org
# rpz-log: yes
Number of queries answered from the edns client subnet cache. These are
counted as cachemiss by the main counters, but hit the client subnet
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"
.TP
.I @ub_conf_file@
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.
.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>
With allow\-notify you can specify additional sources of notifies.
When notified, the server attempts to first probe and then zone transfer.
\fBrpz\-action\-override\fR.
.TP
.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
.B rpz\-log\-name: \fI<name>
Specify a string to be part of the log line, for easy referencing.
int
context_finalize(struct ub_ctx* ctx)
{
- int is_rpz;
+ int is_rpz = 0;
struct config_file* cfg = ctx->env->cfg;
verbosity = cfg->verbosity;
if(ctx_logfile_overridden && !ctx->logfile_override) {
respip_use_rpz(struct resp_addr* raddr, struct rpz* r,
enum respip_action* action,
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) {
- return 0;
+ *is_rpz = 0;
+ return 1;
}
else if(r->action_override == RPZ_NO_OVERRIDE_ACTION)
*action = raddr->action;
}
*rpz_log = r->log;
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;
}
if(raddr) {
if(!respip_use_rpz(raddr, r, &action, &data,
&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);
raddr = NULL;
actinfo->rpz_disabled++;
}
- rpz_used = 1;
}
}
}
unsigned port;
struct respip_addr_info* respip_addr = respip_actinfo->addrinfo;
size_t txtlen = 0;
- char* actionstr = NULL;
+ const char* actionstr = NULL;
if(local_alias)
qname = local_alias->rrset->rk.dname;
txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen, "%s",
"RPZ applied ");
if(respip_actinfo->rpz_cname_override)
- actionstr = strdup(
- rpz_action_to_string(RPZ_CNAME_OVERRIDE_ACTION));
+ actionstr = rpz_action_to_string(
+ RPZ_CNAME_OVERRIDE_ACTION);
else
- actionstr = strdup(rpz_action_to_string(
+ actionstr = rpz_action_to_string(
respip_action_to_rpz_action(
- respip_actinfo->action)));
+ respip_actinfo->action));
}
if(respip_actinfo->log_name) {
txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen,
snprintf(txt+txtlen, sizeof(txt)-txtlen,
"%s/%d %s %s@%u", respip, respip_addr->net,
(actionstr) ? actionstr : "inform", srcip, port);
- if(actionstr)
- free(actionstr);
log_nametypeclass(0, txt, qname, qtype, qclass);
}
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 raddr: resp_addr containing RRset. Must hold write lock.
* @param rrtype: RR type.
/**
* Delete resp_addr node from tree.
* @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
respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node);
delete_respip = rpz_rrset_delete_rr(node, rr_type, rdatawl,
rdatalen);
}
- if(delete_respip) {
- /* delete + reset parent pointers */
+ lock_rw_unlock(&node->lock);
+ if(delete_respip)
respip_sockaddr_delete(r->respip_set, node);
- } else {
- lock_rw_unlock(&node->lock);
- }
lock_rw_unlock(&r->respip_set->lock);
}
#include "daemon/stats.h"
#include "sldns/wire2str.h"
#include "sldns/pkthdr.h"
+#include "services/rpz.h"
#ifdef HAVE_SYS_IPC_H
#include "sys/ipc.h"
PR_UL("rrset.cache.count", s->svr.rrset_cache_count);
PR_UL("infra.cache.count", s->svr.infra_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
PR_UL("dnscrypt_shared_secret.cache.count",
s->svr.shared_secret_cache_count);