2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 18:19:42 +00:00

suppress report-channel for zones above the agent-domain

RFC 9567 section 8.1 specifies that the agent domain cannot
be a subdomain of the domain it is reporting on. therefore,
in addition to making it illegal to configure that at the
zone level, we also need to disable send-report-channel for
any zone for which the global send-report-channel value is
a subdomain.

we also now warn if send-report-channel is configured
globally to a zone that we host, but that zone doesn't
have log-report-channel set.
This commit is contained in:
Evan Hunt 2024-10-22 13:48:58 -07:00
parent 5bcccf4754
commit c6698322c6
10 changed files with 89 additions and 39 deletions

View File

@ -236,7 +236,7 @@ options {\n\
notify yes;\n\ notify yes;\n\
notify-delay 5;\n\ notify-delay 5;\n\
notify-to-soa no;\n\ notify-to-soa no;\n\
# send-report-channel <none>\n\ send-report-channel .;\n\
serial-update-method increment;\n\ serial-update-method increment;\n\
sig-signing-nodes 100;\n\ sig-signing-nodes 100;\n\
sig-signing-signatures 10;\n\ sig-signing-signatures 10;\n\

View File

@ -4271,22 +4271,6 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
} }
} }
obj = NULL;
result = named_config_get(maps, "send-report-channel", &obj);
if (view->rad != NULL) {
dns_name_free(view->rad, view->mctx);
isc_mem_put(view->mctx, view->rad, sizeof(*view->rad));
}
if (result == ISC_R_SUCCESS) {
str = cfg_obj_asstring(obj);
if (strcmp(str, ".") != 0 && strcmp(str, "") != 0) {
view->rad = isc_mem_get(mctx, sizeof(*view->rad));
dns_name_init(view->rad, NULL);
CHECK(dns_name_fromstring(view->rad, str, dns_rootname,
0, mctx));
}
}
obj = NULL; obj = NULL;
result = named_config_get(maps, "dnssec-accept-expired", &obj); result = named_config_get(maps, "dnssec-accept-expired", &obj);
INSIST(result == ISC_R_SUCCESS); INSIST(result == ISC_R_SUCCESS);

View File

@ -1208,6 +1208,8 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
if (ztype != dns_zone_stub && ztype != dns_zone_staticstub && if (ztype != dns_zone_stub && ztype != dns_zone_staticstub &&
ztype != dns_zone_redirect) ztype != dns_zone_redirect)
{ {
bool logreports = false;
/* Make a reference to the default policy. */ /* Make a reference to the default policy. */
result = dns_kasplist_find(kasplist, "default", &kasp); result = dns_kasplist_find(kasplist, "default", &kasp);
INSIST(result == ISC_R_SUCCESS && kasp != NULL); INSIST(result == ISC_R_SUCCESS && kasp != NULL);
@ -1482,23 +1484,49 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE, dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE,
cfg_obj_asboolean(obj)); cfg_obj_asboolean(obj));
obj = NULL;
(void)cfg_map_get(zoptions, "send-report-channel", &obj);
if (obj != NULL) {
dns_fixedname_t fixed;
dns_name_t *rad = dns_fixedname_initname(&fixed);
CHECK(dns_name_fromstring(rad, cfg_obj_asstring(obj),
dns_rootname, 0, mctx));
dns_zone_setrad(zone, rad);
} else {
dns_zone_setrad(zone, NULL);
}
obj = NULL; obj = NULL;
result = cfg_map_get(zoptions, "log-report-channel", &obj); result = cfg_map_get(zoptions, "log-report-channel", &obj);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {
logreports = cfg_obj_asboolean(obj);
dns_zone_setoption(zone, DNS_ZONEOPT_LOGREPORTS, dns_zone_setoption(zone, DNS_ZONEOPT_LOGREPORTS,
cfg_obj_asboolean(obj)); logreports);
}
obj = NULL;
result = named_config_get(maps, "send-report-channel", &obj);
if (result == ISC_R_SUCCESS && obj != NULL) {
dns_fixedname_t fixed;
dns_name_t *rad = dns_fixedname_initname(&fixed);
const char *adstr = cfg_obj_asstring(obj);
dns_name_t *zn = dns_zone_getorigin(zone);
CHECK(dns_name_fromstring(rad, adstr, dns_rootname, 0,
mctx));
if (logreports || dns_name_equal(rad, dns_rootname)) {
/* Disable RC for error-logging zones or root */
dns_zone_setrad(zone, NULL);
} else if (dns_name_equal(rad, zn)) {
/*
* It's illegal to set a matching agent
* domain at the zone level, but it could
* be set in options/view. If so, and the
* matching zone doesn't log reports, warn.
*/
cfg_obj_log(obj, ISC_LOG_WARNING,
"send-report-channel is set to "
"'%s' but that zone does not have "
"log-report-channel set",
zname);
dns_zone_setrad(zone, NULL);
} else if (dns_name_issubdomain(rad, zn)) {
cfg_obj_log(obj, ISC_LOG_WARNING,
"send-report-channel '%s' ignored "
"for zone '%s' because it is a "
"subdomain of the zone",
adstr, zname);
dns_zone_setrad(zone, NULL);
} else {
dns_zone_setrad(zone, rad);
}
} }
} else if (ztype == dns_zone_redirect) { } else if (ztype == dns_zone_redirect) {
dns_zone_setnotifytype(zone, dns_notifytype_no); dns_zone_setnotifytype(zone, dns_notifytype_no);

View File

@ -0,0 +1,23 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 300 ; 5 minutes
@ IN SOA ns root (
2018010100 ; serial
1800 ; refresh (30 minutes)
1800 ; retry (30 minutes)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
NS ns
ns A 10.53.0.1
server A 10.53.0.100
*._er TXT "Report received"

View File

@ -39,9 +39,14 @@ view main in {
send-report-channel "rad.example.net"; send-report-channel "rad.example.net";
}; };
zone example.rad { zone rad {
type primary; type primary;
file "rad.db"; file "rad.db";
};
zone example.rad {
type primary;
file "example.rad.db";
log-report-channel yes; log-report-channel yes;
}; };
}; };

