]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add extended DNS error configuration option for RPZ zones
authorAram Sargsyan <aram@isc.org>
Fri, 26 Aug 2022 14:11:47 +0000 (14:11 +0000)
committerAram Sargsyan <aram@isc.org>
Wed, 31 Aug 2022 08:56:03 +0000 (08:56 +0000)
Implement the configuration option with its checking and parsing parts.

The option should be later used by BIND to set an extended error
code (EDE) for the queries modified in the result of RPZ processing.

bin/named/server.c
doc/man/named.conf.5in
doc/misc/options
lib/bind9/check.c
lib/dns/include/dns/rpz.h
lib/dns/rpz.c
lib/isccfg/namedconf.c

index 899b0e027aeed1f04e11b469b0c85fd9abd0b79b..476c408b7858fc0d6e721346838f0e7eb83cb706 100644 (file)
@@ -18,6 +18,7 @@
 #include <limits.h>
 #include <signal.h>
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -2395,6 +2396,18 @@ configure_rpz_zone(dns_view_t *view, const cfg_listelt_t *element,
                *old_rpz_okp = false;
        }
 
+       obj = cfg_tuple_get(rpz_obj, "ede");
+       if (!cfg_obj_isstring(obj)) {
+               zone->ede = 0;
+       } else {
+               str = cfg_obj_asstring(obj);
+               zone->ede = dns_rpz_str2ede(str);
+               INSIST(zone->ede != UINT16_MAX);
+       }
+       if (*old_rpz_okp && zone->ede != old->ede) {
+               *old_rpz_okp = false;
+       }
+
        obj = cfg_tuple_get(rpz_obj, "add-soa");
        if (cfg_obj_isvoid(obj)) {
                zone->addsoa = add_soa_default;
index cbc565134c5aed9da418f379e20701ca09cb59f3..47ef15b08ee85e7ffc18db7537e18333a75bb0f3 100644 (file)
@@ -312,7 +312,7 @@ options {
        resolver\-query\-timeout <integer>;
        resolver\-retry\-interval <integer>;
        response\-padding { <address_match_element>; ... } block\-size <integer>;
-       response\-policy { zone <string> [ add\-soa <boolean> ] [ log <boolean> ] [ max\-policy\-ttl <duration> ] [ min\-update\-interval <duration> ] [ policy ( cname | disabled | drop | given | no\-op | nodata | nxdomain | passthru | tcp\-only <quoted_string> ) ] [ recursive\-only <boolean> ] [ nsip\-enable <boolean> ] [ nsdname\-enable <boolean> ]; ... } [ add\-soa <boolean> ] [ break\-dnssec <boolean> ] [ max\-policy\-ttl <duration> ] [ min\-update\-interval <duration> ] [ min\-ns\-dots <integer> ] [ nsip\-wait\-recurse <boolean> ] [ nsdname\-wait\-recurse <boolean> ] [ qname\-wait\-recurse <boolean> ] [ recursive\-only <boolean> ] [ nsip\-enable <boolean> ] [ nsdname\-enable <boolean> ] [ dnsrps\-enable <boolean> ] [ dnsrps\-options { <unspecified\-text> } ];
+       response\-policy { zone <string> [ add\-soa <boolean> ] [ log <boolean> ] [ max\-policy\-ttl <duration> ] [ min\-update\-interval <duration> ] [ policy ( cname | disabled | drop | given | no\-op | nodata | nxdomain | passthru | tcp\-only <quoted_string> ) ] [ recursive\-only <boolean> ] [ nsip\-enable <boolean> ] [ nsdname\-enable <boolean> ] [ ede <string> ]; ... } [ add\-soa <boolean> ] [ break\-dnssec <boolean> ] [ max\-policy\-ttl <duration> ] [ min\-update\-interval <duration> ] [ min\-ns\-dots <integer> ] [ nsip\-wait\-recurse <boolean> ] [ nsdname\-wait\-recurse <boolean> ] [ qname\-wait\-recurse <boolean> ] [ recursive\-only <boolean> ] [ nsip\-enable <boolean> ] [ nsdname\-enable <boolean> ] [ dnsrps\-enable <boolean> ] [ dnsrps\-options { <unspecified\-text> } ];
        reuseport <boolean>;
        root\-delegation\-only [ exclude { <string>; ... } ];
        root\-key\-sentinel <boolean>;
@@ -590,7 +590,7 @@ view <string> [ <class> ] {
        resolver\-query\-timeout <integer>;
        resolver\-retry\-interval <integer>;
        response\-padding { <address_match_element>; ... } block\-size <integer>;
-       response\-policy { zone <string> [ add\-soa <boolean> ] [ log <boolean> ] [ max\-policy\-ttl <duration> ] [ min\-update\-interval <duration> ] [ policy ( cname | disabled | drop | given | no\-op | nodata | nxdomain | passthru | tcp\-only <quoted_string> ) ] [ recursive\-only <boolean> ] [ nsip\-enable <boolean> ] [ nsdname\-enable <boolean> ]; ... } [ add\-soa <boolean> ] [ break\-dnssec <boolean> ] [ max\-policy\-ttl <duration> ] [ min\-update\-interval <duration> ] [ min\-ns\-dots <integer> ] [ nsip\-wait\-recurse <boolean> ] [ nsdname\-wait\-recurse <boolean> ] [ qname\-wait\-recurse <boolean> ] [ recursive\-only <boolean> ] [ nsip\-enable <boolean> ] [ nsdname\-enable <boolean> ] [ dnsrps\-enable <boolean> ] [ dnsrps\-options { <unspecified\-text> } ];
+       response\-policy { zone <string> [ add\-soa <boolean> ] [ log <boolean> ] [ max\-policy\-ttl <duration> ] [ min\-update\-interval <duration> ] [ policy ( cname | disabled | drop | given | no\-op | nodata | nxdomain | passthru | tcp\-only <quoted_string> ) ] [ recursive\-only <boolean> ] [ nsip\-enable <boolean> ] [ nsdname\-enable <boolean> ] [ ede <string> ]; ... } [ add\-soa <boolean> ] [ break\-dnssec <boolean> ] [ max\-policy\-ttl <duration> ] [ min\-update\-interval <duration> ] [ min\-ns\-dots <integer> ] [ nsip\-wait\-recurse <boolean> ] [ nsdname\-wait\-recurse <boolean> ] [ qname\-wait\-recurse <boolean> ] [ recursive\-only <boolean> ] [ nsip\-enable <boolean> ] [ nsdname\-enable <boolean> ] [ dnsrps\-enable <boolean> ] [ dnsrps\-options { <unspecified\-text> } ];
        root\-delegation\-only [ exclude { <string>; ... } ];
        root\-key\-sentinel <boolean>;
        rrset\-order { [ class <string> ] [ type <string> ] [ name <quoted_string> ] <string> <string>; ... };
index 1681be1514a4fb09f7156721705471d2c42a8353..6b0609394f20b9a408f1c5005fbdd492fe68f29c 100644 (file)
@@ -255,7 +255,7 @@ options {
        resolver-query-timeout <integer>;
        resolver-retry-interval <integer>;
        response-padding { <address_match_element>; ... } block-size <integer>;
-       response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
+       response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ ede <string> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
        reuseport <boolean>;
        root-delegation-only [ exclude { <string>; ... } ];
        root-key-sentinel <boolean>;
@@ -533,7 +533,7 @@ view <string> [ <class> ] {
        resolver-query-timeout <integer>;
        resolver-retry-interval <integer>;
        response-padding { <address_match_element>; ... } block-size <integer>;
-       response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
+       response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ ede <string> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
        root-delegation-only [ exclude { <string>; ... } ];
        root-key-sentinel <boolean>;
        rrset-order { [ class <string> ] [ type <string> ] [ name <quoted_string> ] <string> <string>; ... };
index f24d02c02dd7ebe48fff7ac88cbe0bf072f649b5..2ddd90b27060e319c81f2624e2ebe46f5f528e12 100644 (file)
@@ -16,6 +16,7 @@
 #include <ctype.h>
 #include <inttypes.h>
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdlib.h>
 
 #include <openssl/opensslv.h>
@@ -53,6 +54,7 @@
 #include <dns/rbt.h>
 #include <dns/rdataclass.h>
 #include <dns/rdatatype.h>
+#include <dns/rpz.h>
 #include <dns/rrl.h>
 #include <dns/secalg.h>
 #include <dns/ssu.h>
@@ -4958,6 +4960,49 @@ check_rpz_catz(const char *rpz_catz, const cfg_obj_t *rpz_obj,
        return (result);
 }
 
+static isc_result_t
+check_rpz(const cfg_obj_t *rpz_obj, isc_log_t *logctx) {
+       const cfg_listelt_t *element;
+       const cfg_obj_t *obj, *nameobj, *edeobj;
+       const char *zonename;
+       isc_result_t result = ISC_R_SUCCESS, tresult;
+       dns_fixedname_t fixed;
+       dns_name_t *name = dns_fixedname_initname(&fixed);
+
+       obj = cfg_tuple_get(rpz_obj, "zone list");
+
+       for (element = cfg_list_first(obj); element != NULL;
+            element = cfg_list_next(element))
+       {
+               obj = cfg_listelt_value(element);
+               nameobj = cfg_tuple_get(obj, "zone name");
+               zonename = cfg_obj_asstring(nameobj);
+
+               tresult = dns_name_fromstring(name, zonename, 0, NULL);
+               if (tresult != ISC_R_SUCCESS) {
+                       cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                   "bad domain name '%s'", zonename);
+                       if (result == ISC_R_SUCCESS) {
+                               result = tresult;
+                               continue;
+                       }
+               }
+
+               edeobj = cfg_tuple_get(obj, "ede");
+               if (edeobj != NULL && cfg_obj_isstring(edeobj)) {
+                       const char *str = cfg_obj_asstring(edeobj);
+
+                       if (dns_rpz_str2ede(str) == UINT16_MAX) {
+                               cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                           "unsupported EDE type '%s'", str);
+                               result = ISC_R_FAILURE;
+                       }
+               }
+       }
+
+       return (result);
+}
+
 static isc_result_t
 check_catz(const cfg_obj_t *catz_obj, const char *viewname, isc_mem_t *mctx,
           isc_log_t *logctx) {
@@ -5214,6 +5259,19 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
                }
        }
 
+       /*
+        * Check response-policy configuration.
+        */
+       if (opts != NULL) {
+               obj = NULL;
+               if ((cfg_map_get(opts, "response-policy", &obj) ==
+                    ISC_R_SUCCESS) &&
+                   (check_rpz(obj, logctx) != ISC_R_SUCCESS))
+               {
+                       result = ISC_R_FAILURE;
+               }
+       }
+
        /*
         * Check catalog-zones configuration.
         */
index c46168d5383a6dec3644a683141297e9e1d81893..4bd421b22fa585687d4de3640af24cb4f9264fac 100644 (file)
@@ -143,6 +143,7 @@ struct dns_rpz_zone {
        dns_name_t       cname;     /* override value for ..._CNAME */
        dns_ttl_t        max_policy_ttl;
        dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */
+       uint16_t         ede;    /* Extended DNS Error */
 
        uint32_t min_update_interval;   /* minimal interval between
                                         * updates */
@@ -379,6 +380,9 @@ dns_rpz_str2policy(const char *str);
 const char *
 dns_rpz_policy2str(dns_rpz_policy_t policy);
 
+uint16_t
+dns_rpz_str2ede(const char *str);
+
 dns_rpz_policy_t
 dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
                     dns_name_t *selfname);
index 4e78b5760989022f1b0da9e0482ff6fbd5dcf81b..cfeac54dead343f8b1e02a1fed7fe5d2665186a5 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <inttypes.h>
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdlib.h>
 
 #include <isc/buffer.h>
@@ -278,6 +279,32 @@ dns_rpz_policy2str(dns_rpz_policy_t policy) {
        return (str);
 }
 
+uint16_t
+dns_rpz_str2ede(const char *str) {
+       static struct {
+               const char *str;
+               uint16_t ede;
+       } tbl[] = {
+               { "none", 0 },
+               { "forged", DNS_EDE_FORGEDANSWER },
+               { "blocked", DNS_EDE_BLOCKED },
+               { "censored", DNS_EDE_CENSORED },
+               { "filtered", DNS_EDE_FILTERED },
+               { "prohibited", DNS_EDE_PROHIBITED },
+       };
+       unsigned int n;
+
+       if (str == NULL) {
+               return (UINT16_MAX);
+       }
+       for (n = 0; n < sizeof(tbl) / sizeof(tbl[0]); ++n) {
+               if (!strcasecmp(tbl[n].str, str)) {
+                       return (tbl[n].ede);
+               }
+       }
+       return (UINT16_MAX);
+}
+
 /*
  * Return the bit number of the highest set bit in 'zbit'.
  * (for example, 0x01 returns 0, 0xFF returns 7, etc.)
index 64d0ddb494febf824f183b12a6fde1c7fc85b30c..481bc9827b2025365b8a943265848fa7b5aad7d3 100644 (file)
@@ -1833,6 +1833,7 @@ static cfg_tuplefielddef_t rpz_zone_fields[] = {
        { "recursive-only", &cfg_type_boolean, 0 },
        { "nsip-enable", &cfg_type_boolean, 0 },
        { "nsdname-enable", &cfg_type_boolean, 0 },
+       { "ede", &cfg_type_ustring, 0 },
        { NULL, NULL, 0 }
 };
 static cfg_type_t cfg_type_rpz_tuple = { "rpz tuple",       cfg_parse_kv_tuple,