From: Aram Sargsyan Date: Fri, 26 Aug 2022 14:11:47 +0000 (+0000) Subject: Add extended DNS error configuration option for RPZ zones X-Git-Tag: v9.19.5~21^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77f12ecba7dfbfb4abfb063d4206cc9795ce589d;p=thirdparty%2Fbind9.git Add extended DNS error configuration option for RPZ zones 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. --- diff --git a/bin/named/server.c b/bin/named/server.c index 899b0e027ae..476c408b785 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -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; diff --git a/doc/man/named.conf.5in b/doc/man/named.conf.5in index cbc565134c5..47ef15b08ee 100644 --- a/doc/man/named.conf.5in +++ b/doc/man/named.conf.5in @@ -312,7 +312,7 @@ options { resolver\-query\-timeout ; resolver\-retry\-interval ; response\-padding { ; ... } block\-size ; - response\-policy { zone [ add\-soa ] [ log ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ policy ( cname | disabled | drop | given | no\-op | nodata | nxdomain | passthru | tcp\-only ) ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ]; ... } [ add\-soa ] [ break\-dnssec ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ min\-ns\-dots ] [ nsip\-wait\-recurse ] [ nsdname\-wait\-recurse ] [ qname\-wait\-recurse ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ] [ dnsrps\-enable ] [ dnsrps\-options { } ]; + response\-policy { zone [ add\-soa ] [ log ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ policy ( cname | disabled | drop | given | no\-op | nodata | nxdomain | passthru | tcp\-only ) ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ] [ ede ]; ... } [ add\-soa ] [ break\-dnssec ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ min\-ns\-dots ] [ nsip\-wait\-recurse ] [ nsdname\-wait\-recurse ] [ qname\-wait\-recurse ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ] [ dnsrps\-enable ] [ dnsrps\-options { } ]; reuseport ; root\-delegation\-only [ exclude { ; ... } ]; root\-key\-sentinel ; @@ -590,7 +590,7 @@ view [ ] { resolver\-query\-timeout ; resolver\-retry\-interval ; response\-padding { ; ... } block\-size ; - response\-policy { zone [ add\-soa ] [ log ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ policy ( cname | disabled | drop | given | no\-op | nodata | nxdomain | passthru | tcp\-only ) ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ]; ... } [ add\-soa ] [ break\-dnssec ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ min\-ns\-dots ] [ nsip\-wait\-recurse ] [ nsdname\-wait\-recurse ] [ qname\-wait\-recurse ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ] [ dnsrps\-enable ] [ dnsrps\-options { } ]; + response\-policy { zone [ add\-soa ] [ log ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ policy ( cname | disabled | drop | given | no\-op | nodata | nxdomain | passthru | tcp\-only ) ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ] [ ede ]; ... } [ add\-soa ] [ break\-dnssec ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ min\-ns\-dots ] [ nsip\-wait\-recurse ] [ nsdname\-wait\-recurse ] [ qname\-wait\-recurse ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ] [ dnsrps\-enable ] [ dnsrps\-options { } ]; root\-delegation\-only [ exclude { ; ... } ]; root\-key\-sentinel ; rrset\-order { [ class ] [ type ] [ name ] ; ... }; diff --git a/doc/misc/options b/doc/misc/options index 1681be1514a..6b0609394f2 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -255,7 +255,7 @@ options { resolver-query-timeout ; resolver-retry-interval ; response-padding { ; ... } block-size ; - response-policy { zone [ add-soa ] [ log ] [ max-policy-ttl ] [ min-update-interval ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only ) ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ]; ... } [ add-soa ] [ break-dnssec ] [ max-policy-ttl ] [ min-update-interval ] [ min-ns-dots ] [ nsip-wait-recurse ] [ nsdname-wait-recurse ] [ qname-wait-recurse ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ] [ dnsrps-enable ] [ dnsrps-options { } ]; + response-policy { zone [ add-soa ] [ log ] [ max-policy-ttl ] [ min-update-interval ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only ) ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ] [ ede ]; ... } [ add-soa ] [ break-dnssec ] [ max-policy-ttl ] [ min-update-interval ] [ min-ns-dots ] [ nsip-wait-recurse ] [ nsdname-wait-recurse ] [ qname-wait-recurse ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ] [ dnsrps-enable ] [ dnsrps-options { } ]; reuseport ; root-delegation-only [ exclude { ; ... } ]; root-key-sentinel ; @@ -533,7 +533,7 @@ view [ ] { resolver-query-timeout ; resolver-retry-interval ; response-padding { ; ... } block-size ; - response-policy { zone [ add-soa ] [ log ] [ max-policy-ttl ] [ min-update-interval ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only ) ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ]; ... } [ add-soa ] [ break-dnssec ] [ max-policy-ttl ] [ min-update-interval ] [ min-ns-dots ] [ nsip-wait-recurse ] [ nsdname-wait-recurse ] [ qname-wait-recurse ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ] [ dnsrps-enable ] [ dnsrps-options { } ]; + response-policy { zone [ add-soa ] [ log ] [ max-policy-ttl ] [ min-update-interval ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only ) ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ] [ ede ]; ... } [ add-soa ] [ break-dnssec ] [ max-policy-ttl ] [ min-update-interval ] [ min-ns-dots ] [ nsip-wait-recurse ] [ nsdname-wait-recurse ] [ qname-wait-recurse ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ] [ dnsrps-enable ] [ dnsrps-options { } ]; root-delegation-only [ exclude { ; ... } ]; root-key-sentinel ; rrset-order { [ class ] [ type ] [ name ] ; ... }; diff --git a/lib/bind9/check.c b/lib/bind9/check.c index f24d02c02dd..2ddd90b2706 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -53,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -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. */ diff --git a/lib/dns/include/dns/rpz.h b/lib/dns/include/dns/rpz.h index c46168d5383..4bd421b22fa 100644 --- a/lib/dns/include/dns/rpz.h +++ b/lib/dns/include/dns/rpz.h @@ -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); diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c index 4e78b576098..cfeac54dead 100644 --- a/lib/dns/rpz.c +++ b/lib/dns/rpz.c @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -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.) diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 64d0ddb494f..481bc9827b2 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -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,