View File

@ -20,4 +20,5 @@ $TTL 300 ; 5 minutes
NS ns NS ns
ns A 10.53.0.1 ns A 10.53.0.1
server A 10.53.0.100 server A 10.53.0.100
*._er TXT "Report received"
example NS ns

View File

@ -194,6 +194,22 @@ grep "; Report-Channel: example.rad" dig.out.test$n >/dev/null || ret=1
[ $ret -eq 0 ] || echo_i "failed" [ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret)) status=$((status + ret))
n=$((n + 1))
echo_i "check that Report-Channel option is omitted for names in error-logging zones ($n)"
ret=0
$DIG $DIGOPTS @10.53.0.1 example.rad >dig.out.test$n
grep "; Report-Channel: example.rad" dig.out.test$n >/dev/null && ret=1
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "check that Report-Channel option is omitted for zones above the agent-domain ($n)"
ret=0
$DIG $DIGOPTS @10.53.0.1 rad >dig.out.test$n
grep "; Report-Channel: example.rad" dig.out.test$n >/dev/null && ret=1
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
n=$((n + 1)) n=$((n + 1))
echo_i "check that a zone-level Report-Channel EDNS option is added to responses ($n)" echo_i "check that a zone-level Report-Channel EDNS option is added to responses ($n)"
ret=0 ret=0

View File

@ -186,7 +186,6 @@ struct dns_view {
uint32_t maxrrperset; uint32_t maxrrperset;
uint32_t maxtypepername; uint32_t maxtypepername;
uint8_t max_restarts; uint8_t max_restarts;
dns_name_t *rad; /* reporting agent domain */
/* /*
* Configurable data for server use only, * Configurable data for server use only,

View File

@ -376,10 +376,6 @@ destroy(dns_view_t *view) {
dns_dns64_unlink(&view->dns64, dns64); dns_dns64_unlink(&view->dns64, dns64);
dns_dns64_destroy(&dns64); dns_dns64_destroy(&dns64);
} }
if (view->rad != NULL) {
dns_name_free(view->rad, view->mctx);
isc_mem_put(view->mctx, view->rad, sizeof(*view->rad));
}
if (view->managed_keys != NULL) { if (view->managed_keys != NULL) {
dns_zone_detach(&view->managed_keys); dns_zone_detach(&view->managed_keys);
} }

View File

@ -1243,8 +1243,6 @@ no_nsid:
dns_name_t *rad = NULL; dns_name_t *rad = NULL;
if (dns_name_dynamic(&client->rad)) { if (dns_name_dynamic(&client->rad)) {
rad = &client->rad; rad = &client->rad;
} else if (view != NULL && view->rad != NULL) {
rad = view->rad;
} }
if (rad != NULL && !dns_name_equal(rad, dns_rootname)) { if (rad != NULL && !dns_name_equal(rad, dns_rootname)) {
INSIST(count < DNS_EDNSOPTIONS); INSIST(count < DNS_EDNSOPTIONS);