xref: /netbsd-src/external/mpl/bind/dist/lib/dns/include/dns/rpz.h (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: rpz.h,v 1.12 2025/01/26 16:25:28 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 #pragma once
17 
18 /* Add -DDNS_RPZ_TRACE=1 to CFLAGS for detailed reference tracing */
19 
20 #include <inttypes.h>
21 #include <stdbool.h>
22 
23 #include <isc/ht.h>
24 #include <isc/lang.h>
25 #include <isc/refcount.h>
26 #include <isc/rwlock.h>
27 #include <isc/time.h>
28 #include <isc/timer.h>
29 
30 #include <dns/fixedname.h>
31 #include <dns/qp.h>
32 #include <dns/rdata.h>
33 #include <dns/types.h>
34 
35 ISC_LANG_BEGINDECLS
36 
37 #define DNS_RPZ_PREFIX "rpz-"
38 /*
39  * Sub-zones of various trigger types.
40  */
41 #define DNS_RPZ_CLIENT_IP_ZONE DNS_RPZ_PREFIX "client-ip"
42 #define DNS_RPZ_IP_ZONE	       DNS_RPZ_PREFIX "ip"
43 #define DNS_RPZ_NSIP_ZONE      DNS_RPZ_PREFIX "nsip"
44 #define DNS_RPZ_NSDNAME_ZONE   DNS_RPZ_PREFIX "nsdname"
45 /*
46  * Special policies.
47  */
48 #define DNS_RPZ_PASSTHRU_NAME DNS_RPZ_PREFIX "passthru"
49 #define DNS_RPZ_DROP_NAME     DNS_RPZ_PREFIX "drop"
50 #define DNS_RPZ_TCP_ONLY_NAME DNS_RPZ_PREFIX "tcp-only"
51 
52 typedef uint8_t dns_rpz_prefix_t;
53 
54 typedef enum {
55 	DNS_RPZ_TYPE_BAD,
56 	DNS_RPZ_TYPE_CLIENT_IP,
57 	DNS_RPZ_TYPE_QNAME,
58 	DNS_RPZ_TYPE_IP,
59 	DNS_RPZ_TYPE_NSDNAME,
60 	DNS_RPZ_TYPE_NSIP
61 } dns_rpz_type_t;
62 
63 /*
64  * Require DNS_RPZ_POLICY_PASSTHRU < DNS_RPZ_POLICY_DROP
65  * < DNS_RPZ_POLICY_TCP_ONLY DNS_RPZ_POLICY_NXDOMAIN < DNS_RPZ_POLICY_NODATA
66  * < DNS_RPZ_POLICY_CNAME to choose among competing policies.
67  */
68 typedef enum {
69 	DNS_RPZ_POLICY_GIVEN = 0,    /* 'given': what policy record says */
70 	DNS_RPZ_POLICY_DISABLED = 1, /* log what would have happened */
71 	DNS_RPZ_POLICY_PASSTHRU = 2, /* 'passthru': do not rewrite */
72 	DNS_RPZ_POLICY_DROP = 3,     /* 'drop': do not respond */
73 	DNS_RPZ_POLICY_TCP_ONLY = 4, /* 'tcp-only': answer UDP with TC=1 */
74 	DNS_RPZ_POLICY_NXDOMAIN = 5, /* 'nxdomain': answer with NXDOMAIN */
75 	DNS_RPZ_POLICY_NODATA = 6,   /* 'nodata': answer with ANCOUNT=0 */
76 	DNS_RPZ_POLICY_CNAME = 7,    /* 'cname x': answer with x's rrsets */
77 	DNS_RPZ_POLICY_DNS64,	     /* Apply DN64 to the A rewrite */
78 	DNS_RPZ_POLICY_RECORD,
79 	DNS_RPZ_POLICY_WILDCNAME,
80 	DNS_RPZ_POLICY_MISS,
81 	DNS_RPZ_POLICY_ERROR
82 } dns_rpz_policy_t;
83 
84 typedef uint8_t dns_rpz_num_t;
85 
86 #define DNS_RPZ_MAX_ZONES 64
87 /*
88  * Type dns_rpz_zbits_t must be an unsigned int wide enough to contain
89  * at least DNS_RPZ_MAX_ZONES bits.
90  */
91 typedef uint64_t dns_rpz_zbits_t;
92 
93 #define DNS_RPZ_ALL_ZBITS ((dns_rpz_zbits_t) - 1)
94 
95 #define DNS_RPZ_INVALID_NUM DNS_RPZ_MAX_ZONES
96 
97 #define DNS_RPZ_ZBIT(n) (((dns_rpz_zbits_t)1) << (dns_rpz_num_t)(n))
98 
99 /*
100  * Mask of the specified and higher numbered policy zones
101  * Avoid hassles with (1<<33) or (1<<65)
102  */
103 #define DNS_RPZ_ZMASK(n)                                     \
104 	((dns_rpz_zbits_t)((((n) >= DNS_RPZ_MAX_ZONES - 1)   \
105 				    ? 0                      \
106 				    : (1ULL << ((n) + 1))) - \
107 			   1))
108 
109 /*
110  * The trigger counter type.
111  */
112 typedef size_t dns_rpz_trigger_counter_t;
113 
114 /*
115  * The number of triggers of each type in a response policy zone.
116  */
117 typedef struct dns_rpz_triggers dns_rpz_triggers_t;
118 struct dns_rpz_triggers {
119 	dns_rpz_trigger_counter_t client_ipv4;
120 	dns_rpz_trigger_counter_t client_ipv6;
121 	dns_rpz_trigger_counter_t qname;
122 	dns_rpz_trigger_counter_t ipv4;
123 	dns_rpz_trigger_counter_t ipv6;
124 	dns_rpz_trigger_counter_t nsdname;
125 	dns_rpz_trigger_counter_t nsipv4;
126 	dns_rpz_trigger_counter_t nsipv6;
127 };
128 
129 /*
130  * A single response policy zone.
131  */
132 typedef struct dns_rpz_zone  dns_rpz_zone_t;
133 typedef struct dns_rpz_zones dns_rpz_zones_t;
134 
135 struct dns_rpz_zone {
136 	unsigned int magic;
137 	isc_loop_t  *loop;
138 
139 	dns_rpz_num_t	 num;	    /* ordinal in list of policy zones */
140 	dns_name_t	 origin;    /* Policy zone name */
141 	dns_name_t	 client_ip; /* DNS_RPZ_CLIENT_IP_ZONE.origin. */
142 	dns_name_t	 ip;	    /* DNS_RPZ_IP_ZONE.origin. */
143 	dns_name_t	 nsdname;   /* DNS_RPZ_NSDNAME_ZONE.origin */
144 	dns_name_t	 nsip;	    /* DNS_RPZ_NSIP_ZONE.origin. */
145 	dns_name_t	 passthru;  /* DNS_RPZ_PASSTHRU_NAME. */
146 	dns_name_t	 drop;	    /* DNS_RPZ_DROP_NAME. */
147 	dns_name_t	 tcp_only;  /* DNS_RPZ_TCP_ONLY_NAME. */
148 	dns_name_t	 cname;	    /* override value for ..._CNAME */
149 	dns_ttl_t	 max_policy_ttl;
150 	dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */
151 	uint16_t	 ede;	 /* Extended DNS Error */
152 
153 	uint32_t min_update_interval;	/* minimal interval between
154 					 * updates */
155 	isc_ht_t	*nodes;		/* entries in zone */
156 	dns_rpz_zones_t *rpzs;		/* owner */
157 	isc_time_t	 lastupdated;	/* last time the zone was processed
158 					 * */
159 	bool		 updatepending; /* there is an update pending */
160 	bool		 updaterunning; /* there is an update running */
161 	isc_result_t	 updateresult;	/* result from the offloaded work */
162 	dns_db_t	*db;		/* zones database */
163 	dns_dbversion_t *dbversion;	/* version we will be updating to */
164 	dns_db_t	*updb;		/* zones database we're working on */
165 	dns_dbversion_t *updbversion;	/* version we're currently working
166 					 * on */
167 	bool	     addsoa;		/* add soa to the additional section */
168 	isc_timer_t *updatetimer;
169 };
170 
171 /*
172  * Radix tree node for response policy IP addresses
173  */
174 typedef struct dns_rpz_cidr_node dns_rpz_cidr_node_t;
175 
176 /*
177  * Bitfields indicating which policy zones have policies of
178  * which type.
179  */
180 typedef struct dns_rpz_have dns_rpz_have_t;
181 struct dns_rpz_have {
182 	dns_rpz_zbits_t client_ipv4;
183 	dns_rpz_zbits_t client_ipv6;
184 	dns_rpz_zbits_t client_ip;
185 	dns_rpz_zbits_t qname;
186 	dns_rpz_zbits_t ipv4;
187 	dns_rpz_zbits_t ipv6;
188 	dns_rpz_zbits_t ip;
189 	dns_rpz_zbits_t nsdname;
190 	dns_rpz_zbits_t nsipv4;
191 	dns_rpz_zbits_t nsipv6;
192 	dns_rpz_zbits_t nsip;
193 	dns_rpz_zbits_t qname_skip_recurse;
194 };
195 
196 /*
197  * Policy options
198  */
199 typedef struct dns_rpz_popt dns_rpz_popt_t;
200 struct dns_rpz_popt {
201 	dns_rpz_zbits_t no_rd_ok;
202 	dns_rpz_zbits_t no_log;
203 	dns_rpz_zbits_t nsip_on;
204 	dns_rpz_zbits_t nsdname_on;
205 	bool		dnsrps_enabled;
206 	bool		break_dnssec;
207 	bool		qname_wait_recurse;
208 	bool		nsip_wait_recurse;
209 	bool		nsdname_wait_recurse;
210 	unsigned int	min_ns_labels;
211 	dns_rpz_num_t	num_zones;
212 };
213 
214 /*
215  * Response policy zones known to a view.
216  */
217 struct dns_rpz_zones {
218 	unsigned int   magic;
219 	isc_refcount_t references;
220 	isc_mem_t     *mctx;
221 	isc_loopmgr_t *loopmgr;
222 
223 	dns_rpz_popt_t	   p;
224 	dns_rpz_zone_t	  *zones[DNS_RPZ_MAX_ZONES];
225 	dns_rpz_triggers_t triggers[DNS_RPZ_MAX_ZONES];
226 
227 	/*
228 	 * RPZ policy version number.
229 	 * It is initially 0 and it increases whenever the server is
230 	 * reconfigured with new zones or policy.
231 	 */
232 	int rpz_ver;
233 
234 	dns_rpz_zbits_t defined;
235 
236 	/*
237 	 * The set of records for a policy zone are in one of these states:
238 	 *	never loaded		    load_begun=0  have=0
239 	 *	during initial loading	    load_begun=1  have=0
240 	 *				and rbtdb->rpzsp == rbtdb->load_rpzsp
241 	 *	after good load		    load_begun=1  have!=0
242 	 *	after failed initial load   load_begun=1  have=0
243 	 *				and rbtdb->load_rpzsp == NULL
244 	 *	reloading after failure	    load_begun=1  have=0
245 	 *	reloading after success
246 	 *		main rpzs	    load_begun=1  have!=0
247 	 *		load rpzs	    load_begun=1  have=0
248 	 */
249 	dns_rpz_zbits_t load_begun;
250 	dns_rpz_have_t	have;
251 
252 	/*
253 	 * total_triggers maintains the total number of triggers in all
254 	 * policy zones in the view. It is only used to print summary
255 	 * statistics after a zone load of how the trigger counts
256 	 * changed.
257 	 */
258 	dns_rpz_triggers_t total_triggers;
259 
260 	/*
261 	 * One lock for short term read-only search that guarantees the
262 	 * consistency of the pointers.
263 	 * A second lock for maintenance that guarantees no other thread
264 	 * is adding or deleting nodes.
265 	 */
266 	isc_rwlock_t search_lock;
267 	isc_mutex_t  maint_lock;
268 
269 	bool shuttingdown;
270 
271 	dns_rpz_cidr_node_t *cidr;
272 	dns_qpmulti_t	    *table;
273 
274 	/*
275 	 * DNSRPZ librpz configuration string and handle on librpz connection
276 	 */
277 	char		     *rps_cstr;
278 	size_t		      rps_cstr_size;
279 	struct librpz_client *rps_client;
280 };
281 
282 /*
283  * context for finding the best policy
284  */
285 typedef struct {
286 	unsigned int state;
287 #define DNS_RPZ_REWRITTEN      0x0001
288 #define DNS_RPZ_DONE_CLIENT_IP 0x0002 /* client IP address checked */
289 #define DNS_RPZ_DONE_QNAME     0x0004 /* qname checked */
290 #define DNS_RPZ_DONE_QNAME_IP  0x0008 /* IP addresses of qname checked */
291 #define DNS_RPZ_DONE_NSDNAME   0x0010 /* NS name missed; checking addresses */
292 #define DNS_RPZ_DONE_IPv4      0x0020
293 #define DNS_RPZ_RECURSING      0x0040
294 #define DNS_RPZ_ACTIVE	       0x0080
295 	/*
296 	 * Best match so far.
297 	 */
298 	struct {
299 		dns_rpz_type_t	 type;
300 		dns_rpz_zone_t	*rpz;
301 		dns_rpz_prefix_t prefix;
302 		dns_rpz_policy_t policy;
303 		dns_ttl_t	 ttl;
304 		isc_result_t	 result;
305 		dns_zone_t	*zone;
306 		dns_db_t	*db;
307 		dns_dbversion_t *version;
308 		dns_dbnode_t	*node;
309 		dns_rdataset_t	*rdataset;
310 	} m;
311 	/*
312 	 * State for chasing IP addresses and NS names including recursion.
313 	 */
314 	struct {
315 		unsigned int	label;
316 		dns_db_t       *db;
317 		dns_rdataset_t *ns_rdataset;
318 		dns_rdatatype_t r_type;
319 		isc_result_t	r_result;
320 		dns_rdataset_t *r_rdataset;
321 	} r;
322 
323 	/*
324 	 * State of real query while recursing for NSIP or NSDNAME.
325 	 */
326 	struct {
327 		isc_result_t	result;
328 		bool		is_zone;
329 		bool		authoritative;
330 		dns_zone_t     *zone;
331 		dns_db_t       *db;
332 		dns_dbnode_t   *node;
333 		dns_rdataset_t *rdataset;
334 		dns_rdataset_t *sigrdataset;
335 		dns_rdatatype_t qtype;
336 	} q;
337 
338 	/*
339 	 * A copy of the 'have' and 'p' structures and the RPZ
340 	 * policy version as of the beginning of RPZ processing,
341 	 * used to avoid problems when policy is updated while
342 	 * RPZ recursion is ongoing.
343 	 */
344 	dns_rpz_have_t have;
345 	dns_rpz_popt_t popt;
346 	int	       rpz_ver;
347 
348 	/*
349 	 * Shim db between BIND and DNRPS librpz.
350 	 */
351 	dns_db_t *rpsdb;
352 
353 	/*
354 	 * p_name: current policy owner name
355 	 * r_name: recursing for this name to possible policy triggers
356 	 * f_name: saved found name from before recursion
357 	 */
358 	dns_name_t     *p_name;
359 	dns_name_t     *r_name;
360 	dns_name_t     *fname;
361 	dns_fixedname_t _p_namef;
362 	dns_fixedname_t _r_namef;
363 	dns_fixedname_t _fnamef;
364 } dns_rpz_st_t;
365 
366 #define DNS_RPZ_TTL_DEFAULT		  5
367 #define DNS_RPZ_MAX_TTL_DEFAULT		  DNS_RPZ_TTL_DEFAULT
368 #define DNS_RPZ_MINUPDATEINTERVAL_DEFAULT 60
369 
370 /*
371  * So various response policy zone messages can be turned up or down.
372  */
373 #define DNS_RPZ_ERROR_LEVEL  ISC_LOG_WARNING
374 #define DNS_RPZ_INFO_LEVEL   ISC_LOG_INFO
375 #define DNS_RPZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1)
376 #define DNS_RPZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2)
377 #define DNS_RPZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3)
378 #define DNS_RPZ_DEBUG_QUIET  (DNS_RPZ_DEBUG_LEVEL3 + 1)
379 
380 const char *
381 dns_rpz_type2str(dns_rpz_type_t type);
382 
383 dns_rpz_policy_t
384 dns_rpz_str2policy(const char *str);
385 
386 const char *
387 dns_rpz_policy2str(dns_rpz_policy_t policy);
388 
389 uint16_t
390 dns_rpz_str2ede(const char *str);
391 
392 dns_rpz_policy_t
393 dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
394 		     dns_name_t *selfname);
395 
396 isc_result_t
397 dns_rpz_new_zones(dns_view_t *view, isc_loopmgr_t *loopmgr, char *rps_cstr,
398 		  size_t rps_cstr_size, dns_rpz_zones_t **rpzsp);
399 
400 isc_result_t
401 dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp);
402 
403 isc_result_t
404 dns_rpz_dbupdate_callback(dns_db_t *db, void *fn_arg);
405 void
406 dns_rpz_dbupdate_unregister(dns_db_t *db, dns_rpz_zone_t *rpz);
407 void
408 dns_rpz_dbupdate_register(dns_db_t *db, dns_rpz_zone_t *rpz);
409 
410 void
411 dns_rpz_zones_shutdown(dns_rpz_zones_t *rpzs);
412 
413 #ifdef DNS_RPZ_TRACE
414 #define dns_rpz_zones_detach(rpzsp) \
415 	dns_rpz_zones__detach(rpzsp, __func__, __FILE__, __LINE__)
416 #define dns_rpz_zones_attach(rpzs, rpzsp) \
417 	dns_rpz_zones__attach(rpzs, rpzsp, __func__, __FILE__, __LINE__)
418 #define dns_rpz_zones_ref(ptr) \
419 	dns_rpz_zones__ref(ptr, __func__, __FILE__, __LINE__)
420 #define dns_rpz_zones_unref(ptr) \
421 	dns_rpz_zones__unref(ptr, __func__, __FILE__, __LINE__)
422 
423 ISC_REFCOUNT_TRACE_DECL(dns_rpz_zones);
424 #else
425 ISC_REFCOUNT_DECL(dns_rpz_zones);
426 #endif
427 
428 dns_rpz_num_t
429 dns_rpz_find_ip(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type,
430 		dns_rpz_zbits_t zbits, const isc_netaddr_t *netaddr,
431 		dns_name_t *ip_name, dns_rpz_prefix_t *prefixp);
432 
433 dns_rpz_zbits_t
434 dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type,
435 		  dns_rpz_zbits_t zbits, dns_name_t *trig_name);
436 
437 ISC_LANG_ENDDECLS
438