Home | History | Annotate | Line # | Download | only in services
      1 /*
      2  * services/rpz.h - rpz service
      3  *
      4  * Copyright (c) 2019, NLnet Labs. All rights reserved.
      5  *
      6  * This software is open source.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * Redistributions of source code must retain the above copyright notice,
     13  * this list of conditions and the following disclaimer.
     14  *
     15  * Redistributions in binary form must reproduce the above copyright notice,
     16  * this list of conditions and the following disclaimer in the documentation
     17  * and/or other materials provided with the distribution.
     18  *
     19  * Neither the name of the NLNET LABS nor the names of its contributors may
     20  * be used to endorse or promote products derived from this software without
     21  * specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
     29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34  */
     35 
     36 /**
     37  * \file
     38  *
     39  * This file contains functions to enable RPZ service.
     40  */
     41 
     42 #ifndef SERVICES_RPZ_H
     43 #define SERVICES_RPZ_H
     44 
     45 #include "services/localzone.h"
     46 #include "util/locks.h"
     47 #include "util/log.h"
     48 #include "util/config_file.h"
     49 #include "services/authzone.h"
     50 #include "sldns/sbuffer.h"
     51 #include "daemon/stats.h"
     52 #include "respip/respip.h"
     53 struct iter_qstate;
     54 
     55 /**
     56  * RPZ triggers, only the QNAME trigger is currently supported in Unbound.
     57  */
     58 enum rpz_trigger {
     59 	RPZ_QNAME_TRIGGER = 0,
     60 	/* unsupported triggers */
     61 	RPZ_CLIENT_IP_TRIGGER,	 /* rpz-client-ip */
     62 	RPZ_RESPONSE_IP_TRIGGER, /* rpz-ip */
     63 	RPZ_NSDNAME_TRIGGER,	 /* rpz-nsdname */
     64 	RPZ_NSIP_TRIGGER,	 /* rpz-nsip */
     65 	RPZ_INVALID_TRIGGER, 	 /* dname does not contain valid trigger */
     66 };
     67 
     68 /**
     69  * RPZ actions.
     70  */
     71 enum rpz_action {
     72 	RPZ_NXDOMAIN_ACTION = 0,/* CNAME . */
     73 	RPZ_NODATA_ACTION,	/* CNAME *. */
     74 	RPZ_PASSTHRU_ACTION,	/* CNAME rpz-passthru. */
     75 	RPZ_DROP_ACTION,	/* CNAME rpz-drop. */
     76 	RPZ_TCP_ONLY_ACTION,	/* CNAME rpz-tcp-only. */
     77 	RPZ_INVALID_ACTION,	/* CNAME with (child of) TLD starting with
     78 				   "rpz-" in target, SOA, NS, DNAME and
     79 				   DNSSEC-related records. */
     80 	RPZ_LOCAL_DATA_ACTION,	/* anything else */
     81 	/* RPZ override actions */
     82 	RPZ_DISABLED_ACTION,    /* RPZ action disabled using override */
     83 	RPZ_NO_OVERRIDE_ACTION, /* RPZ action no override*/
     84 	RPZ_CNAME_OVERRIDE_ACTION, /* RPZ CNAME action override*/
     85 };
     86 
     87 struct clientip_synthesized_rrset {
     88 	struct regional* region;
     89 	struct rbtree_type entries;
     90 	/** lock on the entries tree */
     91 	lock_rw_type lock;
     92 };
     93 
     94 struct clientip_synthesized_rr {
     95 	/** node in address tree */
     96 	struct addr_tree_node node;
     97 	/** lock on the node item */
     98 	lock_rw_type lock;
     99 	/** action for this address span */
    100 	enum rpz_action action;
    101 	/** "local data" for this node */
    102 	struct local_rrset* data;
    103 };
    104 
    105 /**
    106  * RPZ containing policies. Pointed to from corresponding auth-zone. Part of a
    107  * linked list to keep configuration order. Iterating or changing the linked
    108  * list requires the rpz_lock from struct auth_zones. Changing items in this
    109  * struct require the lock from struct auth_zone.
    110  */
    111 struct rpz {
    112 	struct local_zones* local_zones;
    113 	struct respip_set* respip_set;
    114 	struct clientip_synthesized_rrset* client_set;
    115 	struct clientip_synthesized_rrset* ns_set;
    116 	struct local_zones* nsdname_zones;
    117 	uint8_t* taglist;
    118 	size_t taglistlen;
    119 	enum rpz_action action_override;
    120 	struct ub_packed_rrset_key* cname_override;
    121 	int log;
    122 	char* log_name;
    123 	/** signal NXDOMAIN blocked with unset RA flag */
    124 	int signal_nxdomain_ra;
    125 	struct regional* region;
    126 	int disabled;
    127 };
    128 
    129 /**
    130  * Create policy from RR and add to this RPZ.
    131  * @param r: the rpz to add the policy to.
    132  * @param azname: dname of the auth-zone
    133  * @param aznamelen: the length of the auth-zone name
    134  * @param dname: dname of the RR
    135  * @param dnamelen: length of the dname
    136  * @param rr_type: RR type of the RR
    137  * @param rr_class: RR class of the RR
    138  * @param rr_ttl: TTL of the RR
    139  * @param rdatawl: rdata of the RR, prepended with the rdata size
    140  * @param rdatalen: length if the RR, including the prepended rdata size
    141  * @param rr: the complete RR, for logging purposes
    142  * @param rr_len: the length of the complete RR
    143  * @return: 0 on error
    144  */
    145 int rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
    146 	size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
    147 	uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len);
    148 
    149 /**
    150  * Delete policy matching RR, used for IXFR.
    151  * @param r: the rpz to add the policy to.
    152  * @param azname: dname of the auth-zone
    153  * @param aznamelen: the length of the auth-zone name
    154  * @param dname: dname of the RR
    155  * @param dnamelen: length of the dname
    156  * @param rr_type: RR type of the RR
    157  * @param rr_class: RR class of the RR
    158  * @param rdatawl: rdata of the RR, prepended with the rdata size
    159  * @param rdatalen: length if the RR, including the prepended rdata size
    160  */
    161 void rpz_remove_rr(struct rpz* r, uint8_t* azname, size_t aznamelen,
    162 	uint8_t* dname, size_t dnamelen, uint16_t rr_type, uint16_t rr_class,
    163 	uint8_t* rdatawl, size_t rdatalen);
    164 
    165 /**
    166  * Walk over the RPZ zones to find and apply a QNAME trigger policy.
    167  * @param az: auth_zones struct, containing first RPZ item and RPZ lock
    168  * @param env: module env
    169  * @param qinfo: qinfo containing qname and qtype
    170  * @param edns: edns data
    171  * @param buf: buffer to write answer to
    172  * @param temp: scratchpad
    173  * @param repinfo: reply info
    174  * @param taglist: taglist to lookup.
    175  * @param taglen: length of taglist.
    176  * @param stats: worker stats struct
    177  * @param passthru: returns if the query can passthru further rpz processing.
    178  * @return: 1 if client answer is ready, 0 to continue resolving
    179  */
    180 int rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
    181 	struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
    182 	struct regional* temp, struct comm_reply* repinfo,
    183 	uint8_t* taglist, size_t taglen, struct ub_server_stats* stats,
    184 	int* passthru);
    185 
    186 /**
    187  * Callback to process when the iterator module is about to send queries.
    188  * Checks for nsip and nsdname triggers.
    189  * @param qstate: the query state.
    190  * @param iq: iterator module query state.
    191  * @return NULL if nothing is done. Or a new message with the contents from
    192  * 	the rpz, based on the delegation point. It is allocated in the
    193  * 	qstate region.
    194  */
    195 struct dns_msg* rpz_callback_from_iterator_module(struct module_qstate* qstate,
    196 	struct iter_qstate* iq);
    197 
    198 /**
    199  * Callback to process when the iterator module has followed a cname.
    200  * There can be a qname trigger for the new query name.
    201  * @param qstate: the query state.
    202  * @param iq: iterator module query state.
    203  * @return NULL if nothing is done. Or a new message with the contents from
    204  * 	the rpz, based on the iq.qchase. It is allocated in the qstate region.
    205  */
    206 struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* qstate,
    207 	struct iter_qstate* iq);
    208 
    209 /**
    210  * Delete RPZ
    211  * @param r: RPZ struct to delete
    212  */
    213 void rpz_delete(struct rpz* r);
    214 
    215 /**
    216  * Clear local-zones and respip data in RPZ, used after reloading file or
    217  * AXFR/HTTP transfer.
    218  * @param r: RPZ to use
    219  */
    220 int rpz_clear(struct rpz* r);
    221 
    222 /**
    223  * Create RPZ. RPZ must be added to linked list after creation.
    224  * @return: the newly created RPZ
    225  */
    226 struct rpz* rpz_create(struct config_auth* p);
    227 
    228 /**
    229  * Change config on rpz, after reload.
    230  * @param r: the rpz structure.
    231  * @param p: the config that was read.
    232  * @return false on failure.
    233  */
    234 int rpz_config(struct rpz* r, struct config_auth* p);
    235 
    236 /**
    237  * String for RPZ action enum
    238  * @param a: RPZ action to get string for
    239  * @return: string for RPZ action
    240  */
    241 const char* rpz_action_to_string(enum rpz_action a);
    242 
    243 enum rpz_action
    244 respip_action_to_rpz_action(enum respip_action a);
    245 
    246 /**
    247  * Prepare RPZ after processing feed content.
    248  * @param r: RPZ to use
    249  */
    250 void rpz_finish_config(struct rpz* r);
    251 
    252 /**
    253  * Classify respip action for RPZ action
    254  * @param a: RPZ action
    255  * @return: the respip action
    256  */
    257 enum respip_action
    258 rpz_action_to_respip_action(enum rpz_action a);
    259 
    260 /**
    261  * Enable RPZ
    262  * @param r: RPZ struct to enable
    263  */
    264 void rpz_enable(struct rpz* r);
    265 
    266 /**
    267  * Disable RPZ
    268  * @param r: RPZ struct to disable
    269  */
    270 void rpz_disable(struct rpz* r);
    271 
    272 /**
    273  * Get memory usage of rpz. Caller must manage locks.
    274  * @param r: RPZ struct.
    275  * @return memory usage.
    276  */
    277 size_t rpz_get_mem(struct rpz* r);
    278 
    279 #endif /* SERVICES_RPZ_H */
    280