<!--
 - Copyright (C) Internet Systems Consortium, Inc. ("ISC")
 -
 - 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 http://mozilla.org/MPL/2.0/.
 -
 - See the COPYRIGHT file distributed with this work for additional
 - information regarding copyright ownership.
-->

<!-- Converted by db4-upgrade version 1.0 -->
<section xmlns:db="http://docbook.org/ns/docbook" version="5.0" xml:id="dnssec.dynamic.zones"><info><title>DNSSEC, Dynamic Zones, and Automatic Signing</title></info>

  <section><info><title>Converting from insecure to secure</title></info>

  </section>
  <para>
    Changing a zone from insecure to secure can be done in three
    ways: using a dynamic DNS update, use the
    <command>auto-dnssec</command> zone option, or set a DNSSEC
    policy for the zone with <command>dnssec-policy</command>.
  </para>
  <para>
    For either method, you need to configure
    <command>named</command> so that it can see the
    <filename>K*</filename> files which contain the public and private
    parts of the keys that will be used to sign the zone. These files
    will have been generated by
    <command>dnssec-keygen</command> (or created when needed by
    <command>named</command> if <command>dnssec-policy</command> is
    used).  Keys should be placed in the key-directory, as specified in
    <filename>named.conf</filename>:</para>
    <programlisting>
	zone example.net {
		type master;
		update-policy local;
		file "dynamic/example.net/example.net";
		key-directory "dynamic/example.net";
	};
  </programlisting>
  <para>
    If one KSK and one ZSK DNSKEY key have been generated, this
    configuration will cause all records in the zone to be signed
    with the ZSK, and the DNSKEY RRset to be signed with the KSK as
    well. An NSEC chain will be generated as part of the initial
    signing process.
  </para>
  <para>
    With <command>dnssec-policy</command> you specify what keys should
    be KSK and/or ZSK. If you want a key to sign all records with a key
    you will need to specify a CSK:
  </para>
  <programlisting>
	dnssec-policy csk {
		keys {
			csk key-directory lifetime P5Y algorithm 13;
		};
	};
  </programlisting>

  <section><info><title>Dynamic DNS update method</title></info>

  </section>
  <para>To insert the keys via dynamic update:</para>
  <screen>
	% nsupdate
	&gt; ttl 3600
	&gt; update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8=
	&gt; update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
	&gt; send
</screen>
  <para>
    While the update request will complete almost immediately,
    the zone will not be completely signed until
    <command>named</command> has had time to walk the zone and
    generate the NSEC and RRSIG records. The NSEC record at the apex
    will be added last, to signal that there is a complete NSEC
    chain.
  </para>
  <para>
    If you wish to sign using NSEC3 instead of NSEC, you should
    add an NSEC3PARAM record to the initial update request. If you
    wish the NSEC3 chain to have the OPTOUT bit set, set it in the
    flags field of the NSEC3PARAM record.
  </para>
  <screen>
	% nsupdate
	&gt; ttl 3600
	&gt; update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8=
	&gt; update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
	&gt; update add example.net NSEC3PARAM 1 1 100 1234567890
	&gt; send
