]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
processing RPZ review feedback
authorRalph Dolmans <ralph@nlnetlabs.nl>
Fri, 22 Nov 2019 04:56:24 +0000 (12:56 +0800)
committerRalph Dolmans <ralph@nlnetlabs.nl>
Fri, 22 Nov 2019 04:56:24 +0000 (12:56 +0800)
doc/example.conf.in
doc/unbound-control.8.in
doc/unbound.conf.5.in
libunbound/context.c
respip/respip.c
respip/respip.h
services/rpz.c
smallapp/unbound-control.c

index bd6c0e03e36b5248ab6f4c669f5d9b767392fa39..b30dca51326b553eeb51bb29186cf5b38054c502 100644 (file)
@@ -1009,12 +1009,15 @@ remote-control:
 # 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
index 6ea40009cfb14b162363966dc89048b9f0bbd91d..37f88abf76ee4504d2fa49c121bb252f6d363845 100644 (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
 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@
index 0a7e75db45b63543e0e9469cefdb6a84a5dac311..3a649f450f6e72a7bd16ee6fa9015de654c25e81 100644 (file)
@@ -2100,6 +2100,17 @@ Name of the authority zone.
 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.
@@ -2122,7 +2133,7 @@ The CNAME target domain to use if the cname action is configured for
 \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.
index d96722263c78e5f56122d39d1313756356371b43..6d62e32b50fdd5d9e977bdb569bbfdf77fbc684a 100644 (file)
@@ -55,7 +55,7 @@
 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) {
index 5da60ad0e6135eeff2f36b6d12517bd71ba0f05b..e9baa629250f46911fefcf3d6861e2f1d377019a 100644 (file)
@@ -845,10 +845,11 @@ static int
 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;
@@ -861,7 +862,9 @@ respip_use_rpz(struct resp_addr* raddr, struct rpz* r,
        }
        *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;
 }
 
@@ -945,12 +948,16 @@ respip_rewrite_reply(const struct query_info* qinfo,
                        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;
                        }
                }       
        }
@@ -1263,7 +1270,7 @@ respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
        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;
@@ -1277,12 +1284,12 @@ respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
                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,
@@ -1291,7 +1298,5 @@ respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
        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);
 }
index 4a56b8d29f2bbd83dba6baa462d95b3af80f33a2..bbd471421c1ee0faad8a1cc3451a7306b0196245 100644 (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);
 
 /**
- * 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.
@@ -290,7 +290,7 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
 /**
  * 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);
index b9fc03211909426792d7b19d57087d709d336c58..d36f2268eab55cf3d938a615272702fb36e1bda2 100644 (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, 
                        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);
 }
 
index 01e2385faab71331c5c066ef2f2f5a22a2bb24e3..c5aae7a8cd15d12365e912e0dfbb8ab68b24b971 100644 (file)
@@ -62,6 +62,7 @@
 #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"
@@ -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("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);