enforce '*._er' requirement for error-reporting zones

if "log-report-channel" is set to "yes", then the zone must
contain a wildcard name matching '*._er' with a TXT record.
This commit is contained in:
Evan Hunt 2024-10-20 01:04:06 -07:00
parent d60324891c
commit 1cd0d291d3
8 changed files with 135 additions and 5 deletions

View file

@ -159,7 +159,7 @@ main(int argc, char **argv) {
while ((c = isc_commandline_parse(argc, argv,
"c:df:hi:jJ:k:L:l:m:n:qr:s:t:o:vw:C:"
"DF:M:S:T:W:")) != EOF)
"DF:M:R:S:T:W:")) != EOF)
{
switch (c) {
case 'c':
@ -323,6 +323,18 @@ main(int argc, char **argv) {
}
break;
case 'R':
if (ARGCMP("fail")) {
zone_options |= DNS_ZONEOPT_LOGREPORTS;
} else if (ARGCMP("ignore")) {
zone_options &= ~DNS_ZONEOPT_LOGREPORTS;
} else {
fprintf(stderr, "invalid argument to -R: %s\n",
isc_commandline_argument);
exit(EXIT_FAILURE);
}
break;
case 's':
if (ARGCMP("full")) {
outputstyle = &dns_master_style_full;

View file

@ -23,7 +23,7 @@ named-checkzone - zone file validation tool
Synopsis
~~~~~~~~
:program:`named-checkzone` [**-d**] [**-h**] [**-j**] [**-q**] [**-v**] [**-c** class] [**-C** mode] [**-f** format] [**-F** format] [**-J** filename] [**-i** mode] [**-k** mode] [**-m** mode] [**-M** mode] [**-n** mode] [**-l** ttl] [**-L** serial] [**-o** filename] [**-r** mode] [**-s** style] [**-S** mode] [**-t** directory] [**-T** mode] [**-w** directory] [**-D**] [**-W** mode] {zonename} {filename}
:program:`named-checkzone` [**-d**] [**-h**] [**-j**] [**-q**] [**-v**] [**-c** class] [**-C** mode] [**-f** format] [**-F** format] [**-J** filename] [**-i** mode] [**-k** mode] [**-m** mode] [**-M** mode] [**-n** mode] [**-l** ttl] [**-L** serial] [**-o** filename] [**-r** mode] [**-R** mode] [**-s** style] [**-S** mode] [**-t** directory] [**-T** mode] [**-w** directory] [**-D**] [**-W** mode] {zonename} {filename}
Description
~~~~~~~~~~~
@ -166,6 +166,12 @@ Options
semantically equal in plain DNS. Possible modes are ``fail``,
``warn`` (the default), and ``ignore``.
.. option:: -R mode
This option checks whether a TXT wildcard record exists that
matches the name format for RFC 9567 error-reporting queries: ``*._er``.
Possible modes are ``fail`` and ``ignore`` (the default).
.. option:: -s style
This option specifies the style of the dumped zone file. Possible styles are

View file

@ -23,7 +23,7 @@ named-compilezone - zone file converting tool
Synopsis
~~~~~~~~
:program:`named-compilezone` [**-d**] [**-h**] [**-j**] [**-q**] [**-v**] [**-c** class] [**-C** mode] [**-f** format] [**-F** format] [**-J** filename] [**-i** mode] [**-k** mode] [**-m** mode] [**-M** mode] [**-n** mode] [**-l** ttl] [**-L** serial] [**-r** mode] [**-s** style] [**-S** mode] [**-t** directory] [**-T** mode] [**-w** directory] [**-D**] [**-W** mode] {**-o** filename} {zonename} {filename}
:program:`named-compilezone` [**-d**] [**-h**] [**-j**] [**-q**] [**-v**] [**-c** class] [**-C** mode] [**-f** format] [**-F** format] [**-J** filename] [**-i** mode] [**-k** mode] [**-m** mode] [**-M** mode] [**-n** mode] [**-l** ttl] [**-L** serial] [**-r** mode] [**-R** mode] [**-s** style] [**-S** mode] [**-t** directory] [**-T** mode] [**-w** directory] [**-D**] [**-W** mode] {**-o** filename} {zonename} {filename}
Description
~~~~~~~~~~~
@ -175,6 +175,12 @@ Options
semantically equal in plain DNS. Possible modes are ``fail``,
``warn``, and ``ignore`` (the default).
.. option:: -R mode
This option checks whether a TXT wildcard record exists that
matches the name format for RFC 9567 error-reporting queries: ``*._er``.
Possible modes are ``fail`` and ``ignore`` (the default).
.. option:: -s style
This option specifies the style of the dumped zone file. Possible styles are

View file

@ -124,6 +124,16 @@ n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "checking that log-report-channel zones fail if '*._er/TXT' is missing ($n)"
ret=0
$CHECKZONE -R fail example zones/er.db >test.out2.$n 2>&1 || ret=1
grep -F "no '*._er/TXT' wildcard found" test.out4.$n >/dev/null && ret=1
$CHECKZONE example zones/er-missing.db >test.out3.$n 2>&1 || ret=1
grep -F "no '*._er/TXT' wildcard found" test.out4.$n >/dev/null && ret=1
$CHECKZONE -R fail example zones/er-missing.db >test.out4.$n 2>&1 && ret=1
grep -F "no '*._er/TXT' wildcard found" test.out4.$n >/dev/null || ret=1
status=$((status + ret))
echo_i "checking that raw zone with bad class is handled ($n)"
ret=0
$CHECKZONE -f raw example zones/bad-badclass.raw >test.out.$n 2>&1 && ret=1

View file

@ -0,0 +1,22 @@
; 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

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

@ -7315,8 +7315,9 @@ Zone Options
are logged to the ``dns-reporting-agent`` logging category at
level ``info``.
The zone should have a wildcard record in place to respond to such
queries. For example:
The zone must have a wildcard record in place to respond to such
queries; it is a configuration error to use this option in a
zone without such a record. For example:
::

View file

@ -4727,6 +4727,47 @@ process_zone_setnsec3param(dns_zone_t *zone) {
}
}
static unsigned char er_offset[] = { 0, 1 };
static unsigned char er_ndata[] = "\001*\003_er";
static dns_name_t er = DNS_NAME_INITNONABSOLUTE(er_ndata, er_offset);
static isc_result_t
check_reportchannel(dns_zone_t *zone, dns_db_t *db) {
isc_result_t result;
dns_rdataset_t rdataset = DNS_RDATASET_INIT;
dns_dbnode_t *node = NULL;
dns_dbversion_t *version = NULL;
dns_fixedname_t fixed;
dns_name_t *name = NULL;
/*
* If this zone isn't logging reports, it's fine.
*/
if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_LOGREPORTS)) {
return (ISC_R_SUCCESS);
}
/*
* Otherwise, we need a '*._er' wildcard with a TXT rdataset.
*/
name = dns_fixedname_initname(&fixed);
CHECK(dns_name_concatenate(&er, &zone->origin, name, NULL));
CHECK(dns_db_findnode(db, name, false, &node));
dns_db_currentversion(db, &version);
result = dns_db_findrdataset(db, node, version, dns_rdatatype_txt,
dns_rdatatype_none, 0, &rdataset, NULL);
dns_db_closeversion(db, &version, false);
dns_db_detachnode(db, &node);
if (result == ISC_R_SUCCESS) {
dns_rdataset_disassociate(&rdataset);
}
failure:
return (result);
}
/*
* The zone is presumed to be locked.
* If this is a inline_raw zone the secure version is also locked.
@ -4972,6 +5013,15 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
}
}
result = check_reportchannel(zone, db);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"'log-report-channel' is set, but no "
"'*._er/TXT' wildcard found");
result = DNS_R_BADZONE;
goto cleanup;
}
result = dns_zone_verifydb(zone, db, NULL);
if (result != ISC_R_SUCCESS) {
goto cleanup;