</screen>
  <para>
    Again, this update request will complete almost
    immediately; however, the record won't show up until
    <command>named</command> has had a chance to build/remove the
    relevant chain. A private type record will be created to record
    the state of the operation (see below for more details), and will
    be removed once the operation completes.
  </para>
  <para>
    While the initial signing and NSEC/NSEC3 chain generation
    is happening, other updates are possible as well.
  </para>

  <section><info><title>Fully automatic zone signing</title></info>

  </section>
  <para>
    To enable automatic signing, you can set a
    <command>dnssec-policy</command>, or add the
    <command>auto-dnssec</command> option to the zone statement in
    <filename>named.conf</filename>.
    <command>auto-dnssec</command> has two possible arguments:
    <constant>allow</constant> or
    <constant>maintain</constant>.
  </para>
  <para>
    With <command>auto-dnssec allow</command>,
    <command>named</command> can search the key directory for keys
    matching the zone, insert them into the zone, and use them to
    sign the zone. It will do so only when it receives an
    <command>rndc sign &lt;zonename&gt;</command>.
  </para>
  <para>
    <!-- TODO: this is repeated in the ARM -->
    <command>auto-dnssec maintain</command> includes the above
    functionality, but will also automatically adjust the zone's
    DNSKEY records on schedule according to the keys' timing metadata.
    (See <xref linkend="man.dnssec-keygen"/> and
    <xref linkend="man.dnssec-settime"/> for more information.)
  </para>
  <para>
    <command>dnssec-policy</command> is like
    <command>auto-dnssec maintain</command>, but will also automatically
    create new keys when necessary.  Also any configuration related
    to DNSSEC signing is retrieved from the policy (ignoring existing
    DNSSEC named.conf options).
  </para>
  <para>
    <command>named</command> will periodically search the key directory
    for keys matching the zone, and if the keys' metadata indicates
    that any change should be made the zone, such as adding, removing,
    or revoking a key, then that action will be carried out.  By default,
    the key directory is checked for changes every 60 minutes; this period
    can be adjusted with the <option>dnssec-loadkeys-interval</option>, up
    to a maximum of 24 hours.  The <command>rndc loadkeys</command> forces
    <command>named</command> to check for key updates immediately.
  </para>
  <para>
    If keys are present in the key directory the first time the zone
    is loaded, the zone will be signed immediately, without waiting for an
    <command>rndc sign</command> or <command>rndc loadkeys</command>
    command. (Those commands can still be used when there are unscheduled
    key changes, however.)
  </para>
  <para>
    When new keys are added to a zone, the TTL is set to match that
    of any existing DNSKEY RRset. If there is no existing DNSKEY RRset,
    then the TTL will be set to the TTL specified when the key was
    created (using the <command>dnssec-keygen -L</command> option), if
    any, or to the SOA TTL.
  </para>
  <para>
    If you wish the zone to be signed using NSEC3 instead of NSEC,
    submit an NSEC3PARAM record via dynamic update prior to the
    scheduled publication and activation of the keys.  If you wish the
    NSEC3 chain to have the OPTOUT bit set, set it in the flags field
    of the NSEC3PARAM record.  The NSEC3PARAM record will not appear in
    the zone immediately, but it will be stored for later reference.  When
    the zone is signed and the NSEC3 chain is completed, the NSEC3PARAM
    record will appear in the zone.
  </para>
  <para>
    Using the
    <command>auto-dnssec</command> option requires the zone to be
    configured to allow dynamic updates, by adding an
    <command>allow-update</command> or
    <command>update-policy</command> statement to the zone
    configuration. If this has not been done, the configuration will
    fail.
  </para>

  <section><info><title>Private-type records</title></info>

  </section>
  <para>
    The state of the signing process is signaled by
    private-type records (with a default type value of 65534). When
    signing is complete, these records will have a nonzero value for
    the final octet (for those records which have a nonzero initial
    octet).
  </para>
  <para>
    The private type record format: If the first octet is
    non-zero then the record indicates that the zone needs to be
    signed with the key matching the record, or that all signatures
    that match the record should be removed.
  </para>
  <para>
    <literallayout>
<!-- TODO: how to format this? -->
  algorithm (octet 1)
  key id in network order (octet 2 and 3)
  removal flag (octet 4)
  complete flag (octet 5)
</literallayout>
  </para>
  <para>
    Only records flagged as "complete" can be removed via
    dynamic update. Attempts to remove other private type records
    will be silently ignored.
  </para>
  <para>
    If the first octet is zero (this is a reserved algorithm
    number that should never appear in a DNSKEY record) then the
    record indicates changes to the NSEC3 chains are in progress. The
    rest of the record contains an NSEC3PARAM record. The flag field
    tells what operation to perform based on the flag bits.
  </para>
  <para>
    <literallayout>
<!-- TODO: how to format this? -->
  0x01 OPTOUT
  0x80 CREATE
  0x40 REMOVE
  0x20 NONSEC
