From 19352dd187784f40b9a4eb9eff630120f21cfaa5 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Mon, 11 Jul 2022 13:38:51 -0700 Subject: [PATCH 1/5] mark max-zone-ttl deprecated in options and zone The "max-zone-ttl" option should now be configured as part of "dnssec-policy". The option with the same name in "zone" and "options" is hereby flagged as deprecated, and its functionality will be removed in a future release. --- bin/tests/system/checkconf/deprecated.conf | 7 +++ bin/tests/system/checkconf/tests.sh | 1 + doc/arm/reference.rst | 52 ++++++++++++++-------- doc/man/named.conf.5in | 8 ++-- doc/misc/options | 4 +- doc/misc/primary.zoneopt | 2 +- doc/misc/redirect.zoneopt | 2 +- lib/isccfg/namedconf.c | 2 +- 8 files changed, 50 insertions(+), 28 deletions(-) diff --git a/bin/tests/system/checkconf/deprecated.conf b/bin/tests/system/checkconf/deprecated.conf index 44607a042b..6c092db306 100644 --- a/bin/tests/system/checkconf/deprecated.conf +++ b/bin/tests/system/checkconf/deprecated.conf @@ -13,6 +13,7 @@ options { dnssec-validation yes; + max-zone-ttl 600; }; trusted-keys { @@ -36,3 +37,9 @@ managed-keys { RUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwN R1AkUTV74bU="; }; + +zone example.com { + type primary; + file "maxttl-bad.db"; + max-zone-ttl 120; +}; diff --git a/bin/tests/system/checkconf/tests.sh b/bin/tests/system/checkconf/tests.sh index 5d6108ecd2..7d8d50e5ca 100644 --- a/bin/tests/system/checkconf/tests.sh +++ b/bin/tests/system/checkconf/tests.sh @@ -157,6 +157,7 @@ ret=0 $CHECKCONF deprecated.conf > checkconf.out$n.1 2>&1 grep "option 'managed-keys' is deprecated" < checkconf.out$n.1 > /dev/null || ret=1 grep "option 'trusted-keys' is deprecated" < checkconf.out$n.1 > /dev/null || ret=1 +grep "option 'max-zone-ttl' is deprecated" < checkconf.out$n.1 > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` # set -i to ignore deprecate warnings diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index 69fddba873..f6fe74916b 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -1802,26 +1802,28 @@ default is used. The default is five minutes. It cannot be longer than :any:`nta-lifetime`, which cannot be longer than a week. -.. namedconf:statement:: max-zone-ttl +:any:`max-zone-ttl` - This specifies a maximum permissible TTL value in seconds. For - convenience, TTL-style time-unit suffixes may be used to specify the - maximum value. When loading a zone file using a :any:`masterfile-format` - of ``text`` or ``raw``, any record encountered with a TTL higher than - :any:`max-zone-ttl` causes the zone to be rejected. + This should now be configured as part of :namedconf:ref:`dnssec-policy`. + Use of this option in :namedconf:ref:`options`, :namedconf:ref:`view` + and :namedconf:ref:`zone` blocks has no effect on any zone for which + a :namedconf:ref:`dnssec-policy` has also been configured. In zones + without :namedconf:ref:`dnssec-policy`, this option is deprecated, + and will be rendered non-operational in a future release. + + :any:`max-zone-ttl` specifies a maximum permissible TTL value in seconds. + For convenience, TTL-style time-unit suffixes may be used to specify the + maximum value. When a zone file is loaded, any record encountered with a + TTL higher than :any:`max-zone-ttl` causes the zone to be rejected. This is needed in DNSSEC-maintained zones because when rolling to a new DNSKEY, the old key needs to remain available until RRSIG records have expired from caches. The :any:`max-zone-ttl` option guarantees that the largest TTL in the zone is no higher than the set value. - In the :namedconf:ref:`options` and :namedconf:ref:`zone` blocks, - the default value is ``unlimited``. A :any:`max-zone-ttl` of zero is - treated as ``unlimited``. - - In the :namedconf:ref:`dnssec-policy` block, - the default value is ``PT24H`` (24 hours). A :any:`max-zone-ttl` of - zero is treated as if the default value were in use. + When used in :namedconf:ref:`options`, :namedconf:ref:`view` and + :namedconf:ref:`zone` blocks, setting :any:`max-zone-ttl` to zero + is equivalent to "unlimited". .. namedconf:statement:: stale-answer-ttl @@ -4213,9 +4215,9 @@ Tuning Note that when a zone file in a format other than ``text`` is loaded, :iscman:`named` may omit some of the checks which are performed for a file in ``text`` format. For example, :any:`check-names` only applies when loading - zones in ``text`` format, and :any:`max-zone-ttl` only applies to ``text`` - and ``raw``. Zone files in binary formats should be generated with the - same check level as that specified in the :iscman:`named` configuration file. + zones in ``text`` format. Zone files in ``raw`` format should be generated + with the same check level as that specified in the :iscman:`named` + configuration file. When configured in :namedconf:ref:`options`, this statement sets the :any:`masterfile-format` for all zones, but it can be overridden on a @@ -5982,10 +5984,20 @@ The following options can be specified in a :any:`dnssec-policy` statement: This is similar to :any:`signatures-validity`, but for DNSKEY records. The default is ``P2W`` (2 weeks). -:any:`max-zone-ttl` +.. namedconf:statement:: max-zone-ttl + + This specifies the maximum permissible TTL value for the zone. When + a zone file is loaded, any record encountered with a TTL higher than + :any:`max-zone-ttl` causes the zone to be rejected. + + This ensures that when rolling to a new DNSKEY, the old key will remain + available until RRSIG records have expired from caches. The + :any:`max-zone-ttl` option guarantees that the largest TTL in the + zone is no higher than a known and predictable value. + + The default value ``PT24H`` (24 hours). A value of zero is treated + as if the default value were in use. - Like the :namedconf:ref:`max-zone-ttl` zone option, this specifies the maximum - permissible TTL value, in seconds, for the zone. .. namedconf:statement:: nsec3param @@ -6779,6 +6791,8 @@ Zone Options :any:`max-zone-ttl` See the description of :any:`max-zone-ttl` in :ref:`options`. + The use of this option in :any:`zone` blocks is deprecated and + will be rendered nonoperational in a future release. :any:`dnssec-secure-to-insecure` See the description of :any:`dnssec-secure-to-insecure` in :ref:`boolean_options`. diff --git a/doc/man/named.conf.5in b/doc/man/named.conf.5in index 2fc6bd1eb7..cbc565134c 100644 --- a/doc/man/named.conf.5in +++ b/doc/man/named.conf.5in @@ -247,7 +247,7 @@ options { max\-transfer\-time\-in ; max\-transfer\-time\-out ; max\-udp\-size ; - max\-zone\-ttl ( unlimited | ); + max\-zone\-ttl ( unlimited | ); // deprecated memstatistics ; memstatistics\-file ; message\-compression ; @@ -534,7 +534,7 @@ view [ ] { max\-transfer\-time\-in ; max\-transfer\-time\-out ; max\-udp\-size ; - max\-zone\-ttl ( unlimited | ); + max\-zone\-ttl ( unlimited | ); // deprecated message\-compression ; min\-cache\-ttl ; min\-ncache\-ttl ; @@ -703,7 +703,7 @@ zone [ ] { max\-records ; max\-transfer\-idle\-out ; max\-transfer\-time\-out ; - max\-zone\-ttl ( unlimited | ); + max\-zone\-ttl ( unlimited | ); // deprecated notify ( explicit | master\-only | primary\-only | ); notify\-delay ; notify\-source ( | * ) [ port ( | * ) ] [ dscp ]; @@ -902,7 +902,7 @@ zone [ ] { masterfile\-format ( raw | text ); masterfile\-style ( full | relative ); max\-records ; - max\-zone\-ttl ( unlimited | ); + max\-zone\-ttl ( unlimited | ); // deprecated primaries [ port ] [ dscp ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; zone\-statistics ( full | terse | none | ); }; diff --git a/doc/misc/options b/doc/misc/options index 37558e36da..1681be1514 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -190,7 +190,7 @@ options { max-transfer-time-in ; max-transfer-time-out ; max-udp-size ; - max-zone-ttl ( unlimited | ); + max-zone-ttl ( unlimited | ); // deprecated memstatistics ; memstatistics-file ; message-compression ; @@ -477,7 +477,7 @@ view [ ] { max-transfer-time-in ; max-transfer-time-out ; max-udp-size ; - max-zone-ttl ( unlimited | ); + max-zone-ttl ( unlimited | ); // deprecated message-compression ; min-cache-ttl ; min-ncache-ttl ; diff --git a/doc/misc/primary.zoneopt b/doc/misc/primary.zoneopt index c8ceb6d29f..5501962f4c 100644 --- a/doc/misc/primary.zoneopt +++ b/doc/misc/primary.zoneopt @@ -40,7 +40,7 @@ zone [ ] { max-records ; max-transfer-idle-out ; max-transfer-time-out ; - max-zone-ttl ( unlimited | ); + max-zone-ttl ( unlimited | ); // deprecated notify ( explicit | master-only | primary-only | ); notify-delay ; notify-source ( | * ) [ port ( | * ) ] [ dscp ]; diff --git a/doc/misc/redirect.zoneopt b/doc/misc/redirect.zoneopt index 1c34bb11f1..845ca96062 100644 --- a/doc/misc/redirect.zoneopt +++ b/doc/misc/redirect.zoneopt @@ -7,7 +7,7 @@ zone [ ] { masterfile-format ( raw | text ); masterfile-style ( full | relative ); max-records ; - max-zone-ttl ( unlimited | ); + max-zone-ttl ( unlimited | ); // deprecated primaries [ port ] [ dscp ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; zone-statistics ( full | terse | none | ); }; diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index a438fe1f5e..64d0ddb494 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -2300,7 +2300,7 @@ static cfg_clausedef_t zone_clauses[] = { { "max-transfer-time-out", &cfg_type_uint32, CFG_ZONE_PRIMARY | CFG_ZONE_MIRROR | CFG_ZONE_SECONDARY }, { "max-zone-ttl", &cfg_type_maxduration, - CFG_ZONE_PRIMARY | CFG_ZONE_REDIRECT }, + CFG_ZONE_PRIMARY | CFG_ZONE_REDIRECT | CFG_CLAUSEFLAG_DEPRECATED }, { "min-refresh-time", &cfg_type_uint32, CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB }, { "min-retry-time", &cfg_type_uint32, From 21930c70c6a6676014b3eab7b7e74d66e6230d5e Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Wed, 13 Jul 2022 10:27:18 +0200 Subject: [PATCH 2/5] Test dnssec-policy max-zone-ttl rejects zone with too high TTL Similar to the 'max-zone-ttl' zone option, the 'dnssec-policy' option should reject zones with TTLs that are out of range. --- bin/tests/system/kasp/ns3/named.conf.in | 9 +++++++ .../system/kasp/ns3/policies/kasp.conf.in | 4 ++++ bin/tests/system/kasp/ns3/setup.sh | 24 ++++++++----------- bin/tests/system/kasp/tests.sh | 9 +++++++ 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/bin/tests/system/kasp/ns3/named.conf.in b/bin/tests/system/kasp/ns3/named.conf.in index 4815967511..b77f463df7 100644 --- a/bin/tests/system/kasp/ns3/named.conf.in +++ b/bin/tests/system/kasp/ns3/named.conf.in @@ -223,6 +223,15 @@ zone "ecdsa384.kasp" { dnssec-policy "ecdsa384"; }; +/* + * Zone with too high TTL. + */ +zone "max-zone-ttl.kasp" { + type primary; + file "max-zone-ttl.kasp.db"; + dnssec-policy "ttl"; +}; + /* * Zones in different signing states. */ diff --git a/bin/tests/system/kasp/ns3/policies/kasp.conf.in b/bin/tests/system/kasp/ns3/policies/kasp.conf.in index d0ae96ce08..17b900c7b3 100644 --- a/bin/tests/system/kasp/ns3/policies/kasp.conf.in +++ b/bin/tests/system/kasp/ns3/policies/kasp.conf.in @@ -132,3 +132,7 @@ dnssec-policy "checkds-csk" { csk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; }; }; + +dnssec-policy "ttl" { + max-zone-ttl 299; +}; diff --git a/bin/tests/system/kasp/ns3/setup.sh b/bin/tests/system/kasp/ns3/setup.sh index d9accadda5..1842f5064f 100644 --- a/bin/tests/system/kasp/ns3/setup.sh +++ b/bin/tests/system/kasp/ns3/setup.sh @@ -64,20 +64,16 @@ if [ -f ../ed448-supported.file ]; then cat ed448.conf >> named.conf fi -# Set up zone that stays unsigned. -zone="unsigned.kasp" -echo_i "setting up zone: $zone" -zonefile="${zone}.db" -infile="${zone}.db.infile" -cp template.db.in $infile -cp template.db.in $zonefile - -# Set up zone that stays unsigned. -zone="insecure.kasp" -echo_i "setting up zone: $zone" -zonefile="${zone}.db" -infile="${zone}.db.infile" -cp template.db.in $zonefile +# Set up zones that stay unsigned. +for zn in unsigned insecure max-zone-ttl +do + zone="${zn}.kasp" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" + cp template.db.in $infile + cp template.db.in $zonefile +done # Some of these zones already have keys. zone="dnssec-keygen.kasp" diff --git a/bin/tests/system/kasp/tests.sh b/bin/tests/system/kasp/tests.sh index 9c6cea20c8..bd2e4896d3 100644 --- a/bin/tests/system/kasp/tests.sh +++ b/bin/tests/system/kasp/tests.sh @@ -252,6 +252,15 @@ status=$((status+ret)) next_key_event_threshold=$((next_key_event_threshold+i)) +# Test max-zone-ttl rejects zones with too high TTL. +n=$((n+1)) +echo_i "check that max-zone-ttl rejects zones with too high TTL ($n)" +ret=0 +set_zone "max-zone-ttl.kasp" +grep "loading from master file ${ZONE}.db failed: out of range" "ns3/named.run" > /dev/null || ret=1 +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + # # Zone: default.kasp. # From 0712ba502cdc9bb2a55bcd3b41184cddd29b47fb Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Wed, 13 Jul 2022 10:28:59 +0200 Subject: [PATCH 3/5] Reject zones with TTL higher than dnssec-policy max-zone-ttl Reject loading of zones with TTL higher than the max-zone-ttl from the dnssec-policy. With this change, any zone with a dnssec-policy in use will ignore the max-zone-ttl option in zone/view/options. --- bin/named/zoneconf.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 9bc94ee597..898f93af16 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -907,6 +907,7 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, dns_stats_t *dnssecsignstats; dns_zonestat_level_t statlevel = dns_zonestat_none; int seconds; + dns_ttl_t maxttl = 0; /* unlimited */ dns_zone_t *mayberaw = (raw != NULL) ? raw : zone; isc_dscp_t dscp; @@ -1065,20 +1066,6 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, } } - obj = NULL; - result = named_config_get(maps, "max-zone-ttl", &obj); - if (result == ISC_R_SUCCESS) { - dns_ttl_t maxttl = 0; /* unlimited */ - - if (cfg_obj_isduration(obj)) { - maxttl = cfg_obj_asduration(obj); - } - dns_zone_setmaxttl(zone, maxttl); - if (raw != NULL) { - dns_zone_setmaxttl(raw, maxttl); - } - } - obj = NULL; result = named_config_get(maps, "max-records", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); @@ -1531,6 +1518,22 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, dns_zone_setjournalsize(zone, journal_size); } + if (use_kasp) { + maxttl = dns_kasp_zonemaxttl(dns_zone_getkasp(zone)); + } else { + obj = NULL; + result = named_config_get(maps, "max-zone-ttl", &obj); + if (result == ISC_R_SUCCESS) { + if (cfg_obj_isduration(obj)) { + maxttl = cfg_obj_asduration(obj); + } + } + } + dns_zone_setmaxttl(zone, maxttl); + if (raw != NULL) { + dns_zone_setmaxttl(raw, maxttl); + } + /* * Configure update-related options. These apply to * primary servers only. From b1d0cac280cd97f2a0ef09655f24ed23645804ed Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Tue, 19 Jul 2022 12:13:42 -0700 Subject: [PATCH 4/5] Forbid zones with both dnssec-policy and max-zone-ttl Since max-zone-ttl in zone/view/options is a no-op if dnssec-policy is in use, let's make that a fatal error. --- .../checkconf/bad-kasp-max-zone-ttl.conf | 26 +++++++++++++++++++ doc/arm/reference.rst | 8 +++--- lib/bind9/check.c | 24 +++++++++++++++++ 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 bin/tests/system/checkconf/bad-kasp-max-zone-ttl.conf diff --git a/bin/tests/system/checkconf/bad-kasp-max-zone-ttl.conf b/bin/tests/system/checkconf/bad-kasp-max-zone-ttl.conf new file mode 100644 index 0000000000..0b5939478e --- /dev/null +++ b/bin/tests/system/checkconf/bad-kasp-max-zone-ttl.conf @@ -0,0 +1,26 @@ +/* + * 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. + */ + +/* + * The dnssec-policy is not defined. Should also be caught if it is inherited. + */ + +options { + dnssec-policy default; +}; + +zone "example.net" { + type primary; + file "example.db"; + max-zone-ttl 600; +}; diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index f6fe74916b..9dd453b0fe 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -1806,10 +1806,10 @@ default is used. This should now be configured as part of :namedconf:ref:`dnssec-policy`. Use of this option in :namedconf:ref:`options`, :namedconf:ref:`view` - and :namedconf:ref:`zone` blocks has no effect on any zone for which - a :namedconf:ref:`dnssec-policy` has also been configured. In zones - without :namedconf:ref:`dnssec-policy`, this option is deprecated, - and will be rendered non-operational in a future release. + and :namedconf:ref:`zone` blocks is a fatal error if + :namedconf:ref:`dnssec-policy` has also been configured for the same + zone. In zones without :namedconf:ref:`dnssec-policy`, this option is + deprecated, and will be rendered non-operational in a future release. :any:`max-zone-ttl` specifies a maximum permissible TTL value in seconds. For convenience, TTL-style time-unit suffixes may be used to specify the diff --git a/lib/bind9/check.c b/lib/bind9/check.c index baacd29a84..3cad314ad8 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -3142,6 +3142,30 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, } } + /* + * Reject zones with both dnssec-policy and max-zone-ttl + * */ + if (has_dnssecpolicy) { + obj = NULL; + (void)cfg_map_get(zoptions, "max-zone-ttl", &obj); + if (obj == NULL && voptions != NULL) { + (void)cfg_map_get(voptions, "max-zone-ttl", &obj); + } + if (obj == NULL && goptions != NULL) { + (void)cfg_map_get(goptions, "max-zone-ttl", &obj); + } + if (obj != NULL) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "zone '%s': option 'max-zone-ttl' " + "cannot be used together with " + "'dnssec-policy'", + znamestr); + if (result == ISC_R_SUCCESS) { + result = ISC_R_FAILURE; + } + } + } + /* * Check validity of the zone options. */ From 8c3fdecd73f3c5f76b98c4d8db7a2758c1dd21e6 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Mon, 11 Jul 2022 13:48:21 -0700 Subject: [PATCH 5/5] CHANGES and release note for [GL #2918] --- CHANGES | 10 ++++++++++ doc/notes/notes-current.rst | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/CHANGES b/CHANGES index 829500559e..3beb716547 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,13 @@ +5929. [func] The use of the "max-zone-ttl" option in "zone" and + "options" blocks is now deprecated; this should + now be configured as part of "dnssec-policy" + instead. The old option still works in zones + with no "dnssec-policy" configured, but a warning + will be logged when loading configuration. Its + functionality will be removed in a future release. + Using "max-zone-ttl" and "dnssec-policy" in the + same zone is now a fatal error. [GL #2918] + 5928. [placeholder] 5927. [bug] A race was possible in dns_dispatch_connect() diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index b604010fcc..acbec4e529 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -32,6 +32,12 @@ Removed Features - None. +- The use of the ``max-zone-ttl`` option in ``options`` and ``zone`` + blocks has been deprecated; it should now be configured as part of + ``dnssec-policy``. A warning is logged if this option is used in + ``options`` or ``zone``. In a future release, it will become + nonoperational. :gl:`#2918` + Feature Changes ~~~~~~~~~~~~~~~