]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3102. [func] New 'dnssec-loadkeys-interval' option configures
authorEvan Hunt <each@isc.org>
Fri, 29 Apr 2011 21:37:15 +0000 (21:37 +0000)
committerEvan Hunt <each@isc.org>
Fri, 29 Apr 2011 21:37:15 +0000 (21:37 +0000)
how often, in minutes, to check the key repository
for updates when using automatic key maintenance.
Default is every 60 minutes (formerly hard-coded
to 12 hours). [RT #23744]

3101. [bug] Zones using automatic key maintenance could fail
to check the key repository for updates. [RT #23744]

CHANGES
bin/named/config.c
bin/named/zoneconf.c
bin/tests/system/autosign/ns2/named.conf
bin/tests/system/autosign/ns3/named.conf
bin/tests/system/autosign/tests.sh
doc/arm/Bv9ARM-book.xml
lib/bind9/check.c
lib/dns/include/dns/zone.h
lib/dns/zone.c
lib/isccfg/namedconf.c

diff --git a/CHANGES b/CHANGES
index 51c58ae74a45c6d98aa5edf0f34c82efe9a143fc..23e67dd4d2e9192473c1d91472216db4cace4093 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,12 @@
+3102.  [func]          New 'dnssec-loadkeys-interval' option configures
+                       how often, in minutes, to check the key repository
+                       for updates when using automatic key maintenance.
+                       Default is every 60 minutes (formerly hard-coded
+                       to 12 hours). [RT #23744]
+                       
+3101.  [bug]           Zones using automatic key maintenance could fail
+                       to check the key repository for updates. [RT #23744]
+
 3100.  [security]      Certain response policy zone configurations could
                        trigger an INSIST when receiving a query of type
                        RRSIG. [RT #24280]
index 7122e27a32b1fd578aad95a61586c239529da58f..00ba064986866ce3550c296420a971e6734022b9 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: config.c,v 1.116 2011/02/23 03:08:08 marka Exp $ */
+/* $Id: config.c,v 1.117 2011/04/29 21:37:14 each Exp $ */
 
 /*! \file */
 
@@ -210,6 +210,7 @@ options {\n\
        zero-no-soa-ttl yes;\n\
        update-check-ksk yes;\n\
        dnssec-dnskey-kskonly no;\n\
+       dnssec-loadkeys-interval 60;\n\
        try-tcp-refresh yes; /* BIND 8 compat */\n\
 };\n\
 "
index 3fd1cfe278ed98e741ac2ee4496f8925972ed057..387a724d553a45e06c467999c957d3af8be1bc17 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zoneconf.c,v 1.174 2011/03/11 06:11:21 marka Exp $ */
+/* $Id: zoneconf.c,v 1.175 2011/04/29 21:37:14 each Exp $ */
 
 /*% */
 
@@ -1229,6 +1229,12 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
                INSIST(result == ISC_R_SUCCESS && obj != NULL);
                dns_zone_setoption(zone, DNS_ZONEOPT_DNSKEYKSKONLY,
                                   cfg_obj_asboolean(obj));
+
+               obj = NULL;
+               result = ns_config_get(maps, "dnssec-loadkeys-interval", &obj);
+               INSIST(result == ISC_R_SUCCESS && obj != NULL);
+               RETERR(dns_zone_setrefreshkeyinterval(zone,
+                                                     cfg_obj_asuint32(obj)));
        } else if (ztype == dns_zone_slave) {
                RETERR(configure_zone_acl(zconfig, vconfig, config,
                                          allow_update_forwarding, ac, zone,
index 10a91907b60fc85a9d2352f27d5661ccd18efb86..1969be56a29aad4e2ba5423cd6beab29f8efc822 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: named.conf,v 1.5 2010/01/18 23:48:40 tbox Exp $ */
+/* $Id: named.conf,v 1.6 2011/04/29 21:37:14 each Exp $ */
 
 // NS2
 
@@ -32,6 +32,7 @@ options {
        notify yes;
        dnssec-enable yes;
        dnssec-validation yes;
+       dnssec-loadkeys-interval 30;
 };
 
 key rndc_key {
index 4d6598ee3de96d6fa93de33ce597678e55d3b906..8a8eaa32d550e8e16e8668795d8d3390f96cb513 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: named.conf,v 1.10 2011/03/25 23:53:02 each Exp $ */
+/* $Id: named.conf,v 1.11 2011/04/29 21:37:14 each Exp $ */
 
 // NS3
 
@@ -32,6 +32,7 @@ options {
        notify yes;
        dnssec-enable yes;
        dnssec-validation yes;
+       dnssec-loadkeys-interval 10;
 };
 
 key rndc_key {
index a03bdac832f7b6cc2433a345c2a85f37ce080377..729271fc8704919982a16eaa2abe76b0d1394812 100644 (file)
@@ -14,7 +14,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: tests.sh,v 1.20 2011/03/25 23:53:02 each Exp $
+# $Id: tests.sh,v 1.21 2011/04/29 21:37:14 each Exp $
 
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
@@ -879,6 +879,43 @@ grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || lret=1
 n=`expr $n + 1`
 if [ $lret != 0 ]; then echo "I:not yet implemented"; fi
 
+echo "I:checking key event timers are always set ($n)"
+# this is a regression test for a bug in which the next key event could
+# be scheduled for the present moment, and then never fire.  check for
+# visible evidence of this error in the logs:
+awk '/next key event/ {if ($1 == $8 && $2 == $9) exit 1}' */named.run || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+# this confirms that key events are never scheduled more than
+# 'dnssec-loadkeys-interval' minutes in the future, and that the 
+# last event scheduled is precisely that far in the future.
+check_interval () {
+        awk '/next key event/ {print $2 ":" $9}' $1/named.run |
+            awk -F: -vinterval=$2 '
+                     {
+                       if ($6 == 0)
+                         $6 = 25;
+                       x = ($6+ $5*60 + $4*3600) - ($3 + $2*60 + $1*3600);
+                       if (x != int(x))
+                         x = int(x + 1);
+                       if (x > interval)
+                         exit (1);
+                     }
+                     END { if (x != interval) exit(1) }'
+        return $?
+}
+
+echo "I:checking automatic key reloading interval ($n)"
+ret=0
+check_interval ns1 3600 || ret=1
+check_interval ns2 1800 || ret=1
+check_interval ns3 600 || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:exit status: $status"
 
 exit $status
index 21467e81c20fb6ede529ca7913cec71f4b94a6d9..519cb2e05426097a1f5d0fa47cc1c2d8b756f314 100644 (file)
@@ -18,7 +18,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- File: $Id: Bv9ARM-book.xml,v 1.484 2011/04/06 04:20:58 marka Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.485 2011/04/29 21:37:14 each Exp $ -->
 <book xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>BIND 9 Administrator Reference Manual</title>
 
@@ -5060,6 +5060,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
     <optional> allow-update-forwarding { <replaceable>address_match_list</replaceable> }; </optional>
     <optional> update-check-ksk <replaceable>yes_or_no</replaceable>; </optional>
     <optional> dnssec-dnskey-kskonly <replaceable>yes_or_no</replaceable>; </optional>
+    <optional> dnssec-loadkeys-interval <replaceable>number</replaceable>; </optional>
     <optional> dnssec-secure-to-insecure <replaceable>yes_or_no</replaceable> ;</optional>
     <optional> try-tcp-refresh <replaceable>yes_or_no</replaceable>; </optional>
     <optional> allow-v6-synthesis { <replaceable>address_match_list</replaceable> }; </optional>
@@ -6884,6 +6885,26 @@ options {
              </listitem>
            </varlistentry>
 
+           <varlistentry>
+             <term><command>dnssec-loadkeys-interval</command></term>
+             <listitem>
+               <para>
+                  When a zone is configured with <command>auto-dnssec
+                  maintain;</command> its key repository must be checked
+                  periodically to see if any new keys have been added
+                  or any existing keys' timing metadata has been updated
+                  (see <xref linkend="man.dnssec-keygen"/> and
+                  <xref linkend="man.dnssec-settime"/>).  The
+                  <command>dnssec-loadkeys-interval</command> option
+                  sets the frequency of autoatic repository checks, in
+                  minutes.  The default is <literal>60</literal> (1 hour),
+                  the minimum is <literal>1</literal> (1 minute), and the
+                  maximum is <literal>1440</literal> (24 hours); any higher
+                  value is silently reduced.
+               </para>
+             </listitem>
+           </varlistentry>
+
            <varlistentry>
              <term><command>try-tcp-refresh</command></term>
              <listitem>
@@ -10024,6 +10045,7 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
     <optional> allow-update-forwarding { <replaceable>address_match_list</replaceable> }; </optional>
     <optional> update-check-ksk <replaceable>yes_or_no</replaceable>; </optional>
     <optional> dnssec-dnskey-kskonly <replaceable>yes_or_no</replaceable>; </optional>
+    <optional> dnssec-loadkeys-interval <replaceable>number</replaceable>; </optional>
     <optional> dnssec-secure-to-insecure <replaceable>yes_or_no</replaceable> ; </optional>
     <optional> try-tcp-refresh <replaceable>yes_or_no</replaceable>; </optional>
     <optional> also-notify { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ;
@@ -11119,7 +11141,12 @@ example.com. NS ns2.example.net.
                     <command>named</command> to load keys from the key
                     repository and schedule key maintenance events to occur
                     in the future, but it does not sign the full zone
-                    immediately.
+                    immediately.  Note: once keys have been loaded for a
+                    zone the first time, the repository will be searched
+                    for changes periodically, regardless of whether
+                    <command>rndc loadkeys</command> is used.  The recheck
+                    interval is defined by
+                    <command>dnssec-loadkeys-interval</command>.)
                   </para>
                   <para>
                     <command>auto-dnssec create;</command> includes the
index 96b386ee29ca19531aaae3cb699d06b49c1dd88d..84c9c974b3484c61b4a0a4ed215658ca953d7d54 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: check.c,v 1.128 2011/03/11 17:19:05 each Exp $ */
+/* $Id: check.c,v 1.129 2011/04/29 21:37:15 each Exp $ */
 
 /*! \file */
 
@@ -1307,6 +1307,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
          REDIRECTZONE },
        { "update-check-ksk", MASTERZONE },
        { "dnssec-dnskey-kskonly", MASTERZONE },
+       { "dnssec-loadkeys-interval", MASTERZONE },
        { "auto-dnssec", MASTERZONE },
        { "try-tcp-refresh", SLAVEZONE | STREDIRECTZONE },
        { "server-addresses", STATICSTUBZONE },
index 2914ce4579e232e1be73e48a233a84aa23a0e8ba..629a5bebfc363fc92e775eebe16a11857f87d0b1 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.h,v 1.186 2011/03/21 18:38:40 each Exp $ */
+/* $Id: zone.h,v 1.187 2011/04/29 21:37:15 each Exp $ */
 
 #ifndef DNS_ZONE_H
 #define DNS_ZONE_H 1
@@ -1871,6 +1871,18 @@ dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze);
  * \li 'zone' to be valid.
  */
 
+isc_result_t
+dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval);
+/*%
+ * Sets the frequency, in minutes, with which the key repository will be
+ * checked to see if the keys for this zone have been updated.  Any value
+ * higher than 1440 minutes (24 hours) will be silently reduced.  A
+ * value of zero will return an out-of-range error.
+ *
+ * Requires:
+ * \li 'zone' to be valid.
+ */
+
 ISC_LANG_ENDDECLS
 
 #endif /* DNS_ZONE_H */
index 8d8b2f429bf921a2e0dfd0a0ffb2c4dcb8455a06..d1f2b6436d58a87b9c476052ec0c02533265b943 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.601 2011/03/25 23:53:02 each Exp $ */
+/* $Id: zone.c,v 1.602 2011/04/29 21:37:15 each Exp $ */
 
 /*! \file */
 
@@ -207,6 +207,7 @@ struct dns_zone {
        isc_time_t              signingtime;
        isc_time_t              nsec3chaintime;
        isc_time_t              refreshkeytime;
+       isc_uint32_t            refreshkeyinterval;
        isc_uint32_t            refreshkeycount;
        isc_uint32_t            refresh;
        isc_uint32_t            retry;
@@ -770,6 +771,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
        isc_time_settoepoch(&zone->signingtime);
        isc_time_settoepoch(&zone->nsec3chaintime);
        isc_time_settoepoch(&zone->refreshkeytime);
+       zone->refreshkeyinterval = 0;
        zone->refreshkeycount = 0;
        zone->refresh = DNS_ZONE_DEFAULTREFRESH;
        zone->retry = DNS_ZONE_DEFAULTRETRY;
@@ -14172,48 +14174,52 @@ zone_rekey(dns_zone_t *zone) {
                UNLOCK_ZONE(zone);
        }
 
+       /*
+        * If we are doing automatic key maintenance and the key metadata
+        * indicates there is a key change event scheduled in the future,
+        * set the key refresh timer.
+        */
        isc_stdtime_get(&now);
        TIME_NOW(&timenow);
        isc_time_settoepoch(&zone->refreshkeytime);
-       for (key = ISC_LIST_HEAD(dnskeys);
-            key != NULL;
-            key = ISC_LIST_NEXT(key, link)) {
-               isc_stdtime_t then;
+
+       /*
+        * If we're doing key maintenance, set the key refresh timer to
+        * the next scheduled key event or to 'dnssec-loadkeys-interval'
+        * seconds in the future, whichever is sooner.
+        */
+       if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
                isc_time_t timethen;
+               isc_stdtime_t then;
 
-               /*
-                * If we are doing automatic key maintenance and the
-                * key metadata indicates there is a key change event
-                * scheduled in the future, set the key refresh timer.
-                */
-               if (!DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
-                       break;
+               LOCK_ZONE(zone);
+               DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
+                                 &timethen);
+               zone->refreshkeytime = timethen;
+               UNLOCK_ZONE(zone);
 
-               then = now;
-               result = next_keyevent(key->key, &then);
-               if (result != ISC_R_SUCCESS)
-                       continue;
+               for (key = ISC_LIST_HEAD(dnskeys);
+                    key != NULL;
+                    key = ISC_LIST_NEXT(key, link)) {
+                       then = now;
+                       result = next_keyevent(key->key, &then);
+                       if (result != ISC_R_SUCCESS)
+                               continue;
 
-               DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
-               LOCK_ZONE(zone);
-               if (isc_time_isepoch(&zone->refreshkeytime) ||
-                   isc_time_compare(&timethen, &zone->refreshkeytime) < 0) {
-                       zone->refreshkeytime = timethen;
-                       zone_settimer(zone, &timenow);
+                       DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
+                       LOCK_ZONE(zone);
+                       if (isc_time_compare(&timethen,
+                                            &zone->refreshkeytime) < 0) {
+                               zone->refreshkeytime = timethen;
+                       }
+                       UNLOCK_ZONE(zone);
                }
-               UNLOCK_ZONE(zone);
-       }
 
-       /*
-        * If no key event is scheduled, we should still check the key
-        * repository for updates every so often.  (Currently this is
-        * hard-coded to 12 hours, but it could be configurable.)
-        */
-       if (isc_time_isepoch(&zone->refreshkeytime))
-               DNS_ZONE_TIME_ADD(&timenow, (3600 * 12), &zone->refreshkeytime);
+               zone_settimer(zone, &timenow);
 
-       isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
-       dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
+               isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
+               dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
+       }
 
  failure:
        dns_diff_clear(&diff);
@@ -14306,3 +14312,16 @@ dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
        UNLOCK_ZONE(zone);
        return result;
 }
+
+isc_result_t
+dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) {
+       REQUIRE(DNS_ZONE_VALID(zone));
+       if (interval == 0)
+               return (ISC_R_RANGE);
+       /* Maximum value: 24 hours (3600 minutes) */
+       if (interval > (24 * 60)) 
+               interval = (24 * 60);
+       /* Multiply by 60 for seconds */
+       zone->refreshkeyinterval = interval * 60;
+       return (ISC_R_SUCCESS);
+}
index a1c0aa77464c11fcc676f835fa932ad1a6e6a54e..8546878aa2af24c3692faeb44def37d5033c6111 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: namedconf.c,v 1.134 2011/03/11 06:11:27 marka Exp $ */
+/* $Id: namedconf.c,v 1.135 2011/04/29 21:37:15 each Exp $ */
 
 /*! \file */
 
@@ -1341,6 +1341,7 @@ zone_clauses[] = {
        { "check-wildcard", &cfg_type_boolean, 0 },
        { "dialup", &cfg_type_dialuptype, 0 },
        { "dnssec-dnskey-kskonly", &cfg_type_boolean, 0 },
+       { "dnssec-loadkeys-interval", &cfg_type_uint32, 0 },
        { "dnssec-secure-to-insecure", &cfg_type_boolean, 0 },
        { "forward", &cfg_type_forwardtype, 0 },
        { "forwarders", &cfg_type_portiplist, 0 },