]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3116. [func] New 'dnssec-update-mode' option controls updates
authorEvan Hunt <each@isc.org>
Mon, 23 May 2011 20:10:03 +0000 (20:10 +0000)
committerEvan Hunt <each@isc.org>
Mon, 23 May 2011 20:10:03 +0000 (20:10 +0000)
of DNSSEC records in signed dynamic zones.  Set to
'no-resign' to disable automatic RRSIG regeneration
while retaining the ability to sign new or changed
data. [RT #24533]

12 files changed:
CHANGES
bin/named/config.c
bin/named/zoneconf.c
bin/tests/system/dnssec/clean.sh
bin/tests/system/dnssec/ns3/named.conf
bin/tests/system/dnssec/ns3/nosign.example.db.in [new file with mode: 0644]
bin/tests/system/dnssec/ns3/sign.sh
bin/tests/system/dnssec/tests.sh
doc/arm/Bv9ARM-book.xml
lib/dns/include/dns/zone.h
lib/dns/zone.c
lib/isccfg/namedconf.c

diff --git a/CHANGES b/CHANGES
index 7ddbda4617c421ab045c4fcfbdee196b2494ff90..0ae3f445d65134e9cafb817e622cf09e511a1836 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+3116.  [func]          New 'dnssec-update-mode' option controls updates
+                       of DNSSEC records in signed dynamic zones.  Set to
+                       'no-resign' to disable automatic RRSIG regeneration
+                       while retaining the ability to sign new or changed
+                       data. [RT #24533]
+
 3115.  [bug]           Named could fail to return requested data when
                        following a CNAME that points into the same zone.
                        [RT #24455]
index 00ba064986866ce3550c296420a971e6734022b9..fe102d2b0241718cc718988613b2863d7597fe2f 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: config.c,v 1.117 2011/04/29 21:37:14 each Exp $ */
+/* $Id: config.c,v 1.118 2011/05/23 20:10:01 each Exp $ */
 
 /*! \file */
 
@@ -209,6 +209,7 @@ options {\n\
        check-srv-cname warn;\n\
        zero-no-soa-ttl yes;\n\
        update-check-ksk yes;\n\
+       dnssec-update-mode maintain;\n\
        dnssec-dnskey-kskonly no;\n\
        dnssec-loadkeys-interval 60;\n\
        try-tcp-refresh yes; /* BIND 8 compat */\n\
index 5fb74159b763b6356c57ea42bfaec5cbc3711e3d..8764ec1c6c2d2d95c8ee9cdfc06f35dbd9ec4a9f 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zoneconf.c,v 1.176 2011/05/06 21:23:50 each Exp $ */
+/* $Id: zoneconf.c,v 1.177 2011/05/23 20:10:01 each Exp $ */
 
 /*% */
 
@@ -1248,7 +1248,6 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
         */
        if (ztype == dns_zone_master) {
                isc_boolean_t allow = ISC_FALSE, maint = ISC_FALSE;
-               isc_boolean_t create = ISC_FALSE;
 
                obj = NULL;
                result = ns_config_get(maps, "check-wildcard", &obj);
@@ -1338,15 +1337,25 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
                                allow = ISC_TRUE;
                        else if (strcasecmp(arg, "maintain") == 0)
                                allow = maint = ISC_TRUE;
-                       else if (strcasecmp(arg, "create") == 0)
-                               allow = maint = create = ISC_TRUE;
                        else if (strcasecmp(arg, "off") == 0)
                                ;
                        else
                                INSIST(0);
                        dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow);
                        dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint);
-                       dns_zone_setkeyopt(zone, DNS_ZONEKEY_CREATE, create);
+               }
+
+               obj = NULL;
+               result = cfg_map_get(zoptions, "dnssec-update-mode", &obj);
+               if (result == ISC_R_SUCCESS) {
+                       const char *arg = cfg_obj_asstring(obj);
+                       if (strcasecmp(arg, "no-resign") == 0)
+                               dns_zone_setkeyopt(zone, DNS_ZONEKEY_NORESIGN,
+                                                  ISC_TRUE);
+                       else if (strcasecmp(arg, "maintain") == 0)
+                               ;
+                       else
+                               INSIST(0);
                }
        }
 
index d5ca8e8fd0bd6d08703d9df8f653b409a85e98b8..e4c1c2ad5cfe8f8a5f8b4d376edde2e5b58a9f6d 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: clean.sh,v 1.41 2011/03/07 14:03:49 marka Exp $
+# $Id: clean.sh,v 1.42 2011/05/23 20:10:02 each Exp $
 
 rm -f */K* */keyset-* */dsset-* */dlvset-* */signedkey-* */*.signed
 rm -f */trusted.conf */managed.conf */tmp* */*.jnl */*.bk
@@ -24,6 +24,7 @@ rm -f ns3/unsecure.example.db ns3/bogus.example.db ns3/keyless.example.db
 rm -f ns3/dynamic.example.db ns3/dynamic.example.db.signed.jnl
 rm -f ns3/rsasha256.example.db ns3/rsasha512.example.db
 rm -f ns3/split-dnssec.example.db
+rm -f ns3/expiring.example.db ns3/nosign.example.db
 rm -f ns2/private.secure.example.db
 rm -f ns2/badparam.db ns2/badparam.db.bad
 rm -f ns2/single-nsec3.db
@@ -56,3 +57,4 @@ rm -f signer/nsec3param.out
 rm -f ns3/ttlpatch.example.db ns3/ttlpatch.example.db.signed
 rm -f ns3/ttlpatch.example.db.patched
 rm -f ns3/split-smart.example.db
+rm -f nosign.before
index 4e320bbccb75b9fa6922a32773c5a2646d4865cd..2ed281d8d786e13926be86a2c8a3ae6ac4554ef7 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: named.conf,v 1.47 2011/05/19 00:31:57 smann Exp $ */
+/* $Id: named.conf,v 1.48 2011/05/23 20:10:02 each Exp $ */
 
 // NS3
 
@@ -229,4 +229,11 @@ zone "expiring.example" {
        file "expiring.example.db.signed";
 };
 
+zone "nosign.example" {
+       type master;
+       allow-update { any; };
+       dnssec-update-mode no-resign;
+       file "nosign.example.db.signed";
+};
+
 include "trusted.conf";
diff --git a/bin/tests/system/dnssec/ns3/nosign.example.db.in b/bin/tests/system/dnssec/ns3/nosign.example.db.in
new file mode 100644 (file)
index 0000000..c6a1860
--- /dev/null
@@ -0,0 +1,28 @@
+; Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+;
+; Permission to use, copy, modify, and/or distribute this software for any
+; purpose with or without fee is hereby granted, provided that the above
+; copyright notice and this permission notice appear in all copies.
+;
+; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+; AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+; PERFORMANCE OF THIS SOFTWARE.
+
+; $Id: nosign.example.db.in,v 1.2 2011/05/23 20:10:02 each Exp $
+
+$TTL 300       ; 5 minutes
+@                      IN SOA  mname1. . (
+                               2000042407 ; serial
+                               20         ; refresh (20 seconds)
+                               20         ; retry (20 seconds)
+                               1814400    ; expire (3 weeks)
+                               3600       ; minimum (1 hour)
+                               )
+                       NS      ns
+ns                     A       10.53.0.3
+
+a                      A       10.0.0.1
index 58e9ad1811222340c0811074968b10c410fbfb2e..24731960bddc986a86f8efb7ea5ac7227d183697 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: sign.sh,v 1.41 2011/05/19 00:31:57 smann Exp $
+# $Id: sign.sh,v 1.42 2011/05/23 20:10:02 each Exp $
 
 SYSTEMTESTTOP=../..
 . $SYSTEMTESTTOP/conf.sh
@@ -370,6 +370,9 @@ echo '$INCLUDE "'"$signedfile"'"' >> $zonefile
 : > $signedfile
 $SIGNER -P -S -r $RANDFILE -D -o $zone $zonefile > /dev/null 2>&1
 
+# 
+# Zone with signatures about to expire, but no private key to replace them
+#
 zone="expiring.example."
 infile="expiring.example.db.in"
 zonefile="expiring.example.db"
@@ -380,3 +383,20 @@ cp $infile $zonefile
 $SIGNER -S -r $RANDFILE -e now+1mi -o $zone $zonefile > /dev/null 2>&1
 rm -f ${zskname}.private ${kskname}.private
 
+#
+# Zone with signatures about to expire, and dynamic, but configured
+# not to resign with 'auto-resign no;'
+#
+zone="nosign.example."
+infile="nosign.example.db.in"
+zonefile="nosign.example.db"
+signedfile="nosign.example.db.signed"
+kskname=`$KEYGEN -q -r $RANDFILE $zone`
+zskname=`$KEYGEN -q -r $RANDFILE -f KSK $zone`
+cp $infile $zonefile
+$SIGNER -S -r $RANDFILE -e now+1mi -o $zone $zonefile > /dev/null 2>&1
+# preserve a normalized copy of the NS RRSIG for comparison later
+$CHECKZONE -D nosign.example nosign.example.db.signed 2>&- | \
+        awk '$4 == "RRSIG" && $5 == "NS" {$2 = ""; print}' | \
+        sed 's/[       ][      ]*/ /g'> ../nosign.before
+
index 58e8637e932405a1f8e53fd8869a94c609e43b14..e19bcb6b0aa2d76644f09c3ded5475b4cbbdfaf5 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: tests.sh,v 1.89 2011/05/19 00:31:57 smann Exp $
+# $Id: tests.sh,v 1.90 2011/05/23 20:10:02 each Exp $
 
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
@@ -1329,6 +1329,49 @@ ret=0
 $DIG +noall +answer +dnssec +nottl -p 5300 expiring.example ns @10.53.0.3 | grep RRSIG > dig.out.ns3.test$n 2>&1
 # there must be a signature here
 [ -s dig.out.ns3.test$n ] || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:testing new records are signed with 'no-resign' ($n)"
+ret=0
+(
+echo zone nosign.example
+echo server 10.53.0.3 5300
+echo update add new.nosign.example 300 in txt "hi there"
+echo send
+) | $NSUPDATE
+sleep 1
+$DIG +noall +answer +dnssec -p 5300 txt new.nosign.example @10.53.0.3 \
+        > dig.out.ns3.test$n 2>&1
+grep RRSIG dig.out.ns3.test$n > /dev/null 2>&1 || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:testing expiring records aren't resigned with 'no-resign' ($n)"
+ret=0
+$DIG +noall +answer +dnssec +nottl -p 5300 nosign.example ns @10.53.0.3 | \
+        grep RRSIG | sed 's/[  ][      ]*/ /g' > dig.out.ns3.test$n 2>&1
+# the NS RRSIG should not be changed
+cmp -s nosign.before dig.out.ns3.test$n || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:testing updates fail with no private key ($n)"
+ret=0
+rm -f ns3/Knosign.example.*.private
+(
+echo zone nosign.example
+echo server 10.53.0.3 5300
+echo update add fail.nosign.example 300 in txt "reject me"
+echo send
+) | $NSUPDATE > /dev/null 2>&1 && ret=1
+$DIG +noall +answer +dnssec -p 5300 fail.nosign.example txt @10.53.0.3 \
+        > dig.out.ns3.test$n 2>&1
+[ -s dig.out.ns3.test$n ] && ret=1
+n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
index 214cc9c331c784d1edd5d8b5471fc74f9e5d936a..79bb52c4d1ee8fe4a12d91fa3e57f420a095ddea 100644 (file)
@@ -18,7 +18,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- File: $Id: Bv9ARM-book.xml,v 1.491 2011/05/17 04:48:51 marka Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.492 2011/05/23 20:10:02 each Exp $ -->
 <book xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>BIND 9 Administrator Reference Manual</title>
 
@@ -1189,10 +1189,10 @@ zone "eng.example.com" {
                       <para>
                         This command requires that the
                         <command>auto-dnssec</command> zone option to be set
-                        to <literal>allow</literal>,
-                        <literal>maintain</literal>, or
-                        <literal>create</literal>,  and also requires
-                        the zone to be configured to allow dynamic DNS.
+                        to <literal>allow</literal> or
+                        <literal>maintain</literal>,
+                        and also requires the zone to be configured to
+                        allow dynamic DNS.
                         See <xref linkend="dynamic_update_policies"/> for
                         more details.
                       </para>
@@ -1218,9 +1218,9 @@ zone "eng.example.com" {
                       <para>
                         This command requires that the
                         <command>auto-dnssec</command> zone option to
-                        be set to <literal>maintain</literal> or
-                        <literal>create</literal>, and also requires
-                        the zone to be configured to allow dynamic DNS.
+                        be set to <literal>maintain</literal>,
+                        and also requires the zone to be configured to
+                        allow dynamic DNS.
                         See <xref linkend="dynamic_update_policies"/> for
                         more details.
                       </para>
@@ -5062,6 +5062,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
     <optional> allow-update { <replaceable>address_match_list</replaceable> }; </optional>
     <optional> allow-update-forwarding { <replaceable>address_match_list</replaceable> }; </optional>
     <optional> update-check-ksk <replaceable>yes_or_no</replaceable>; </optional>
+    <optional> dnssec-update-mode ( <replaceable>maintain</replaceable> | <replaceable>no-resign</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>
@@ -5852,6 +5853,41 @@ options {
             </listitem>
          </varlistentry>
 
+         <varlistentry>
+           <term><command>dnssec-update-mode</command></term>
+           <listitem>
+               <para>
+                  If this option is set to its default value of
+                  <literal>maintain</literal> in a zone of type
+                  <literal>master</literal> which is DNSSEC-signed
+                  and configured to allow dynamic updates (see
+                  <xref linkend="dynamic_update_policies"/>), and
+                  if <command>named</command> has access to the
+                  private signing key(s) for the zone, then
+                  <command>named</command> will automatically sign all new
+                  or changed records and maintain signatures for the zone
+                  by regenerating RRSIG records whenever they approach
+                  their expiration date.
+               </para>
+               <para>
+                  If the option is changed to <literal>no-resign</literal>,
+                  then <command>named</command> will sign all new or
+                  changed records, but scheduled maintenance of
+                  signatures is disabled.
+                </para>
+                <para>
+                  With either of these settings, <command>named</command>
+                  will reject updates to a DNSSEC-signed zone when the
+                  signing keys are inactive or unavailable to
+                  <command>named</command>.  (A planned third option,
+                  <literal>external</literal>, will disable all automatic
+                  signing and allow DNSSEC data to be submitted into a zone
+                  via dyanmic update; this is not yet implemented.)
+               </para>
+           </listitem>
+         </varlistentry>
+
+
         </variablelist>
 
         <sect3 id="boolean_options">
@@ -10052,7 +10088,7 @@ view "external" {
     <optional> min-retry-time <replaceable>number</replaceable> ; </optional>
     <optional> max-retry-time <replaceable>number</replaceable> ; </optional>
     <optional> key-directory <replaceable>path_name</replaceable>; </optional>
-    <optional> auto-dnssec <constant>allow</constant>|<constant>maintain</constant>|<constant>create</constant>|<constant>off</constant>; </optional>
+    <optional> auto-dnssec <constant>allow</constant>|<constant>maintain</constant>|<constant>off</constant>; </optional>
     <optional> zero-no-soa-ttl <replaceable>yes_or_no</replaceable> ; </optional>
 };
 
@@ -10064,6 +10100,7 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
     <optional> allow-transfer { <replaceable>address_match_list</replaceable> }; </optional>
     <optional> allow-update-forwarding { <replaceable>address_match_list</replaceable> }; </optional>
     <optional> update-check-ksk <replaceable>yes_or_no</replaceable>; </optional>
+    <optional> dnssec-update-mode ( <replaceable>maintain</replaceable> | <replaceable>no-resign</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>
@@ -10666,6 +10703,16 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
                 </listitem>
               </varlistentry>
 
+             <varlistentry>
+               <term><command>dnssec-update-mode</command></term>
+                <listitem>
+                  <para>
+                    See the description of
+                    <command>dnssec-update-mode</command> in <xref linkend="options"/>.
+                  </para>
+                </listitem>
+              </varlistentry>
+
              <varlistentry>
                <term><command>dnssec-dnskey-kskonly</command></term>
                 <listitem>
@@ -11141,7 +11188,7 @@ example.com. NS ns2.example.net.
                   <para>
                     Zones configured for dynamic DNS may also use this
                     option to allow varying levels of automatic DNSSEC key
-                    management. There are four possible settings:
+                    management. There are three possible settings:
                   </para>
                   <para>
                     <command>auto-dnssec allow;</command> permits
@@ -11172,13 +11219,6 @@ example.com. NS ns2.example.net.
                     interval is defined by
                     <command>dnssec-loadkeys-interval</command>.)
                   </para>
-                  <para>
-                    <command>auto-dnssec create;</command> includes the
-                    above, but also allows <command>named</command>
-                    to create new keys in the key repository when needed.
-                    (NOTE: This option is not yet implemented; the syntax is
-                    being reserved for future use.)
-                  </para>
                   <para>
                     The default setting is <command>auto-dnssec off</command>.
                   </para>
index 043d0371cb1bae021e0c491ad01ece63dc1a60ef..496dfe251494e49ba61981d40b3f9808d6395912 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.h,v 1.188 2011/05/06 21:23:51 each Exp $ */
+/* $Id: zone.h,v 1.189 2011/05/23 20:10:03 each Exp $ */
 
 #ifndef DNS_ZONE_H
 #define DNS_ZONE_H 1
@@ -93,6 +93,7 @@ typedef enum {
 #define DNS_ZONEKEY_MAINTAIN   0x00000002U     /*%< publish/sign on schedule */
 #define DNS_ZONEKEY_CREATE     0x00000004U     /*%< make keys when needed */
 #define DNS_ZONEKEY_FULLSIGN    0x00000008U     /*%< roll to new keys immediately */
+#define DNS_ZONEKEY_NORESIGN   0x00000010U     /*%< no automatic resigning */
 
 #ifndef DNS_ZONE_MINREFRESH
 #define DNS_ZONE_MINREFRESH                300 /*%< 5 minutes */
index 03cc0f202c12fbc241a3f9c71069d9ed8c3e500b..38e3ce6ff009a36584be07ad64f19e71de7e136a 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.610 2011/05/19 23:47:17 tbox Exp $ */
+/* $Id: zone.c,v 1.611 2011/05/23 20:10:02 each Exp $ */
 
 /*! \file */
 
@@ -3625,6 +3625,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
                }
 
                if (zone->type == dns_zone_master &&
+                   !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
                    dns_zone_isdynamic(zone, ISC_FALSE) &&
                    dns_db_issecure(db)) {
                        dns_name_t *name;
@@ -4956,10 +4957,14 @@ zone_resigninc(dns_zone_t *zone) {
        dns_diff_init(zone->mctx, &sig_diff);
        sig_diff.resign = zone->sigresigninginterval;
 
+
        /*
-        * Updates are disabled.  Pause for 5 minutes.
+        * Zone is frozen or automatic resigning is disabled.
+        * Pause for 5 minutes.
         */
-       if (zone->update_disabled) {
+       if (zone->update_disabled ||
+           DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
+       {
                result = ISC_R_FAILURE;
                goto failure;
        }
index 7baca1c38c9a477d1543d7b9475bd1396a90e77a..491ab71390311894bf7443f0f3b6778c111139c3 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: namedconf.c,v 1.137 2011/05/07 05:55:17 each Exp $ */
+/* $Id: namedconf.c,v 1.138 2011/05/23 20:10:03 each Exp $ */
 
 /*! \file */
 
@@ -541,13 +541,18 @@ static cfg_type_t cfg_type_bracketed_sockaddrlist = {
        &cfg_rep_list, &cfg_type_sockaddr
 };
 
-static const char *autodnssec_enums[] = { "allow", "maintain", "create",
-                                         "off", NULL };
+static const char *autodnssec_enums[] = { "allow", "maintain", "off", NULL };
 static cfg_type_t cfg_type_autodnssec = {
        "autodnssec", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
        &cfg_rep_string, &autodnssec_enums
 };
 
+static const char *dnssecupdatemode_enums[] = { "maintain", "no-resign", NULL };
+static cfg_type_t cfg_type_dnssecupdatemode = {
+       "dnssecupdatemode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
+       &cfg_rep_string, &dnssecupdatemode_enums
+};
+
 static cfg_type_t cfg_type_rrsetorder = {
        "rrsetorder", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list,
        &cfg_rep_list, &cfg_type_rrsetorderingelement
@@ -1360,6 +1365,7 @@ zone_clauses[] = {
        { "dnssec-dnskey-kskonly", &cfg_type_boolean, 0 },
        { "dnssec-loadkeys-interval", &cfg_type_uint32, 0 },
        { "dnssec-secure-to-insecure", &cfg_type_boolean, 0 },
+       { "dnssec-update-mode", &cfg_type_dnssecupdatemode, 0 },
        { "forward", &cfg_type_forwardtype, 0 },
        { "forwarders", &cfg_type_portiplist, 0 },
        { "key-directory", &cfg_type_qstring, 0 },