</literallayout>
  </para>
  <section><info><title>DNSKEY rollovers</title></info>

  </section>
  <para>
    As with insecure-to-secure conversions, rolling DNSSEC
    keys can be done in two ways: using a dynamic DNS update, or the
    <command>auto-dnssec</command> zone option.
  </para>

  <section><info><title>Dynamic DNS update method</title></info>

  </section>
  <para>
    To perform key rollovers via dynamic update, you need to add
    the <filename>K*</filename> files for the new keys so that
    <command>named</command> can find them. You can then add the new
    DNSKEY RRs via dynamic update.
    <command>named</command> will then cause the zone to be signed
    with the new keys. When the signing is complete the private type
    records will be updated so that the last octet is non
    zero.
  </para>
  <para>
    If this is for a KSK you need to inform the parent and any
    trust anchor repositories of the new KSK.
  </para>
  <para>
    You should then wait for the maximum TTL in the zone before
    removing the old DNSKEY. If it is a KSK that is being updated,
    you also need to wait for the DS RRset in the parent to be
    updated and its TTL to expire. This ensures that all clients will
    be able to verify at least one signature when you remove the old
    DNSKEY.
  </para>
  <para>
    The old DNSKEY can be removed via UPDATE. Take care to
    specify the correct key.
    <command>named</command> will clean out any signatures generated
    by the old key after the update completes.
  </para>

  <section><info><title>Automatic key rollovers</title></info>

  </section>
  <para>
    When a new key reaches its activation date (as set by
    <command>dnssec-keygen</command> or <command>dnssec-settime</command>),
    if the <command>auto-dnssec</command> zone option is set to
    <constant>maintain</constant>, <command>named</command> will
    automatically carry out the key rollover.  If the key's algorithm
    has not previously been used to sign the zone, then the zone will
    be fully signed as quickly as possible.  However, if the new key
    is replacing an existing key of the same algorithm, then the
    zone will be re-signed incrementally, with signatures from the
    old key being replaced with signatures from the new key as their
    signature validity periods expire.  By default, this rollover
    completes in 30 days, after which it will be safe to remove the
    old key from the DNSKEY RRset.
  </para>

  <section><info><title>NSEC3PARAM rollovers via UPDATE</title></info>

  </section>
  <para>
    Add the new NSEC3PARAM record via dynamic update. When the
    new NSEC3 chain has been generated, the NSEC3PARAM flag field
    will be zero. At this point you can remove the old NSEC3PARAM
    record. The old chain will be removed after the update request
    completes.
  </para>

  <section><info><title>Converting from NSEC to NSEC3</title></info>

  </section>
  <para>
    To do this, you just need to add an NSEC3PARAM record. When
    the conversion is complete, the NSEC chain will have been removed
    and the NSEC3PARAM record will have a zero flag field. The NSEC3
    chain will be generated before the NSEC chain is
    destroyed.
  </para>
  <para>
    NSEC3 is not supported yet with <command>dnssec-policy</command>.
  </para>

  <section><info><title>Converting from NSEC3 to NSEC</title></info>

  </section>
  <para>
    To do this, use <command>nsupdate</command> to
    remove all NSEC3PARAM records with a zero flag
    field. The NSEC chain will be generated before the NSEC3 chain is
    removed.
  </para>

  <section><info><title>Converting from secure to insecure</title></info>

  </section>
  <para>
    To convert a signed zone to unsigned using dynamic DNS,
    delete all the DNSKEY records from the zone apex using
    <command>nsupdate</command>. All signatures, NSEC or NSEC3 chains,
    and associated NSEC3PARAM records will be removed automatically.
    This will take place after the update request completes.</para>
    <para> This requires the
    <command>dnssec-secure-to-insecure</command> option to be set to
    <userinput>yes</userinput> in
    <filename>named.conf</filename>.</para>
    <para>In addition, if the <command>auto-dnssec maintain</command>
    zone statement is used, it should be removed or changed to
    <command>allow</command> instead (or it will re-sign).
  </para>

  <section><info><title>Periodic re-signing</title></info>

  </section>
  <para>
    In any secure zone which supports dynamic updates, <command>named</command>
    will periodically re-sign RRsets which have not been re-signed as
    a result of some update action. The signature lifetimes will be
    adjusted so as to spread the re-sign load over time rather than
    all at once.
  </para>

  <section><info><title>NSEC3 and OPTOUT</title></info>

  </section>
  <para>
    <command>named</command> only supports creating new NSEC3 chains
    where all the NSEC3 records in the zone have the same OPTOUT
    state.
    <command>named</command> supports UPDATES to zones where the NSEC3
    records in the chain have mixed OPTOUT state.
    <command>named</command> does not support changing the OPTOUT
    state of an individual NSEC3 record, the entire chain needs to be
    changed if the OPTOUT state of an individual NSEC3 needs to be
    changed.
  </para>
</section>
