From fb24454c5876af9445054d4fe82297b0df0d28d6 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Wed, 11 May 2022 09:39:44 +0200 Subject: [PATCH 01/22] Nit changes in introduction of DNSSEC chapter DNSSEC-bis is an uncommon term. Other servers are typically resolvers and they usually are configured with the root key. --- doc/arm/dnssec.inc.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index ac92aedd0e..2dffeef121 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -15,7 +15,7 @@ DNSSEC ------ Cryptographic authentication of DNS information is possible through the -DNS Security ("DNSSEC-bis") extensions, defined in :rfc:`4033`, :rfc:`4034`, +DNS Security Extensions (DNSSEC), defined in :rfc:`4033`, :rfc:`4034`, and :rfc:`4035`. This section describes the creation and use of DNSSEC signed zones. @@ -32,9 +32,10 @@ indicated by the parent zone for a DNSSEC-capable resolver to trust its data. This is done through the presence or absence of a ``DS`` record at the delegation point. -For other servers to trust data in this zone, they must be -statically configured with either this zone's zone key or the zone key of -another zone above this one in the DNS tree. +For resolvers to trust data in this zone, they must be configured with a trust +anchor. Typically this is the public key of the DNS root zone, although you +can also configure a trust anchor that is the public key of this zone or +another zone above this on in the DNS tree. .. _generating_dnssec_keys: From a1c95e8e7c1d4595758060310260d60bc3f8f987 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Wed, 11 May 2022 11:04:47 +0200 Subject: [PATCH 02/22] Rewrite DNSSEC chapter - signing Restructure the first part of the DNSSEC chapter that deals with zone signing. Put dnssec-policy first. Mention Key and Signing Policy. Only then talk about the DNSSEC tools. --- doc/arm/dnssec.inc.rst | 118 +++++++++++++++++++++++++++++++++++------ 1 file changed, 102 insertions(+), 16 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index 2dffeef121..02bd96262f 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -37,25 +37,115 @@ anchor. Typically this is the public key of the DNS root zone, although you can also configure a trust anchor that is the public key of this zone or another zone above this on in the DNS tree. -.. _generating_dnssec_keys: +.. _dnssec_keys: DNSSEC Keys ~~~~~~~~~~~ -Generating Keys -^^^^^^^^^^^^^^^ - -The :iscman:`dnssec-keygen` program is used to generate keys. - A secure zone must contain one or more zone keys. The zone keys sign all other records in the zone, as well as the zone keys of any -secure delegated zones. Zone keys must have the same name as the zone, have a +secure delegated zones. It is recommended that zone keys use one of the +cryptographic algorithms designated as "mandatory to implement" by the +IETF, that is either RSASHA256 or ECDSAP256SHA256. + +Zone keys must have the same name as the zone, have a name type of ``ZONE``, and be usable for authentication. It is recommended that zone keys use a cryptographic algorithm designated as "mandatory to implement" by the IETF. Currently there are two algorithms, RSASHA256 and ECDSAP256SHA256; ECDSAP256SHA256 is recommended for current and future deployments. +Keys are stored in files, ``Kdnssec.example.+013+12345.key`` and +``Kdnssec.example.+013+12345.private`` (where 12345 is an example of a +key tag). The key filenames contain the key name (``dnssec.example.``), +the algorithm (5 is RSASHA1, 8 is RSASHA256, 13 is ECDSAP256SHA256, 15 is +ED25519, etc.), and the key tag (12345 in this case). The private key (in +the ``.private`` file) is used to generate signatures, and the public +key (in the ``.key`` file) is used for signature verification. + +.. _dnssec_zone_signing: + +Zone Signing +~~~~~~~~~~~~ + +To sign a zone, configure a key and signing policy for the zone. The +configuration below will sign the zone ``dnssec.example`` according to the +built-in default policy: + +:: + + zone "dnssec.example" { + type primary; + dnssec-policy default; + file "dnssec.example.db"; + }; + +.. + +This will create the necessary keys and generates ``DNSKEY``, ``RRSIG`` and +``NSEC`` records for the zone. BIND will now also take care of any DNSSEC +maintenance for this zone, including replacing signatures that are about to +expire and managing key rollovers. + +The file ``dnssec.example.db`` remains untouched and the signed zone is stored +on disk in ``dnssec.example.db.signed``. In addition to the +``Kdnssec.example.+013+12345.key`` and ``Kdnssec.example.+013+12345.private`` +key files, this method stores another file on disk, +``Kdnssec.example+013+12345.state``, that tracks DNSSEC key timings and are +used to perform key rollovers safely. + +The default policy creates one key that is used to sign the complete zone, +and uses ``NSEC`` to enable authenticated denial of existence (a secure way +to tell which records do not exist in your zone). How to create your own +policy is decribed in the section below. + +.. _dnssec_kasp: + +Key and Signing Policy +^^^^^^^^^^^^^^^^^^^^^^ + +A key and signing policy (KASP) is a piece of configuration that describes +how to make a zone DNSSEC secure. The built-in ``default`` policy uses the most +common DNSSEC practices, but you can define a custom policy by adding a +``dnssec-policy`` clause in your configuration: + +:: + + dnssec-policy "custom" { + dnskey-ttl 600; + keys { + ksk lifetime PT1Y algorithm rsasha256 2048; + zsk lifetime 60d algorithm rsasha256 2048; + }; + }; + +.. + +This ``custom`` policy for example, uses a short ``DNSKEY`` TTL (600 seconds) +and it uses two keys to sign the zone (a KSK to sign the key related RRsets, +``DNSKEY``, ``CDS``, and ``CDNSKEY``, and a ZSK to sign the rest of the zone). +The configured keys also have a lifetime set and use a different algorithm. + +``dnssec-policy`` is described in more detail later in this document. + +The :ref:`dnssec_advanced_discussions` in the DNSSEC Guide discusses the +various policy settings and may help you determining which values you should +use. + +.. _dnssec_tools: + +DNSSEC Tools +^^^^^^^^^^^^ + +There are several tools available if you want to sign your zone manually. + +.. warning:: + + Please note manual procedures are available mainly for backwards + compatibility and should be used only by expert users with specific needs. + +The :iscman:`dnssec-keygen` program is used to generate keys. + The following command generates an ECDSAP256SHA256 key for the ``child.example`` zone: @@ -79,17 +169,13 @@ crypto hardware device and build the key files. Its usage is similar to The public keys should be inserted into the zone file by including the ``.key`` files using ``$INCLUDE`` statements. -.. _dnssec_zone_signing: - -Signing the Zone -^^^^^^^^^^^^^^^^ - The :iscman:`dnssec-signzone` program is used to sign a zone. Any ``keyset`` files corresponding to secure sub-zones should be present. The zone signer generates ``NSEC``, ``NSEC3``, and ``RRSIG`` -records for the zone, as well as ``DS`` for the child zones if :option:`-g ` -is specified. If :option:`-g ` is not specified, then DS RRsets for the +records for the zone, as well as ``DS`` for the child zones if +:option:`-g ` is specified. If +:option:`-g ` is not specified, then DS RRsets for the secure child zones need to be added manually. By default, all zone keys which have an available private key are used @@ -107,8 +193,8 @@ corresponding ``DS`` records) that are the secure entry point to the zone. .. _dnssec_config: -Configuring Servers for DNSSEC -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +DNSSEC Validation +~~~~~~~~~~~~~~~~~ To enable :iscman:`named` to validate answers received from other servers, the ``dnssec-validation`` option must be set to either ``yes`` or ``auto``. From 34dea43f9c2aa27e2c03526e8b486a69b31f063d Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Wed, 11 May 2022 11:10:04 +0200 Subject: [PATCH 03/22] Rewrap a paragraph in DNSSEC Validation section No textual changes, just rewrapping to 80 characters. --- doc/arm/dnssec.inc.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index 02bd96262f..6a512ec4f0 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -215,10 +215,10 @@ The default is ``auto`` unless BIND is built with ``configure --disable-auto-validation``, in which case the default is ``yes``. -The keys specified in ``trust-anchors`` are copies of DNSKEY RRs for zones that are -used to form the first link in the cryptographic chain of trust. Keys configured -with the keyword ``static-key`` or ``static-ds`` are loaded directly into the -table of trust anchors, and can only be changed by altering the +The keys specified in ``trust-anchors`` are copies of ``DNSKEY`` RRs for zones +that are used to form the first link in the cryptographic chain of trust. Keys +configured with the keyword ``static-key`` or ``static-ds`` are loaded directly +into the table of trust anchors, and can only be changed by altering the configuration. Keys configured with ``initial-key`` or ``initial-ds`` are used to initialize :rfc:`5011` trust anchor maintenance, and are kept up-to-date automatically after the first time :iscman:`named` runs. From 71490a5a2d1eddb99f8d640f595f0a06426b17e4 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Wed, 11 May 2022 12:09:43 +0200 Subject: [PATCH 04/22] Add a section about Denial of Existence Move bits from the "DNSSEC, Dynamic Zones, and Automatic Signing" about denial of existence to a separate section below the "Key and Signing Policy" section. Add a brief introduction about denial of existence to this section. --- doc/arm/dnssec.inc.rst | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index 6a512ec4f0..e09d4d16d7 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -132,6 +132,50 @@ The :ref:`dnssec_advanced_discussions` in the DNSSEC Guide discusses the various policy settings and may help you determining which values you should use. +.. _dnssec_denial_of_existence: + +Denial of Existence +^^^^^^^^^^^^^^^^^^^ + +To prove that some data does not exist in the zone, ``NSEC`` records are added +to the zone for each domain name. This record contains a list that tells +which record types are present at that name, so that if a query comes in for +a type that is not in the list, the requestor can proof its non-existence. +The ``NSEC`` record also contains a next owner name, proving that all names +between the owner name and next owner name do not exist. + +The ``NSEC`` method allows for trivial zone walking, where one would query +for the apex ``NSEC`` record and then queries the ``NSEC`` of each next owner +name to learn about all names that exist in a certain zone. While this may not +be a problem for most, you can mitigate against this by using ``NSEC3``, hashed +denial of existence (defined in :rfc:`5155`). This uses one-way hashes to +obfuscate the next owner names. + +With ``NSEC3`` you can also opt-out insecure delegations from denial of +existence, which may be useful for parent zones with a lot of insecure child +zones. + +To enable ``NSEC3``, add an ``nsec3param`` option to your DNSSEC Policy: + +:: + + dnssec-policy "nsec3" { + nsec3param iterations 5 optout yes salt-length 8; + }; + +.. + +The ``nsec3`` policy above creates ``NSEC3`` records using the SHA-1 hash +algorithm, using 5 iterations and a salt that is 8 characters long. It also +skips insecure delegations. + +The ``NSEC3`` chain is generated and the ``NSEC3PARAM`` record is added before +the existing ``NSEC`` chain (if any) is destroyed. + +You can also switch back to ``NSEC`` by removing the ``nsec3param`` option. +In this case, the ``NSEC`` chain is generated before the ``NSEC3`` chain +is removed. + .. _dnssec_tools: DNSSEC Tools From be54c08d2b6da73c47c707cab79dbda6833f9623 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 12 May 2022 10:26:25 +0200 Subject: [PATCH 05/22] Rewrite Dynamic Zones section Restructure the section about dynamic zones and automatic signing: - Focus on dynamic zones with 'auto-dnssec allow;'. - Add a section about multi-signer models. - Move NSEC3 related topics into one section. - Remove any text that does not concern dynamic zones (mostly duplicate text anyway). --- doc/arm/dnssec.inc.rst | 319 ++++++++++++++++------------------------- 1 file changed, 123 insertions(+), 196 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index e09d4d16d7..4f5dddb700 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -354,50 +354,73 @@ according to its parent, should have been secure. .. _dnssec_dynamic_zones: -DNSSEC, Dynamic Zones, and Automatic Signing -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Dynamic Zones +~~~~~~~~~~~~~ -Converting From Insecure to Secure -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +When setting a ``dnssec-policy`` for a zone, it typically creates a new file +with a ``.signed`` extension on disk, while the original zone file stays +untouched. This is called inline signing. -A zone can be changed from insecure to secure in three ways: using a -dynamic DNS update, via the ``auto-dnssec`` zone option, or by setting a -DNSSEC policy for the zone with ``dnssec-policy``. +This works a bit different for dynamic zones. Zones with an update ACL or update +policy will have the DNSSEC related records applied directly to the zone, +similar to the non-DNSSEC records, instead of storing them in a file with +``.signed`` extension. -For any method, :iscman:`named` must be configured so that it can see -the ``K*`` files which contain the public and private parts of the keys -that are used to sign the zone. These files are generated -by :iscman:`dnssec-keygen`, or created when needed by :iscman:`named` if -``dnssec-policy`` is used. Keys should be placed in the -key-directory, as specified in :iscman:`named.conf`: +.. _dnssec_dynamic_zones_multisigner_model: + +Multi-Signer Model +^^^^^^^^^^^^^^^^^^ + +Dynamic zones provide the ability to sign a zone by multiple providers, meaning +each provider signs and serves the same zone independently. Such a setup requires +some coordination between providers when it comes to key rollovers, and may be +better suited to be configured with ``auto-dnssec allow;``. This permits keys to +be updated and the zone to be re-signed only if the user issues the command +:option:`rndc sign zonename `. + +A zone can also be configured with ``auto-dnssec maintain``, which automatically +adjusts the zone's DNSSEC keys on a schedule according to the key timing +metadata. However, keys still need to be generated separately, for +example with :iscman:`dnssec-keygen`. + +Of course, dynamic zones can also use ``dnssec-policy`` to fully automate DNSSEC +maintenance. The next sections assume that more key +management control is needed, and describe how to use dynamic DNS update to perform +various DNSSEC operations. + +.. _dnssec_dynamic_zones_enabling_dnssec: + +Enabling DNSSEC Manually +^^^^^^^^^^^^^^^^^^^^^^^^ +As an alternative to fully automated zone signing using :ref:`dnssec-policy +`, a zone can be changed from insecure to secure using a dynamic +DNS update. :iscman:`named` must be configured so that it can see the ``K*`` +files which contain the public and private parts of the keys that are used to +sign the zone. Key files should be placed in the key-directory, as specified in +:iscman:`named.conf`: :: - zone example.net { + zone update.example { type primary; update-policy local; - file "dynamic/example.net/example.net"; - key-directory "dynamic/example.net"; + auto-dnssec allow; + file "dynamic/update.example.db"; + key-directory "keys/update.example/"; }; -If one KSK and one ZSK DNSKEY key have been generated, this -configuration causes all records in the zone to be signed with the -ZSK, and the DNSKEY RRset to be signed with the KSK. An NSEC -chain is generated as part of the initial signing process. +If there are both a KSK and a ZSK available (or a CSK), this configuration causes the +zone to be signed. An ``NSEC`` chain is generated as part of the initial signing +process. -With ``dnssec-policy``, it is possible to specify which keys should be -KSK and/or ZSK. To sign all records with a key, a CSK must be specified. -For example: +In any secure zone which supports dynamic updates, :iscman:`named` periodically +re-signs RRsets which have not been re-signed as a result of some update action. +The signature lifetimes are adjusted to spread the re-sign load over time rather +than all at once. -:: +.. _dnssec_dynamic_zones_publishing_dnskey_records: - dnssec-policy csk { - keys { - csk lifetime unlimited algorithm 13; - }; - }; - -Dynamic DNS Update Method +Publishing DNSKEY Records ^^^^^^^^^^^^^^^^^^^^^^^^^ To insert the keys via dynamic update: @@ -406,14 +429,17 @@ To insert the keys via dynamic update: % nsupdate > ttl 3600 - > update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8= - > update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk= + > update add update.example DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8= + > update add update.example DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk= > send -While the update request completes almost immediately, the zone is -not completely signed until :iscman:`named` has had time to "walk" the zone -and generate the NSEC and RRSIG records. The NSEC record at the apex -is added last, to signal that there is a complete NSEC chain. +In order to sign with these keys, the corresponding key files should also be +placed in the ``key-directory``. + +.. _dnssec_dynamic_zones_nsec3: + +NSEC3 +^^^^^ To sign using :ref:`NSEC3 ` instead of :ref:`NSEC `, add an NSEC3PARAM record to the initial update @@ -425,84 +451,50 @@ NSEC3PARAM record. % nsupdate > ttl 3600 - > update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8= - > update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk= - > update add example.net NSEC3PARAM 1 1 100 1234567890 + > update add update.example DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8= + > update add update.example DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk= + > update add update.example NSEC3PARAM 1 0 0 - > send -Again, this update request completes almost immediately; however, -the record does not show up until :iscman:`named` has had a chance to -build/remove the relevant chain. A private type record is created -to record the state of the operation (see below for more details), and +Note that the ``NSEC3PARAM`` record does not show up until :iscman:`named` has +had a chance to build/remove the relevant chain. A private type record is +created to record the state of the operation (see below for more details), and is removed once the operation completes. -While the initial signing and NSEC/NSEC3 chain generation is happening, +The ``NSEC3`` chain is generated and the ``NSEC3PARAM`` record is added before +the ``NSEC`` chain is destroyed. + +While the initial signing and ``NSEC``/``NSEC3`` chain generation are occurring, other updates are possible as well. -Fully Automatic Zone Signing -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +A new ``NSEC3PARAM`` record can be added via dynamic update. When the new +``NSEC3`` chain has been generated, the ``NSEC3PARAM`` flag field is set to +zero. At that point, the old ``NSEC3PARAM`` record can be removed. The old +chain is removed after the update request completes. -To enable automatic signing, set a ``dnssec-policy`` or add the -``auto-dnssec`` option to the zone statement in :iscman:`named.conf`. -``auto-dnssec`` has two possible arguments: ``allow`` or ``maintain``. +:iscman:`named` only supports creating new ``NSEC3`` chains where all the +``NSEC3`` records in the zone have the same ``OPTOUT`` state. :iscman:`named` +supports updates to zones where the ``NSEC3`` records in the chain have mixed +``OPTOUT`` state. :iscman:`named` does not support changing the ``OPTOUT`` +state of an individual ``NSEC3`` record; if the ``OPTOUT`` state of an +individual ``NSEC3`` needs to be changed, the entire chain must be changed. -With ``auto-dnssec allow``, :iscman:`named` can search the key directory for -keys matching the zone, insert them into the zone, and use them to sign -the zone. It does so only when it receives an -:option:`rndc sign zonename `. +To switch back to ``NSEC``, use :iscman:`nsupdate` to remove any ``NSEC3PARAM`` +records. The ``NSEC`` chain is generated before the ``NSEC3`` chain is removed. -``auto-dnssec maintain`` includes the above functionality, but also -automatically adjusts the zone's DNSKEY records on a schedule according to -the keys' timing metadata. (See :ref:`man_dnssec-keygen` and -:ref:`man_dnssec-settime` for more information.) - -``dnssec-policy`` is similar to ``auto-dnssec maintain``, but -``dnssec-policy`` also automatically creates new keys when necessary. In -addition, any configuration related to DNSSEC signing is retrieved from the -policy, ignoring existing DNSSEC :iscman:`named.conf` options. - -:iscman:`named` periodically searches the key directory for keys matching -the zone; if the keys' metadata indicates that any change should be -made to the zone - such as adding, removing, or revoking a key - then that -action is carried out. By default, the key directory is checked for -changes every 60 minutes; this period can be adjusted with -``dnssec-loadkeys-interval``, up to a maximum of 24 hours. The -:option:`rndc loadkeys` command forces :iscman:`named` to check for key updates immediately. - -If keys are present in the key directory the first time the zone is -loaded, the zone is signed immediately, without waiting for an -:option:`rndc sign` or :option:`rndc loadkeys` command. Those commands can still be -used when there are unscheduled key changes. - -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, the -TTL is set to the TTL specified when the key was created (using the -:option:`dnssec-keygen -L` option), if any, or to the SOA TTL. - -To sign the zone using NSEC3 instead of NSEC, submit an -NSEC3PARAM record via dynamic update prior to the scheduled publication -and activation of the keys. The OPTOUT bit for the NSEC3 chain can be set -in the flags field of the NSEC3PARAM record. The -NSEC3PARAM record does not appear in the zone immediately, but it is -stored for later reference. When the zone is signed and the NSEC3 -chain is completed, the NSEC3PARAM record appears in the zone. - -Using the ``auto-dnssec`` option requires the zone to be configured to -allow dynamic updates, by adding an ``allow-update`` or -``update-policy`` statement to the zone configuration. If this has not -been done, the configuration fails. +.. _dnssec_dynamic_zones_private_type_records: Private Type Records ^^^^^^^^^^^^^^^^^^^^ -The state of the signing process is signaled by private type records -(with a default type value of 65534). When signing is complete, those -records with a non-zero initial octet have a non-zero value for the final octet. +The state of the signing process is signaled by private type records (with a +default type value of 65534). When signing is complete, those records with a +non-zero initial octet have a non-zero value for the final octet. -If the first octet of a private type record is non-zero, the -record indicates either that the zone needs to be signed with the key matching -the record, or that all signatures that match the record should be -removed. Here are the meanings of the different values of the first octet: +If the first octet of a private type record is non-zero, the record indicates +either that the zone needs to be signed with the key matching the record, or +that all signatures that match the record should be removed. Here are the +meanings of the different values of the first octet: - algorithm (octet 1) @@ -515,11 +507,11 @@ removed. Here are the meanings of the different values of the first octet: Only records flagged as "complete" can be removed via dynamic update; attempts to remove other private type records are silently ignored. -If the first octet is zero (this is a reserved algorithm number that -should never appear in a DNSKEY record), the record indicates that -changes to the NSEC3 chains are in progress. The rest of the record -contains an NSEC3PARAM record, while the flag field tells what operation to -perform based on the flag bits: +If the first octet is zero (this is a reserved algorithm number that should +never appear in a ``DNSKEY`` record), the record indicates that changes to the +``NSEC3`` chains are in progress. The rest of the record contains an +``NSEC3PARAM`` record, while the flag field tells what operation to perform +based on the flag bits: 0x01 OPTOUT @@ -529,106 +521,41 @@ perform based on the flag bits: 0x20 NONSEC +.. _dnssec_dynamic_zones_dnskey_rollovers: + DNSKEY Rollovers ^^^^^^^^^^^^^^^^ -As with insecure-to-secure conversions, DNSSEC keyrolls can be done -in two ways: using a dynamic DNS update, or via the ``auto-dnssec`` zone -option. +To perform key rollovers via a dynamic update, the ``K*`` files for the new keys +must be added so that :iscman:`named` can find them. The new ``DNSKEY`` RRs can +then be added via dynamic update. When the zones are being signed, they are +signed with the new key set; when the signing is complete, the private type +records are updated so that the last octet is non-zero. -Dynamic DNS Update Method -^^^^^^^^^^^^^^^^^^^^^^^^^ +If this is for a KSK, the parent and any trust anchor repositories of the new +KSK must be informed. -To perform key rollovers via a dynamic update, the ``K*`` -files for the new keys must be added so that :iscman:`named` can find them. -The new DNSKEY RRs can then be added via dynamic update. :iscman:`named` then causes the -zone to be signed with the new keys; when the signing is complete, the -private type records are updated so that the last octet is non-zero. +The maximum TTL in the zone must expire before removing the old ``DNSKEY``. If +it is a KSK that is being updated, the DS RRset in the parent must also be +updated and its TTL allowed to expire. This ensures that all clients are able to +verify at least one signature when the old ``DNSKEY`` is removed. -If this is for a KSK, the parent and any trust anchor -repositories of the new KSK must be informed. +The old ``DNSKEY`` can be removed via ``UPDATE``, taking care to specify the +correct key. :iscman:`named` cleans out any signatures generated by the old +key after the update completes. -The maximum TTL in the zone must expire before removing the -old DNSKEY. If it is a KSK that is being updated, -the DS RRset in the parent must also be updated and its TTL allowed to expire. This -ensures that all clients are able to verify at least one signature -when the old DNSKEY is removed. +.. _dnssec_dynamic_zones_going_insecure: -The old DNSKEY can be removed via UPDATE, taking care to specify the -correct key. :iscman:`named` cleans out any signatures generated by the -old key after the update completes. - -Automatic Key Rollovers -^^^^^^^^^^^^^^^^^^^^^^^ - -When a new key reaches its activation date (as set by :iscman:`dnssec-keygen` -or :iscman:`dnssec-settime`), and if the ``auto-dnssec`` zone option is set to -``maintain``, :iscman:`named` automatically carries out the key rollover. -If the key's algorithm has not previously been used to sign the zone, -then the zone is fully signed as quickly as possible. However, if -the new key replaces an existing key of the same algorithm, the -zone is re-signed incrementally, with signatures from the old key -replaced with signatures from the new key as their signature -validity periods expire. By default, this rollover completes in 30 days, -after which it is safe to remove the old key from the DNSKEY RRset. - -NSEC3PARAM Rollovers via UPDATE -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The new NSEC3PARAM record can be added via dynamic update. When the new NSEC3 -chain has been generated, the NSEC3PARAM flag field is set to zero. At -that point, the old NSEC3PARAM record can be removed. The old chain is -removed after the update request completes. - -Converting From NSEC to NSEC3 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Add a ``nsec3param`` option to your ``dnssec-policy`` and -run :option:`rndc reconfig`. - -Or use :iscman:`nsupdate` to add an NSEC3PARAM record. - -In both cases, the NSEC3 chain is generated and the NSEC3PARAM record is -added before the NSEC chain is destroyed. - -Converting From NSEC3 to NSEC -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -To do this, remove the ``nsec3param`` option from the ``dnssec-policy`` and -run :option:`rndc reconfig`. - -Or use :iscman:`nsupdate` to remove all NSEC3PARAM records with a -zero flag field. The NSEC chain is generated before the NSEC3 chain -is removed. - -Converting From Secure to Insecure -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Going Insecure +^^^^^^^^^^^^^^ To convert a signed zone to unsigned using dynamic DNS, delete all the -DNSKEY records from the zone apex using :iscman:`nsupdate`. All signatures, -NSEC or NSEC3 chains, and associated NSEC3PARAM records are removed -automatically. This takes place after the update request completes. +``DNSKEY`` records from the zone apex using :iscman:`nsupdate`. All signatures, +``NSEC`` or ``NSEC3`` chains, and associated ``NSEC3PARAM`` records are removed +automatically when the zone is supposed to be re-signed. -This requires the ``dnssec-secure-to-insecure`` option to be set to -``yes`` in :iscman:`named.conf`. +This requires the ``dnssec-secure-to-insecure`` option to be set to ``yes`` in +:iscman:`named.conf`. -In addition, if the ``auto-dnssec maintain`` zone statement is used, it +In addition, if the ``auto-dnssec maintain`` or a ``dnssec-policy`` is used, it should be removed or changed to ``allow`` instead; otherwise it will re-sign. - -Periodic Re-signing -^^^^^^^^^^^^^^^^^^^ - -In any secure zone which supports dynamic updates, :iscman:`named` -periodically re-signs RRsets which have not been re-signed as a result of -some update action. The signature lifetimes are adjusted to -spread the re-sign load over time rather than all at once. - -NSEC3 and OPTOUT -^^^^^^^^^^^^^^^^ - -:iscman:`named` only supports creating new NSEC3 chains where all the NSEC3 -records in the zone have the same OPTOUT state. :iscman:`named` supports -UPDATES to zones where the NSEC3 records in the chain have mixed OPTOUT -state. :iscman:`named` does not support changing the OPTOUT state of an -individual NSEC3 record; if the -OPTOUT state of an individual NSEC3 needs to be changed, the entire chain must be changed. From 7824c5c9675c09878c6b14e4b75fb385bcc28c81 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 12 May 2022 11:19:03 +0200 Subject: [PATCH 06/22] Move Dynamic Zones section up Move this section up so that DNSSEC signing topics are grouped together (and not split by the DNSSEC Validation chapter). --- doc/arm/dnssec.inc.rst | 232 ++++++++++++++++++++--------------------- 1 file changed, 115 insertions(+), 117 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index 4f5dddb700..98c70e0c49 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -235,123 +235,6 @@ should be referenced by :iscman:`named.conf` as the input file for the zone. to provide the parent zone administrators with the ``DNSKEYs`` (or their corresponding ``DS`` records) that are the secure entry point to the zone. -.. _dnssec_config: - -DNSSEC Validation -~~~~~~~~~~~~~~~~~ - -To enable :iscman:`named` to validate answers received from other servers, the -``dnssec-validation`` option must be set to either ``yes`` or ``auto``. - -When ``dnssec-validation`` is set to ``auto``, a trust anchor for the -DNS root zone is automatically used. This trust anchor is provided -as part of BIND and is kept up to date using :rfc:`5011` key management. - -When ``dnssec-validation`` is set to ``yes``, DNSSEC validation -only occurs if at least one trust anchor has been explicitly configured -in :iscman:`named.conf`, using a ``trust-anchors`` statement (or the -``managed-keys`` and ``trusted-keys`` statements, both deprecated). - -When ``dnssec-validation`` is set to ``no``, DNSSEC validation does not -occur. - -The default is ``auto`` unless BIND is built with -``configure --disable-auto-validation``, in which case the default is -``yes``. - -The keys specified in ``trust-anchors`` are copies of ``DNSKEY`` RRs for zones -that are used to form the first link in the cryptographic chain of trust. Keys -configured with the keyword ``static-key`` or ``static-ds`` are loaded directly -into the table of trust anchors, and can only be changed by altering the -configuration. Keys configured with ``initial-key`` or ``initial-ds`` are used -to initialize :rfc:`5011` trust anchor maintenance, and are kept up-to-date -automatically after the first time :iscman:`named` runs. - -``trust-anchors`` is described in more detail later in this document. - -BIND 9 does not verify signatures on load, so zone keys -for authoritative zones do not need to be specified in the configuration -file. - -After DNSSEC is established, a typical DNSSEC configuration looks -something like the following. It has one or more public keys for the -root, which allows answers from outside the organization to be validated. -It also has several keys for parts of the namespace that the -organization controls. These are here to ensure that :iscman:`named` is immune -to compromised security in the DNSSEC components of parent zones. - -:: - - trust-anchors { - /* Root Key */ - "." initial-key 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwS - JxrGkxJWoZu6I7PzJu/E9gx4UC1zGAHlXKdE4zYIpRh - aBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3zy2Xy - 4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYg - hf+6fElrmLkdaz MQ2OCnACR817DF4BBa7UR/beDHyp - 5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M/lUUVRbke - g1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq - 66gKodQj+MiA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ - 97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ - dgxbcDTClU0CRBdiieyLMNzXG3"; - /* Key for our organization's forward zone */ - example.com. static-ds 54135 5 2 "8EF922C97F1D07B23134440F19682E7519ADDAE180E20B1B1EC52E7F58B2831D" - - /* Key for our reverse zone. */ - 2.0.192.IN-ADDRPA.NET. static-key 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc - xOdNax071L18QqZnQQQAVVr+i - LhGTnNGp3HoWQLUIzKrJVZ3zg - gy3WwNT6kZo6c0tszYqbtvchm - gQC8CzKojM/W16i6MG/eafGU3 - siaOdS0yOI6BgPsw+YZdzlYMa - IJGf4M4dyoKIhzdZyQ2bYQrjy - Q4LB0lC7aOnsMyYKHHYeRvPxj - IQXmdqgOJGq+vsevG06zW+1xg - YJh9rCIfnm1GX/KMgxLPG2vXT - D/RnLX+D3T3UL7HJYHJhAZD5L - 59VvjSPsZJHeDCUyWYrvPZesZ - DIRvhDD52SKvbheeTJUm6Ehkz - ytNN2SN96QRk8j/iI8ib"; - }; - - options { - ... - dnssec-validation yes; - }; - -.. - -.. note:: - - None of the keys listed in this example are valid. In particular, the - root key is not valid. - -When DNSSEC validation is enabled and properly configured, the resolver -rejects any answers from signed, secure zones which fail to -validate, and returns SERVFAIL to the client. - -Responses may fail to validate for any of several reasons, including -missing, expired, or invalid signatures, a key which does not match the -DS RRset in the parent zone, or an insecure response from a zone which, -according to its parent, should have been secure. - -.. note:: - - When the validator receives a response from an unsigned zone that has - a signed parent, it must confirm with the parent that the zone was - intentionally left unsigned. It does this by verifying, via signed - and validated NSEC/NSEC3 records, that the parent zone contains no DS - records for the child. - - If the validator *can* prove that the zone is insecure, then the - response is accepted. However, if it cannot, the validator must assume an - insecure response to be a forgery; it rejects the response and logs - an error. - - The logged error reads "insecurity proof failed" and "got insecure - response; parent indicates it should be secure." - - .. _dnssec_dynamic_zones: Dynamic Zones @@ -559,3 +442,118 @@ This requires the ``dnssec-secure-to-insecure`` option to be set to ``yes`` in In addition, if the ``auto-dnssec maintain`` or a ``dnssec-policy`` is used, it should be removed or changed to ``allow`` instead; otherwise it will re-sign. + + +DNSSEC Validation +~~~~~~~~~~~~~~~~~ + +To enable :iscman:`named` to validate answers received from other servers, the +``dnssec-validation`` option must be set to either ``yes`` or ``auto``. + +When ``dnssec-validation`` is set to ``auto``, a trust anchor for the +DNS root zone is automatically used. This trust anchor is provided +as part of BIND and is kept up to date using :rfc:`5011` key management. + +When ``dnssec-validation`` is set to ``yes``, DNSSEC validation +only occurs if at least one trust anchor has been explicitly configured +in :iscman:`named.conf`, using a ``trust-anchors`` statement (or the +``managed-keys`` and ``trusted-keys`` statements, both deprecated). + +When ``dnssec-validation`` is set to ``no``, DNSSEC validation does not +occur. + +The default is ``auto`` unless BIND is built with +``configure --disable-auto-validation``, in which case the default is +``yes``. + +The keys specified in ``trust-anchors`` are copies of ``DNSKEY`` RRs for zones +that are used to form the first link in the cryptographic chain of trust. Keys +configured with the keyword ``static-key`` or ``static-ds`` are loaded directly +into the table of trust anchors, and can only be changed by altering the +configuration. Keys configured with ``initial-key`` or ``initial-ds`` are used +to initialize :rfc:`5011` trust anchor maintenance, and are kept up-to-date +automatically after the first time :iscman:`named` runs. + +``trust-anchors`` is described in more detail later in this document. + +BIND 9 does not verify signatures on load, so zone keys +for authoritative zones do not need to be specified in the configuration +file. + +After DNSSEC is established, a typical DNSSEC configuration looks +something like the following. It has one or more public keys for the +root, which allows answers from outside the organization to be validated. +It also has several keys for parts of the namespace that the +organization controls. These are here to ensure that :iscman:`named` is immune +to compromised security in the DNSSEC components of parent zones. + +:: + + trust-anchors { + /* Root Key */ + "." initial-key 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwS + JxrGkxJWoZu6I7PzJu/E9gx4UC1zGAHlXKdE4zYIpRh + aBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3zy2Xy + 4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYg + hf+6fElrmLkdaz MQ2OCnACR817DF4BBa7UR/beDHyp + 5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M/lUUVRbke + g1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq + 66gKodQj+MiA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ + 97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ + dgxbcDTClU0CRBdiieyLMNzXG3"; + /* Key for our organization's forward zone */ + example.com. static-ds 54135 5 2 "8EF922C97F1D07B23134440F19682E7519ADDAE180E20B1B1EC52E7F58B2831D" + + /* Key for our reverse zone. */ + 2.0.192.IN-ADDRPA.NET. static-key 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc + xOdNax071L18QqZnQQQAVVr+i + LhGTnNGp3HoWQLUIzKrJVZ3zg + gy3WwNT6kZo6c0tszYqbtvchm + gQC8CzKojM/W16i6MG/eafGU3 + siaOdS0yOI6BgPsw+YZdzlYMa + IJGf4M4dyoKIhzdZyQ2bYQrjy + Q4LB0lC7aOnsMyYKHHYeRvPxj + IQXmdqgOJGq+vsevG06zW+1xg + YJh9rCIfnm1GX/KMgxLPG2vXT + D/RnLX+D3T3UL7HJYHJhAZD5L + 59VvjSPsZJHeDCUyWYrvPZesZ + DIRvhDD52SKvbheeTJUm6Ehkz + ytNN2SN96QRk8j/iI8ib"; + }; + + options { + ... + dnssec-validation yes; + }; + +.. + +.. note:: + + None of the keys listed in this example are valid. In particular, the + root key is not valid. + +When DNSSEC validation is enabled and properly configured, the resolver +rejects any answers from signed, secure zones which fail to +validate, and returns SERVFAIL to the client. + +Responses may fail to validate for any of several reasons, including +missing, expired, or invalid signatures; a key which does not match the +DS RRset in the parent zone; or an insecure response from a zone which, +according to its parent, should have been secure. + +.. note:: + + When the validator receives a response from an unsigned zone that has + a signed parent, it must confirm with the parent that the zone was + intentionally left unsigned. It does this by verifying, via signed + and validated NSEC/NSEC3 records, that the parent zone contains no DS + records for the child. + + If the validator *can* prove that the zone is insecure, then the + response is accepted. However, if it cannot, the validator must assume an + insecure response to be a forgery; it rejects the response and logs + an error. + + The logged error reads "insecurity proof failed" and "got insecure + response; parent indicates it should be secure." From 024c15f03b29b3791292ee97be0d2d92ba9bc69a Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 12 May 2022 11:23:42 +0200 Subject: [PATCH 07/22] Move "DNSSEC" chapter before "Advanced" and "Security" DNSSEC is mainstream nowadays, so let's give it more attention. --- doc/arm/chapter5.rst | 8 +++----- doc/arm/chapter6.rst | 9 +++++---- doc/arm/chapter7.rst | 7 ++++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/arm/chapter5.rst b/doc/arm/chapter5.rst index 68d98bced0..365deb45f1 100644 --- a/doc/arm/chapter5.rst +++ b/doc/arm/chapter5.rst @@ -9,8 +9,6 @@ .. See the COPYRIGHT file distributed with this work for additional .. information regarding copyright ownership. -.. include:: advanced.inc.rst -.. include:: dlz.inc.rst -.. include:: dyndb.inc.rst -.. include:: catz.inc.rst -.. include:: rpz.inc.rst +.. include:: dnssec.inc.rst +.. include:: managed-keys.inc.rst +.. include:: pkcs11.inc.rst diff --git a/doc/arm/chapter6.rst b/doc/arm/chapter6.rst index 429acea283..68d98bced0 100644 --- a/doc/arm/chapter6.rst +++ b/doc/arm/chapter6.rst @@ -9,7 +9,8 @@ .. See the COPYRIGHT file distributed with this work for additional .. information regarding copyright ownership. -.. include:: security.inc.rst -.. include:: tsig.inc.rst -.. include:: tkey.inc.rst -.. include:: sig0.inc.rst +.. include:: advanced.inc.rst +.. include:: dlz.inc.rst +.. include:: dyndb.inc.rst +.. include:: catz.inc.rst +.. include:: rpz.inc.rst diff --git a/doc/arm/chapter7.rst b/doc/arm/chapter7.rst index 365deb45f1..429acea283 100644 --- a/doc/arm/chapter7.rst +++ b/doc/arm/chapter7.rst @@ -9,6 +9,7 @@ .. See the COPYRIGHT file distributed with this work for additional .. information regarding copyright ownership. -.. include:: dnssec.inc.rst -.. include:: managed-keys.inc.rst -.. include:: pkcs11.inc.rst +.. include:: security.inc.rst +.. include:: tsig.inc.rst +.. include:: tkey.inc.rst +.. include:: sig0.inc.rst From 93601d83251efa13e9818215eadbb774e62551ab Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Tue, 7 Jun 2022 10:23:47 +0200 Subject: [PATCH 08/22] Use NSEC3 guidance values in nsec3 config examples Use best practice values in examples that follow new guidance from draft-ietf-dnsop-nsec3-guidance: ; SHA-1, no extra iterations, empty salt: ; bcp.example. IN NSEC3PARAM 1 0 0 - --- doc/arm/dnssec.inc.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index 98c70e0c49..8e87aa4e69 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -160,14 +160,14 @@ To enable ``NSEC3``, add an ``nsec3param`` option to your DNSSEC Policy: :: dnssec-policy "nsec3" { - nsec3param iterations 5 optout yes salt-length 8; + nsec3param iterations 0 optout no salt-length 0; }; .. The ``nsec3`` policy above creates ``NSEC3`` records using the SHA-1 hash -algorithm, using 5 iterations and a salt that is 8 characters long. It also -skips insecure delegations. +algorithm, using zero extra iterations and no salt. ``optout`` is disabled, +meaning insecure delegations will also get an ``NSEC3`` record. The ``NSEC3`` chain is generated and the ``NSEC3PARAM`` record is added before the existing ``NSEC`` chain (if any) is destroyed. From 0dc9c33149244594a61ba50a7ec2b27c1108a815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Wed, 8 Jun 2022 15:45:35 +0200 Subject: [PATCH 09/22] Rewrite introduction for DNSSEC chapter of the ARM I've attempted to drop most of DNSSEC-specific jargon from the intro paragraph, and to convince readers to read on. --- doc/arm/dnssec.inc.rst | 105 +++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index 8e87aa4e69..0172361433 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -13,66 +13,69 @@ DNSSEC ------ +DNS Security Extensions (DNSSEC) provide reliable protection from +`cache poisoning`_ attacks. At the same time these extensions also provide other benefits: +they limit the impact of `random subdomain attacks`_ on resolver caches and authoritative +servers, and provide the foundation for modern applications like `authenticated +and private e-mail transfer`_. -Cryptographic authentication of DNS information is possible through the -DNS Security Extensions (DNSSEC), defined in :rfc:`4033`, :rfc:`4034`, -and :rfc:`4035`. This section describes the creation and use of DNSSEC -signed zones. +To achieve this goal, DNSSEC adds `digital signatures`_ to DNS records in +authoritative DNS zones, and DNS resolvers verify the validity of the signatures on the +received records. If the signatures match the received data, the resolver can +be sure that the data was not modified in transit. -In order to set up a DNSSEC secure zone, there are a series of steps -which must be followed. BIND 9 ships with several tools that are used in -this process, which are explained in more detail below. In all cases, -the ``-h`` option prints a full list of parameters. Note that the DNSSEC -tools require the keyset files to be in the working directory or the -directory specified by the ``-d`` option. +.. note:: + DNSSEC and transport-level encryption are complementary! + Unlike typical transport-level encryption like DNS-over-TLS, DNS-over-HTTPS, + or VPN, DNSSEC makes DNS records verifiable at all points of the DNS + resolution chain. -There must also be communication with the administrators of the parent -and/or child zone to transmit keys. A zone's security status must be -indicated by the parent zone for a DNSSEC-capable resolver to trust its -data. This is done through the presence or absence of a ``DS`` record at -the delegation point. +This section focuses on ways to deploy DNSSEC using BIND. For a more in-depth +discussion of DNSSEC principles (e.g. :ref:`how_does_dnssec_change_dns_lookup`) +please see :doc:`dnssec-guide`. -For resolvers to trust data in this zone, they must be configured with a trust -anchor. Typically this is the public key of the DNS root zone, although you -can also configure a trust anchor that is the public key of this zone or -another zone above this on in the DNS tree. +.. _`cache poisoning`: https://en.wikipedia.org/wiki/DNS_cache_poisoning +.. _`random subdomain attacks`: https://www.isc.org/blogs/nsec-caching-should-limit-excessive-queries-to-dns-root/ +.. _`digital signatures`: https://en.wikipedia.org/wiki/Digital_signature +.. _`authenticated and private e-mail transfer`: https://github.com/internetstandards/toolbox-wiki/blob/main/DANE-for-SMTP-how-to.md -.. _dnssec_keys: - -DNSSEC Keys -~~~~~~~~~~~ - -A secure zone must contain one or more zone keys. The zone keys -sign all other records in the zone, as well as the zone keys of any -secure delegated zones. It is recommended that zone keys use one of the -cryptographic algorithms designated as "mandatory to implement" by the -IETF, that is either RSASHA256 or ECDSAP256SHA256. - -Zone keys must have the same name as the zone, have a -name type of ``ZONE``, and be usable for authentication. It is -recommended that zone keys use a cryptographic algorithm designated as -"mandatory to implement" by the IETF. Currently there are two algorithms, -RSASHA256 and ECDSAP256SHA256; ECDSAP256SHA256 is recommended for -current and future deployments. - -Keys are stored in files, ``Kdnssec.example.+013+12345.key`` and -``Kdnssec.example.+013+12345.private`` (where 12345 is an example of a -key tag). The key filenames contain the key name (``dnssec.example.``), -the algorithm (5 is RSASHA1, 8 is RSASHA256, 13 is ECDSAP256SHA256, 15 is -ED25519, etc.), and the key tag (12345 in this case). The private key (in -the ``.private`` file) is used to generate signatures, and the public -key (in the ``.key`` file) is used for signature verification. .. _dnssec_zone_signing: Zone Signing ~~~~~~~~~~~~ -To sign a zone, configure a key and signing policy for the zone. The -configuration below will sign the zone ``dnssec.example`` according to the -built-in default policy: +BIND offers several ways to generate signatures and maintain their validity +during the lifetime of a DNS zone: -:: + - :ref:`dnssec_kasp` - **strongly recommended** + - :ref:`dnssec_dynamic_zones` - only for special needs + - :ref:`dnssec_tools` - discouraged, use only for debugging + +Zone keys +^^^^^^^^^ +Regardless of the :ref:`zone-signing ` method in use, cryptographic keys are +stored in files named like :file:`Kdnssec.example.+013+12345.key` and +:file:`Kdnssec.example.+013+12345.private`. +The private key (in the ``.private`` file) is used to generate signatures, and +the public key (in the ``.key`` file) is used for signature verification. +Additionally, the :ref:`dnssec_kasp` method creates a third file, +:file:`Kdnssec.example+013+12345.state`, which is used to track DNSSEC key timings +and to perform key rollovers safely. + +These filenames contain: + + - the key name, which always matches the zone name (``dnssec.example.``), + - the `algorithm number`_ (013 is ECDSAP256SHA256, 008 is RSASHA256, etc.), + - and the key tag, i.e. a non-unique key identifier (12345 in this case). + +.. _`algorithm number`: https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml#dns-sec-alg-numbers-1 + + +.. warning:: + Private keys are required for full disaster recovery. Back up key files in a + safe location and protect them from unauthorized access. Anyone with + access to the private key can create fake but seemingly valid DNS data. zone "dnssec.example" { type primary; @@ -278,9 +281,9 @@ Enabling DNSSEC Manually As an alternative to fully automated zone signing using :ref:`dnssec-policy `, a zone can be changed from insecure to secure using a dynamic DNS update. :iscman:`named` must be configured so that it can see the ``K*`` -files which contain the public and private parts of the keys that are used to -sign the zone. Key files should be placed in the key-directory, as specified in -:iscman:`named.conf`: +files which contain the public and private parts of the `zone keys`_ that are +used to sign the zone. Key files should be placed in the ``key-directory``, as +specified in :iscman:`named.conf`: :: From 744763f8f2e9c0cd13b3952a26fff9357a4f18f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Wed, 8 Jun 2022 16:48:06 +0200 Subject: [PATCH 10/22] Rewrite KASP section of DNSSEC chapter in the ARM The goal is simplicity. Copy&paste to do the right thing, or read referenced material and make up your mind if you need specialities. NSEC discussion is already present in the DNSSEC guide so I merged KASP examples with example for NSEC3 and removed NSEC text from the DNSSEC chapter. --- doc/arm/dnssec.inc.rst | 125 ++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 78 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index 0172361433..44ba51a686 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -77,107 +77,76 @@ These filenames contain: safe location and protect them from unauthorized access. Anyone with access to the private key can create fake but seemingly valid DNS data. +.. _dnssec_kasp: + +Fully Automated (Key and Signing Policy) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Key and Signing Policy (KASP) is a method of configuration that describes +how to maintain DNSSEC signing keys and how to sign the zone. + +This is the recommended, fully automated way to sign and maintain DNS zones. For +most use cases users can simply use the built-in default policy, which applies +up-to-date DNSSEC practices: + +.. code-block:: none + :emphasize-lines: 4 + zone "dnssec.example" { type primary; - dnssec-policy default; file "dnssec.example.db"; + dnssec-policy default; }; -.. +This single line is sufficient to create the necessary signing keys, and generate +``DNSKEY``, ``RRSIG``, and ``NSEC`` records for the zone. BIND also takes +care of any DNSSEC maintenance for this zone, including replacing signatures +that are about to expire and managing :ref:`key_rollovers`. -This will create the necessary keys and generates ``DNSKEY``, ``RRSIG`` and -``NSEC`` records for the zone. BIND will now also take care of any DNSSEC -maintenance for this zone, including replacing signatures that are about to -expire and managing key rollovers. - -The file ``dnssec.example.db`` remains untouched and the signed zone is stored -on disk in ``dnssec.example.db.signed``. In addition to the -``Kdnssec.example.+013+12345.key`` and ``Kdnssec.example.+013+12345.private`` -key files, this method stores another file on disk, -``Kdnssec.example+013+12345.state``, that tracks DNSSEC key timings and are -used to perform key rollovers safely. +**TODO:** +The original zone file :file:`dnssec.example.db` remains untouched and the +signed version of the zone is stored on disk in :file:`dnssec.example.db.signed`. The default policy creates one key that is used to sign the complete zone, and uses ``NSEC`` to enable authenticated denial of existence (a secure way -to tell which records do not exist in your zone). How to create your own -policy is decribed in the section below. +to tell which records do not exist in a zone). This policy is recommended +and typically does not need to be changed. -.. _dnssec_kasp: +If needed, a custom policy can be defined by adding a ``dnssec-policy`` statement +into the configuration: -Key and Signing Policy -^^^^^^^^^^^^^^^^^^^^^^ +.. code-block:: none -A key and signing policy (KASP) is a piece of configuration that describes -how to make a zone DNSSEC secure. The built-in ``default`` policy uses the most -common DNSSEC practices, but you can define a custom policy by adding a -``dnssec-policy`` clause in your configuration: - -:: dnssec-policy "custom" { dnskey-ttl 600; keys { - ksk lifetime PT1Y algorithm rsasha256 2048; - zsk lifetime 60d algorithm rsasha256 2048; + ksk lifetime P1Y algorithm ecdsap384sha384; + zsk lifetime 60d algorithm ecdsap384sha384; }; - }; - -.. - -This ``custom`` policy for example, uses a short ``DNSKEY`` TTL (600 seconds) -and it uses two keys to sign the zone (a KSK to sign the key related RRsets, -``DNSKEY``, ``CDS``, and ``CDNSKEY``, and a ZSK to sign the rest of the zone). -The configured keys also have a lifetime set and use a different algorithm. - -``dnssec-policy`` is described in more detail later in this document. - -The :ref:`dnssec_advanced_discussions` in the DNSSEC Guide discusses the -various policy settings and may help you determining which values you should -use. - -.. _dnssec_denial_of_existence: - -Denial of Existence -^^^^^^^^^^^^^^^^^^^ - -To prove that some data does not exist in the zone, ``NSEC`` records are added -to the zone for each domain name. This record contains a list that tells -which record types are present at that name, so that if a query comes in for -a type that is not in the list, the requestor can proof its non-existence. -The ``NSEC`` record also contains a next owner name, proving that all names -between the owner name and next owner name do not exist. - -The ``NSEC`` method allows for trivial zone walking, where one would query -for the apex ``NSEC`` record and then queries the ``NSEC`` of each next owner -name to learn about all names that exist in a certain zone. While this may not -be a problem for most, you can mitigate against this by using ``NSEC3``, hashed -denial of existence (defined in :rfc:`5155`). This uses one-way hashes to -obfuscate the next owner names. - -With ``NSEC3`` you can also opt-out insecure delegations from denial of -existence, which may be useful for parent zones with a lot of insecure child -zones. - -To enable ``NSEC3``, add an ``nsec3param`` option to your DNSSEC Policy: - -:: - - dnssec-policy "nsec3" { nsec3param iterations 0 optout no salt-length 0; }; -.. +This ``custom`` policy, for example: -The ``nsec3`` policy above creates ``NSEC3`` records using the SHA-1 hash -algorithm, using zero extra iterations and no salt. ``optout`` is disabled, -meaning insecure delegations will also get an ``NSEC3`` record. + - uses a very short ``DNSKEY`` TTL (600 seconds), + - uses two keys to sign the zone: a Key Signing Key (KSK) to sign the key + related RRsets (``DNSKEY``, ``CDS``, and ``CDNSKEY``), and a Zone Signing + Key (ZSK) to sign the rest of the zone. The KSK is automatically + rotated after one year and the ZSK after 60 days. -The ``NSEC3`` chain is generated and the ``NSEC3PARAM`` record is added before -the existing ``NSEC`` chain (if any) is destroyed. +Also: + - The configured keys also have a lifetime set and use the ECDSAP384SHA384 + algorithm. + - The last line instructs BIND to generate NSEC3 records for + :ref:`Proof of Non-Existence `, + using zero extra iterations and no salt. NSEC3 opt-out is disabled, meaning + insecure delegations also get an NSEC3 record. -You can also switch back to ``NSEC`` by removing the ``nsec3param`` option. -In this case, the ``NSEC`` chain is generated before the ``NSEC3`` chain -is removed. +For more information about KASP configuration see :ref:`dnssec_policy_grammar`. + +The :ref:`dnssec_advanced_discussions` in the DNSSEC Guide discusses the +various policy settings and may help you determining values for your special needs. .. _dnssec_tools: From 28a533322b25b018a86dc986a6de05db8ae39841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Wed, 8 Jun 2022 18:05:56 +0200 Subject: [PATCH 11/22] Reorder chapters about Zone Signing in the DNSSEC chapter of ARM Let's make more automated methods more prominent: - KASP first - dynamic updates second - command-line tools only as last resort --- doc/arm/dnssec.inc.rst | 434 +++++++++++++++++++++-------------------- 1 file changed, 223 insertions(+), 211 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index 44ba51a686..a7110b302e 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -106,6 +106,14 @@ that are about to expire and managing :ref:`key_rollovers`. **TODO:** The original zone file :file:`dnssec.example.db` remains untouched and the signed version of the zone is stored on disk in :file:`dnssec.example.db.signed`. +When setting a ``dnssec-policy`` for a zone, it typically creates a new file +with a ``.signed`` extension on disk, while the original zone file stays +untouched. This is called inline signing. + +DNSSEC configuration works slightly differently for dynamic zones. DNSSEC-related +records are applied directly to zones with an update ACL or update +policy, similarly to non-DNSSEC records, instead of storing them in a file with a +``.signed`` extension. The default policy creates one key that is used to sign the complete zone, and uses ``NSEC`` to enable authenticated denial of existence (a secure way @@ -148,18 +156,230 @@ For more information about KASP configuration see :ref:`dnssec_policy_grammar`. The :ref:`dnssec_advanced_discussions` in the DNSSEC Guide discusses the various policy settings and may help you determining values for your special needs. +.. _dnssec_dynamic_zones: + +Manual Key Management +^^^^^^^^^^^^^^^^^^^^^ + +.. warning:: + The method described here allows full control over the keys used to sign + the zone. This is required only for very special cases and is generally + discouraged. Under normal circumstances, please use :ref:`dnssec_kasp`. + + +.. _dnssec_dynamic_zones_multisigner_model: + +Multi-Signer Model +================== + +Dynamic zones provide the ability to sign a zone by multiple providers, meaning +each provider signs and serves the same zone independently. Such a setup requires +some coordination between providers when it comes to key rollovers, and may be +better suited to be configured with ``auto-dnssec allow;``. This permits keys to +be updated and the zone to be re-signed only if the user issues the command +:option:`rndc sign zonename `. + +A zone can also be configured with ``auto-dnssec maintain``, which automatically +adjusts the zone's DNSSEC keys on a schedule according to the key timing +metadata. However, keys still need to be generated separately, for +example with :iscman:`dnssec-keygen`. + +Of course, dynamic zones can also use ``dnssec-policy`` to fully automate DNSSEC +maintenance. The next sections assume that more key +management control is needed, and describe how to use dynamic DNS update to perform +various DNSSEC operations. + +.. _dnssec_dynamic_zones_enabling_dnssec: + +Enabling DNSSEC Manually +======================== +As an alternative to fully automated zone signing using :ref:`dnssec-policy +`, a zone can be changed from insecure to secure using a dynamic +DNS update. :iscman:`named` must be configured so that it can see the ``K*`` +files which contain the public and private parts of the `zone keys`_ that are +used to sign the zone. Key files should be placed in the ``key-directory``, as +specified in :iscman:`named.conf`: + +:: + + zone update.example { + type primary; + update-policy local; + auto-dnssec allow; + file "dynamic/update.example.db"; + key-directory "keys/update.example/"; + }; + +If there are both a KSK and a ZSK available (or a CSK), this configuration causes the +zone to be signed. An ``NSEC`` chain is generated as part of the initial signing +process. + +In any secure zone which supports dynamic updates, :iscman:`named` periodically +re-signs RRsets which have not been re-signed as a result of some update action. +The signature lifetimes are adjusted to spread the re-sign load over time rather +than all at once. + +.. _dnssec_dynamic_zones_publishing_dnskey_records: + +Publishing DNSKEY Records +========================= + +To insert the keys via dynamic update: + +:: + + % nsupdate + > ttl 3600 + > update add update.example DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8= + > update add update.example DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk= + > send + +In order to sign with these keys, the corresponding key files should also be +placed in the ``key-directory``. + +.. _dnssec_dynamic_zones_nsec3: + +NSEC3 +===== + +To sign using :ref:`NSEC3 ` instead of :ref:`NSEC +`, add an NSEC3PARAM record to the initial update +request. The :term:`OPTOUT ` bit in the NSEC3 +chain can be set in the flags field of the +NSEC3PARAM record. + +:: + + % nsupdate + > ttl 3600 + > update add update.example DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8= + > update add update.example DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk= + > update add update.example NSEC3PARAM 1 0 0 - + > send + +Note that the ``NSEC3PARAM`` record does not show up until :iscman:`named` has +had a chance to build/remove the relevant chain. A private type record is +created to record the state of the operation (see below for more details), and +is removed once the operation completes. + +The ``NSEC3`` chain is generated and the ``NSEC3PARAM`` record is added before +the ``NSEC`` chain is destroyed. + +While the initial signing and ``NSEC``/``NSEC3`` chain generation are occurring, +other updates are possible as well. + +A new ``NSEC3PARAM`` record can be added via dynamic update. When the new +``NSEC3`` chain has been generated, the ``NSEC3PARAM`` flag field is set to +zero. At that point, the old ``NSEC3PARAM`` record can be removed. The old +chain is removed after the update request completes. + +:iscman:`named` only supports creating new ``NSEC3`` chains where all the +``NSEC3`` records in the zone have the same ``OPTOUT`` state. :iscman:`named` +supports updates to zones where the ``NSEC3`` records in the chain have mixed +``OPTOUT`` state. :iscman:`named` does not support changing the ``OPTOUT`` +state of an individual ``NSEC3`` record; if the ``OPTOUT`` state of an +individual ``NSEC3`` needs to be changed, the entire chain must be changed. + +To switch back to ``NSEC``, use :iscman:`nsupdate` to remove any ``NSEC3PARAM`` +records. The ``NSEC`` chain is generated before the ``NSEC3`` chain is removed. + +.. _dnssec_dynamic_zones_private_type_records: + +Private Type Records +==================== + +The state of the signing process is signaled by private type records (with a +default type value of 65534). When signing is complete, those records with a +non-zero initial octet have a non-zero value for the final octet. + +If the first octet of a private type record is non-zero, the record indicates +either that the zone needs to be signed with the key matching the record, or +that all signatures that match the record should be removed. Here are the +meanings of the different values of the first octet: + + - algorithm (octet 1) + + - key id in network order (octet 2 and 3) + + - removal flag (octet 4) + + - complete flag (octet 5) + +Only records flagged as "complete" can be removed via dynamic update; attempts +to remove other private type records are silently ignored. + +If the first octet is zero (this is a reserved algorithm number that should +never appear in a ``DNSKEY`` record), the record indicates that changes to the +``NSEC3`` chains are in progress. The rest of the record contains an +``NSEC3PARAM`` record, while the flag field tells what operation to perform +based on the flag bits: + + 0x01 OPTOUT + + 0x80 CREATE + + 0x40 REMOVE + + 0x20 NONSEC + +.. _dnssec_dynamic_zones_dnskey_rollovers: + +DNSKEY Rollovers +================ + +To perform key rollovers via a dynamic update, the ``K*`` files for the new keys +must be added so that :iscman:`named` can find them. The new ``DNSKEY`` RRs can +then be added via dynamic update. When the zones are being signed, they are +signed with the new key set; when the signing is complete, the private type +records are updated so that the last octet is non-zero. + +If this is for a KSK, the parent and any trust anchor repositories of the new +KSK must be informed. + +The maximum TTL in the zone must expire before removing the old ``DNSKEY``. If +it is a KSK that is being updated, the DS RRset in the parent must also be +updated and its TTL allowed to expire. This ensures that all clients are able to +verify at least one signature when the old ``DNSKEY`` is removed. + +The old ``DNSKEY`` can be removed via ``UPDATE``, taking care to specify the +correct key. :iscman:`named` cleans out any signatures generated by the old +key after the update completes. + +.. _dnssec_dynamic_zones_going_insecure: + +Going Insecure +============== + +To convert a signed zone to unsigned using dynamic DNS, delete all the +``DNSKEY`` records from the zone apex using :iscman:`nsupdate`. All signatures, +``NSEC`` or ``NSEC3`` chains, and associated ``NSEC3PARAM`` records are removed +automatically when the zone is supposed to be re-signed. + +This requires the ``dnssec-secure-to-insecure`` option to be set to ``yes`` in +:iscman:`named.conf`. + +In addition, if the ``auto-dnssec maintain`` or a ``dnssec-policy`` is used, it +should be removed or changed to ``allow`` instead; otherwise it will re-sign. + .. _dnssec_tools: -DNSSEC Tools -^^^^^^^^^^^^ +Manual Signing +^^^^^^^^^^^^^^ -There are several tools available if you want to sign your zone manually. +There are several tools available to manually sign a zone. .. warning:: Please note manual procedures are available mainly for backwards compatibility and should be used only by expert users with specific needs. +To set up a DNSSEC secure zone manually, a series of steps +must be followed. BIND 9 ships with several tools that are used in +this process, which are explained in more detail below. In all cases, +the ``-h`` option prints a full list of parameters. Note that the DNSSEC +tools require the keyset files to be in the working directory or the +directory specified by the ``-d`` option. + The :iscman:`dnssec-keygen` program is used to generate keys. The following command generates an ECDSAP256SHA256 key for the @@ -207,214 +427,6 @@ should be referenced by :iscman:`named.conf` as the input file for the zone. to provide the parent zone administrators with the ``DNSKEYs`` (or their corresponding ``DS`` records) that are the secure entry point to the zone. -.. _dnssec_dynamic_zones: - -Dynamic Zones -~~~~~~~~~~~~~ - -When setting a ``dnssec-policy`` for a zone, it typically creates a new file -with a ``.signed`` extension on disk, while the original zone file stays -untouched. This is called inline signing. - -This works a bit different for dynamic zones. Zones with an update ACL or update -policy will have the DNSSEC related records applied directly to the zone, -similar to the non-DNSSEC records, instead of storing them in a file with -``.signed`` extension. - -.. _dnssec_dynamic_zones_multisigner_model: - -Multi-Signer Model -^^^^^^^^^^^^^^^^^^ - -Dynamic zones provide the ability to sign a zone by multiple providers, meaning -each provider signs and serves the same zone independently. Such a setup requires -some coordination between providers when it comes to key rollovers, and may be -better suited to be configured with ``auto-dnssec allow;``. This permits keys to -be updated and the zone to be re-signed only if the user issues the command -:option:`rndc sign zonename `. - -A zone can also be configured with ``auto-dnssec maintain``, which automatically -adjusts the zone's DNSSEC keys on a schedule according to the key timing -metadata. However, keys still need to be generated separately, for -example with :iscman:`dnssec-keygen`. - -Of course, dynamic zones can also use ``dnssec-policy`` to fully automate DNSSEC -maintenance. The next sections assume that more key -management control is needed, and describe how to use dynamic DNS update to perform -various DNSSEC operations. - -.. _dnssec_dynamic_zones_enabling_dnssec: - -Enabling DNSSEC Manually -^^^^^^^^^^^^^^^^^^^^^^^^ -As an alternative to fully automated zone signing using :ref:`dnssec-policy -`, a zone can be changed from insecure to secure using a dynamic -DNS update. :iscman:`named` must be configured so that it can see the ``K*`` -files which contain the public and private parts of the `zone keys`_ that are -used to sign the zone. Key files should be placed in the ``key-directory``, as -specified in :iscman:`named.conf`: - -:: - - zone update.example { - type primary; - update-policy local; - auto-dnssec allow; - file "dynamic/update.example.db"; - key-directory "keys/update.example/"; - }; - -If there are both a KSK and a ZSK available (or a CSK), this configuration causes the -zone to be signed. An ``NSEC`` chain is generated as part of the initial signing -process. - -In any secure zone which supports dynamic updates, :iscman:`named` periodically -re-signs RRsets which have not been re-signed as a result of some update action. -The signature lifetimes are adjusted to spread the re-sign load over time rather -than all at once. - -.. _dnssec_dynamic_zones_publishing_dnskey_records: - -Publishing DNSKEY Records -^^^^^^^^^^^^^^^^^^^^^^^^^ - -To insert the keys via dynamic update: - -:: - - % nsupdate - > ttl 3600 - > update add update.example DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8= - > update add update.example DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk= - > send - -In order to sign with these keys, the corresponding key files should also be -placed in the ``key-directory``. - -.. _dnssec_dynamic_zones_nsec3: - -NSEC3 -^^^^^ - -To sign using :ref:`NSEC3 ` instead of :ref:`NSEC -`, add an NSEC3PARAM record to the initial update -request. The :term:`OPTOUT ` bit in the NSEC3 -chain can be set in the flags field of the -NSEC3PARAM record. - -:: - - % nsupdate - > ttl 3600 - > update add update.example DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8= - > update add update.example DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk= - > update add update.example NSEC3PARAM 1 0 0 - - > send - -Note that the ``NSEC3PARAM`` record does not show up until :iscman:`named` has -had a chance to build/remove the relevant chain. A private type record is -created to record the state of the operation (see below for more details), and -is removed once the operation completes. - -The ``NSEC3`` chain is generated and the ``NSEC3PARAM`` record is added before -the ``NSEC`` chain is destroyed. - -While the initial signing and ``NSEC``/``NSEC3`` chain generation are occurring, -other updates are possible as well. - -A new ``NSEC3PARAM`` record can be added via dynamic update. When the new -``NSEC3`` chain has been generated, the ``NSEC3PARAM`` flag field is set to -zero. At that point, the old ``NSEC3PARAM`` record can be removed. The old -chain is removed after the update request completes. - -:iscman:`named` only supports creating new ``NSEC3`` chains where all the -``NSEC3`` records in the zone have the same ``OPTOUT`` state. :iscman:`named` -supports updates to zones where the ``NSEC3`` records in the chain have mixed -``OPTOUT`` state. :iscman:`named` does not support changing the ``OPTOUT`` -state of an individual ``NSEC3`` record; if the ``OPTOUT`` state of an -individual ``NSEC3`` needs to be changed, the entire chain must be changed. - -To switch back to ``NSEC``, use :iscman:`nsupdate` to remove any ``NSEC3PARAM`` -records. The ``NSEC`` chain is generated before the ``NSEC3`` chain is removed. - -.. _dnssec_dynamic_zones_private_type_records: - -Private Type Records -^^^^^^^^^^^^^^^^^^^^ - -The state of the signing process is signaled by private type records (with a -default type value of 65534). When signing is complete, those records with a -non-zero initial octet have a non-zero value for the final octet. - -If the first octet of a private type record is non-zero, the record indicates -either that the zone needs to be signed with the key matching the record, or -that all signatures that match the record should be removed. Here are the -meanings of the different values of the first octet: - - - algorithm (octet 1) - - - key id in network order (octet 2 and 3) - - - removal flag (octet 4) - - - complete flag (octet 5) - -Only records flagged as "complete" can be removed via dynamic update; attempts -to remove other private type records are silently ignored. - -If the first octet is zero (this is a reserved algorithm number that should -never appear in a ``DNSKEY`` record), the record indicates that changes to the -``NSEC3`` chains are in progress. The rest of the record contains an -``NSEC3PARAM`` record, while the flag field tells what operation to perform -based on the flag bits: - - 0x01 OPTOUT - - 0x80 CREATE - - 0x40 REMOVE - - 0x20 NONSEC - -.. _dnssec_dynamic_zones_dnskey_rollovers: - -DNSKEY Rollovers -^^^^^^^^^^^^^^^^ - -To perform key rollovers via a dynamic update, the ``K*`` files for the new keys -must be added so that :iscman:`named` can find them. The new ``DNSKEY`` RRs can -then be added via dynamic update. When the zones are being signed, they are -signed with the new key set; when the signing is complete, the private type -records are updated so that the last octet is non-zero. - -If this is for a KSK, the parent and any trust anchor repositories of the new -KSK must be informed. - -The maximum TTL in the zone must expire before removing the old ``DNSKEY``. If -it is a KSK that is being updated, the DS RRset in the parent must also be -updated and its TTL allowed to expire. This ensures that all clients are able to -verify at least one signature when the old ``DNSKEY`` is removed. - -The old ``DNSKEY`` can be removed via ``UPDATE``, taking care to specify the -correct key. :iscman:`named` cleans out any signatures generated by the old -key after the update completes. - -.. _dnssec_dynamic_zones_going_insecure: - -Going Insecure -^^^^^^^^^^^^^^ - -To convert a signed zone to unsigned using dynamic DNS, delete all the -``DNSKEY`` records from the zone apex using :iscman:`nsupdate`. All signatures, -``NSEC`` or ``NSEC3`` chains, and associated ``NSEC3PARAM`` records are removed -automatically when the zone is supposed to be re-signed. - -This requires the ``dnssec-secure-to-insecure`` option to be set to ``yes`` in -:iscman:`named.conf`. - -In addition, if the ``auto-dnssec maintain`` or a ``dnssec-policy`` is used, it -should be removed or changed to ``allow`` instead; otherwise it will re-sign. - DNSSEC Validation ~~~~~~~~~~~~~~~~~ From 29030fa5d744b6a1a9cf25c81f45fbb8daab200a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Thu, 9 Jun 2022 09:04:24 +0200 Subject: [PATCH 12/22] Add hints about secure delegation to DNSSEC chapter of the ARM Let's not duplicate texts from elsewhere, just point to different parts of documentation. --- doc/arm/dnssec.inc.rst | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index a7110b302e..e2ca6ed0dd 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -77,6 +77,7 @@ These filenames contain: safe location and protect them from unauthorized access. Anyone with access to the private key can create fake but seemingly valid DNS data. + .. _dnssec_kasp: Fully Automated (Key and Signing Policy) @@ -428,6 +429,44 @@ to provide the parent zone administrators with the ``DNSKEYs`` (or their corresponding ``DS`` records) that are the secure entry point to the zone. +.. _secure_delegation: + +Secure Delegation +~~~~~~~~~~~~~~~~~ + +Once a zone is signed on the authoritative servers, the last remaining step +is to establish chain of trust [#validation]_ between the parent zone +(``example.``) and the local zone (``dnssec.example.``). + +Generally the procedure is: + + - **Wait** for stale data to expire from caches. The amount of time required + is equal to the maximum TTL value used in the zone before signing. This + step ensures that unsigned data expire from caches and resolvers do not get + confused by missing signatures. + - Insert/update DS records in the parent zone (``dnssec.example. DS`` record). + +There are multiple ways to update DS records in the parent zone. Refer to the +documentation for the parent zone to find out which options are applicable to +a given case zone. Generally the options are, from most- to least-recommended: + + - Automatically update the DS record in the parent zone using + ``CDS``/``CDNSKEY`` records automatically generated by BIND. This requires + support for :rfc:`7344` in either parent zone, registry, or registrar. In + that case, configure BIND to :ref:`monitor DS records in the parent + zone ` and everything will happen automatically at the right + time. + - Query the zone for automatically generated ``CDS`` or ``CDNSKEY`` records using + :iscman:`dig`, and then insert these records into the parent zone using + the method specified by the parent zone (web form, e-mail, API, ...). + - Generate DS records manually using the :iscman:`dnssec-dsfromkey` utility on + `zone keys`_, and then insert them into the parent zone. + +.. [#validation] For further details on how the chain of trust is used in practice, see + :ref:`dnssec_12_steps` in the :doc:`dnssec-guide`. + + + DNSSEC Validation ~~~~~~~~~~~~~~~~~ From bffa3063f0c624ef3efcd9dfa882eac95542f3e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Thu, 9 Jun 2022 11:53:13 +0200 Subject: [PATCH 13/22] Rewrite DNSSEC Validation subchapter in the ARM Mostly deduplicating and linking information across the ARM. Generally people should not touch it unless they what they are doing, so let's try to discourage them a bit. --- doc/arm/dnssec.inc.rst | 135 +++++++++++++---------------------------- doc/arm/reference.rst | 4 +- 2 files changed, 45 insertions(+), 94 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index e2ca6ed0dd..397c9d0ab7 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -470,113 +470,62 @@ a given case zone. Generally the options are, from most- to least-recommended: DNSSEC Validation ~~~~~~~~~~~~~~~~~ -To enable :iscman:`named` to validate answers received from other servers, the -``dnssec-validation`` option must be set to either ``yes`` or ``auto``. +The BIND resolver validates answers from authoritative servers by default. This +behavior is controlled by the configuration statement :ref:`dnssec-validation +`. -When ``dnssec-validation`` is set to ``auto``, a trust anchor for the -DNS root zone is automatically used. This trust anchor is provided -as part of BIND and is kept up to date using :rfc:`5011` key management. +By default a trust anchor for the DNS root zone is used. +This trust anchor is provided as part of BIND and is kept up-to-date using +:ref:`rfc5011.support`. -When ``dnssec-validation`` is set to ``yes``, DNSSEC validation -only occurs if at least one trust anchor has been explicitly configured -in :iscman:`named.conf`, using a ``trust-anchors`` statement (or the -``managed-keys`` and ``trusted-keys`` statements, both deprecated). +.. note:: + DNSSEC validation works "out of the box" and does not require + additional configuration. Additional configuration options are intended only + for special cases. -When ``dnssec-validation`` is set to ``no``, DNSSEC validation does not -occur. +To validate answers, the resolver needs at least one trusted starting point, +a "trust anchor." Essentially, trust anchors are copies of ``DNSKEY`` RRs for +zones that are used to form the first link in the cryptographic chain of trust. +Alternative trust anchors can be specified using :ref:`trust_anchors`, but +this setup is very unusual and is recommended only for expert use. +For more information, see :ref:`trust_anchors_description` in the +:doc:`dnssec-guide`. -The default is ``auto`` unless BIND is built with -``configure --disable-auto-validation``, in which case the default is -``yes``. - -The keys specified in ``trust-anchors`` are copies of ``DNSKEY`` RRs for zones -that are used to form the first link in the cryptographic chain of trust. Keys -configured with the keyword ``static-key`` or ``static-ds`` are loaded directly -into the table of trust anchors, and can only be changed by altering the -configuration. Keys configured with ``initial-key`` or ``initial-ds`` are used -to initialize :rfc:`5011` trust anchor maintenance, and are kept up-to-date -automatically after the first time :iscman:`named` runs. - -``trust-anchors`` is described in more detail later in this document. - -BIND 9 does not verify signatures on load, so zone keys +The BIND authoritative server does not verify signatures on load, so zone keys for authoritative zones do not need to be specified in the configuration file. -After DNSSEC is established, a typical DNSSEC configuration looks -something like the following. It has one or more public keys for the -root, which allows answers from outside the organization to be validated. -It also has several keys for parts of the namespace that the -organization controls. These are here to ensure that :iscman:`named` is immune -to compromised security in the DNSSEC components of parent zones. +Validation Failures +^^^^^^^^^^^^^^^^^^^ -:: - - trust-anchors { - /* Root Key */ - "." initial-key 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwS - JxrGkxJWoZu6I7PzJu/E9gx4UC1zGAHlXKdE4zYIpRh - aBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3zy2Xy - 4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYg - hf+6fElrmLkdaz MQ2OCnACR817DF4BBa7UR/beDHyp - 5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M/lUUVRbke - g1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq - 66gKodQj+MiA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ - 97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ - dgxbcDTClU0CRBdiieyLMNzXG3"; - /* Key for our organization's forward zone */ - example.com. static-ds 54135 5 2 "8EF922C97F1D07B23134440F19682E7519ADDAE180E20B1B1EC52E7F58B2831D" - - /* Key for our reverse zone. */ - 2.0.192.IN-ADDRPA.NET. static-key 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc - xOdNax071L18QqZnQQQAVVr+i - LhGTnNGp3HoWQLUIzKrJVZ3zg - gy3WwNT6kZo6c0tszYqbtvchm - gQC8CzKojM/W16i6MG/eafGU3 - siaOdS0yOI6BgPsw+YZdzlYMa - IJGf4M4dyoKIhzdZyQ2bYQrjy - Q4LB0lC7aOnsMyYKHHYeRvPxj - IQXmdqgOJGq+vsevG06zW+1xg - YJh9rCIfnm1GX/KMgxLPG2vXT - D/RnLX+D3T3UL7HJYHJhAZD5L - 59VvjSPsZJHeDCUyWYrvPZesZ - DIRvhDD52SKvbheeTJUm6Ehkz - ytNN2SN96QRk8j/iI8ib"; - }; - - options { - ... - dnssec-validation yes; - }; - -.. - -.. note:: - - None of the keys listed in this example are valid. In particular, the - root key is not valid. - -When DNSSEC validation is enabled and properly configured, the resolver -rejects any answers from signed, secure zones which fail to -validate, and returns SERVFAIL to the client. +When DNSSEC validation is configured, the resolver rejects any answers from +signed, secure zones which fail to validate, and returns SERVFAIL to the +client. Responses may fail to validate for any of several reasons, including missing, expired, or invalid signatures; a key which does not match the DS RRset in the parent zone; or an insecure response from a zone which, according to its parent, should have been secure. -.. note:: +For more information see :ref:`dnssec_troubleshooting`. - When the validator receives a response from an unsigned zone that has - a signed parent, it must confirm with the parent that the zone was - intentionally left unsigned. It does this by verifying, via signed - and validated NSEC/NSEC3 records, that the parent zone contains no DS - records for the child. +Coexistence With Unsigned (Insecure) Zones +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - If the validator *can* prove that the zone is insecure, then the - response is accepted. However, if it cannot, the validator must assume an - insecure response to be a forgery; it rejects the response and logs - an error. +Zones not protected by DNSSEC are called "insecure," and these zones seamlessly +coexist with signed zones. - The logged error reads "insecurity proof failed" and "got insecure - response; parent indicates it should be secure." +When the validator receives a response from an unsigned zone that has +a signed parent, it must confirm with the parent that the zone was +intentionally left unsigned. It does this by verifying, via signed +and validated :ref:`NSEC/NSEC3 records +`, that the parent zone contains no +DS records for the child. + +If the validator *can* prove that the zone is insecure, then the +response is accepted. However, if it cannot, the validator must assume an +insecure response to be a forgery; it rejects the response and logs +an error. + +The logged error reads "insecurity proof failed" and "got insecure +response; parent indicates it should be secure." diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index 54ca960b67..2b1f46b65f 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -2114,7 +2114,9 @@ Boolean Options This option enables DNSSEC validation in :iscman:`named`. If set to ``auto``, DNSSEC validation is enabled and a default trust - anchor for the DNS root zone is used. + anchor for the DNS root zone is used. This trust anchor is provided + as part of BIND and is kept up-to-date using :ref:`rfc5011.support` key + management. If set to ``yes``, DNSSEC validation is enabled, but a trust anchor must be manually configured using a ``trust-anchors`` statement (or the From 5ba618fd28a5a89d129ef74e462d4aef93f156a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Thu, 16 Jun 2022 12:56:04 +0200 Subject: [PATCH 14/22] Move Private Type Records in DNSSEC chapter to higher level Private Type Records are not specific to manually signing, so it is better to move it to the end of the "Zone Signing" section shared by all three methods. --- doc/arm/dnssec.inc.rst | 75 ++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index 397c9d0ab7..cce6aa56f7 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -284,45 +284,6 @@ individual ``NSEC3`` needs to be changed, the entire chain must be changed. To switch back to ``NSEC``, use :iscman:`nsupdate` to remove any ``NSEC3PARAM`` records. The ``NSEC`` chain is generated before the ``NSEC3`` chain is removed. -.. _dnssec_dynamic_zones_private_type_records: - -Private Type Records -==================== - -The state of the signing process is signaled by private type records (with a -default type value of 65534). When signing is complete, those records with a -non-zero initial octet have a non-zero value for the final octet. - -If the first octet of a private type record is non-zero, the record indicates -either that the zone needs to be signed with the key matching the record, or -that all signatures that match the record should be removed. Here are the -meanings of the different values of the first octet: - - - algorithm (octet 1) - - - key id in network order (octet 2 and 3) - - - removal flag (octet 4) - - - complete flag (octet 5) - -Only records flagged as "complete" can be removed via dynamic update; attempts -to remove other private type records are silently ignored. - -If the first octet is zero (this is a reserved algorithm number that should -never appear in a ``DNSKEY`` record), the record indicates that changes to the -``NSEC3`` chains are in progress. The rest of the record contains an -``NSEC3PARAM`` record, while the flag field tells what operation to perform -based on the flag bits: - - 0x01 OPTOUT - - 0x80 CREATE - - 0x40 REMOVE - - 0x20 NONSEC - .. _dnssec_dynamic_zones_dnskey_rollovers: DNSKEY Rollovers @@ -428,6 +389,42 @@ should be referenced by :iscman:`named.conf` as the input file for the zone. to provide the parent zone administrators with the ``DNSKEYs`` (or their corresponding ``DS`` records) that are the secure entry point to the zone. +Monitoring with Private Type Records +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The state of the signing process is signaled by private type records (with a +default type value of 65534). When signing is complete, those records with a +non-zero initial octet have a non-zero value for the final octet. + +If the first octet of a private type record is non-zero, the record indicates +either that the zone needs to be signed with the key matching the record, or +that all signatures that match the record should be removed. Here are the +meanings of the different values of the first octet: + + - algorithm (octet 1) + + - key ID in network order (octet 2 and 3) + + - removal flag (octet 4) + + - complete flag (octet 5) + +Only records flagged as "complete" can be removed via dynamic update; attempts +to remove other private type records are silently ignored. + +If the first octet is zero (this is a reserved algorithm number that should +never appear in a ``DNSKEY`` record), the record indicates that changes to the +``NSEC3`` chains are in progress. The rest of the record contains an +``NSEC3PARAM`` record, while the flag field tells what operation to perform +based on the flag bits: + + 0x01 OPTOUT + + 0x80 CREATE + + 0x40 REMOVE + + 0x20 NONSEC .. _secure_delegation: From 1dcc34f0768f69433b9bef4289747cdb4d9206c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Thu, 16 Jun 2022 13:06:11 +0200 Subject: [PATCH 15/22] Deduplicate key filename description in the DNSSEC chapter --- doc/arm/dnssec.inc.rst | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index cce6aa56f7..af0d10a84a 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -350,12 +350,8 @@ The following command generates an ECDSAP256SHA256 key for the ``dnssec-keygen -a ECDSAP256SHA256 -n ZONE child.example.`` Two output files are produced: ``Kchild.example.+013+12345.key`` and -``Kchild.example.+013+12345.private`` (where 12345 is an example of a -key tag). The key filenames contain the key name (``child.example.``), -the algorithm (5 is RSASHA1, 8 is RSASHA256, 13 is ECDSAP256SHA256, 15 is -ED25519, etc.), and the key tag (12345 in this case). The private key (in -the ``.private`` file) is used to generate signatures, and the public -key (in the ``.key`` file) is used for signature verification. +``Kchild.example.+013+12345.private``. Structure of the file names is described +in section `Zone Keys`_. To generate another key with the same properties but with a different key tag, repeat the above command. From 915237a28f94c2072d11b8171912ceea5452beee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Thu, 16 Jun 2022 13:13:03 +0200 Subject: [PATCH 16/22] Use code-block directive for complete command lines Minor rendering nit, not really important. --- doc/arm/dnssec.inc.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index af0d10a84a..f3722283a3 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -347,7 +347,9 @@ The :iscman:`dnssec-keygen` program is used to generate keys. The following command generates an ECDSAP256SHA256 key for the ``child.example`` zone: -``dnssec-keygen -a ECDSAP256SHA256 -n ZONE child.example.`` +.. code-block:: shell + + dnssec-keygen -a ECDSAP256SHA256 -n ZONE child.example. Two output files are produced: ``Kchild.example.+013+12345.key`` and ``Kchild.example.+013+12345.private``. Structure of the file names is described @@ -376,7 +378,9 @@ By default, all zone keys which have an available private key are used to generate signatures. The following command signs the zone, assuming it is in a file called ``zone.child.example``: -``dnssec-signzone -o child.example zone.child.example`` +.. code-block:: shell + + dnssec-signzone -o child.example zone.child.example One output file is produced: ``zone.child.example.signed``. This file should be referenced by :iscman:`named.conf` as the input file for the zone. From 3eb6898a143328bbdc3ce4773ff8c2e9fa581c6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Thu, 16 Jun 2022 13:43:19 +0200 Subject: [PATCH 17/22] Use ECDSAP256SHA256 in DNSSEC signing examples --- doc/dnssec-guide/signing.rst | 54 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/doc/dnssec-guide/signing.rst b/doc/dnssec-guide/signing.rst index d95a267a1d..6effd7f27c 100644 --- a/doc/dnssec-guide/signing.rst +++ b/doc/dnssec-guide/signing.rst @@ -1098,25 +1098,25 @@ Generate Keys Everything in DNSSEC centers around keys, so we begin by generating our own keys. -:: +.. code-block:: console - # cd /etc/bind - # dnssec-keygen -a RSASHA256 -b 1024 example.com - Generating key pair...........................+++++ ......................+++++ - Kexample.com.+008+34371 - # dnssec-keygen -a RSASHA256 -b 2048 -f KSK example.com - Generating key pair........................+++ ..................................+++ - Kexample.com.+008+00472 + # cd /etc/bind/keys + # dnssec-keygen -a ECDSAP256SHA256 example.com + Generating key pair...........................+++++ ......................+++++ + Kexample.com.+013+34371 + # dnssec-keygen -a ECDSAP256SHA256 -f KSK example.com + Generating key pair........................+++ ..................................+++ + Kexample.com.+013+00472 This command generates four key files in ``/etc/bind/keys``: -- Kexample.com.+008+34371.key +- Kexample.com.+013+34371.key -- Kexample.com.+008+34371.private +- Kexample.com.+013+34371.private -- Kexample.com.+008+00472.key +- Kexample.com.+013+00472.key -- Kexample.com.+008+00472.private +- Kexample.com.+013+00472.private The two files ending in ``.key`` are the public keys. These contain the DNSKEY resource records that appear in the zone. The two files @@ -1127,20 +1127,20 @@ Of the two pairs, one is the zone-signing key (ZSK), and one is the key-signing key (KSK). We can tell which is which by looking at the file contents (the actual keys are shortened here for ease of display): -:: +.. code-block:: console - # cat Kexample.com.+008+34371.key + # cat Kexample.com.+013+34371.key ; This is a zone-signing key, keyid 34371, for example.com. ; Created: 20200616104249 (Tue Jun 16 11:42:49 2020) ; Publish: 20200616104249 (Tue Jun 16 11:42:49 2020) ; Activate: 20200616104249 (Tue Jun 16 11:42:49 2020) - example.com. IN DNSKEY 256 3 8 AwEAAfel66...LqkA7cvn8= - # cat Kexample.com.+008+00472.key + example.com. IN DNSKEY 256 3 13 AwEAAfel66...LqkA7cvn8= + # cat Kexample.com.+013+00472.key ; This is a key-signing key, keyid 472, for example.com. ; Created: 20200616104254 (Tue Jun 16 11:42:54 2020) ; Publish: 20200616104254 (Tue Jun 16 11:42:54 2020) ; Activate: 20200616104254 (Tue Jun 16 11:42:54 2020) - example.com. IN DNSKEY 257 3 8 AwEAAbCR6U...l8xPjokVU= + example.com. IN DNSKEY 257 3 13 AwEAAbCR6U...l8xPjokVU= The first line of each file tells us what type of key it is. Also, by looking at the actual DNSKEY record, we can tell them apart: 256 is @@ -1179,15 +1179,15 @@ the zone on 1 July 2020, use it to sign records for a year starting on 15 July 2020, and remove it from the zone at the end of July 2021, we can use the following command: -:: +.. code-block:: console - # dnssec-settime -P 20200701 -A 20200715 -I 20210715 -D 20210731 Kexample.com.+008+34371.key - ./Kexample.com.+008+34371.key - ./Kexample.com.+008+34371.private + # dnssec-settime -P 20200701 -A 20200715 -I 20210715 -D 20210731 Kexample.com.+013+34371.key + ./Kexample.com.+013+34371.key + ./Kexample.com.+013+34371.private which would set the contents of the key file to: -:: +.. code-block:: none ; This is a zone-signing key, keyid 34371, for example.com. ; Created: 20200616104249 (Tue Jun 16 11:42:49 2020) @@ -1195,7 +1195,7 @@ which would set the contents of the key file to: ; Activate: 20200715000000 (Wed Jul 15 01:00:00 2020) ; Inactive: 20210715000000 (Thu Jul 15 01:00:00 2021) ; Delete: 20210731000000 (Sat Jul 31 01:00:00 2021) - example.com. IN DNSKEY 256 3 8 AwEAAfel66...LqkA7cvn8= + example.com. IN DNSKEY 256 3 13 AwEAAfel66...LqkA7cvn8= (The actual key is truncated here to improve readability.) @@ -1390,11 +1390,11 @@ command :iscman:`dnssec-signzone`: # cd /etc/bind/keys/example.com/ # dnssec-signzone -A -t -N INCREMENT -o example.com -f /etc/bind/db/example.com.signed.db \ - > /etc/bind/db/example.com.db Kexample.com.+008+17694.key Kexample.com.+008+06817.key - Verifying the zone using the following algorithms: RSASHA256. + > /etc/bind/db/example.com.db Kexample.com.+013+17694.key Kexample.com.+013+06817.key + Verifying the zone using the following algorithms: ECDSAP256SHA256. Zone fully signed: - Algorithm: RSASHA256: KSKs: 1 active, 0 stand-by, 0 revoked - ZSKs: 1 active, 0 stand-by, 0 revoked + Algorithm: ECDSAP256SHA256: KSKs: 1 active, 0 stand-by, 0 revoked + ZSKs: 1 active, 0 stand-by, 0 revoked /etc/bind/db/example.com.signed.db Signatures generated: 17 Signatures retained: 0 From 7e9680184121b19f26cf51d599a9579006c6381d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Thu, 16 Jun 2022 13:48:55 +0200 Subject: [PATCH 18/22] Deduplicate key filename description in the DNSSEC Guide Third time ... --- doc/arm/dnssec.inc.rst | 2 ++ doc/dnssec-guide/signing.rst | 12 +----------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index f3722283a3..2e14d163ac 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -52,6 +52,8 @@ during the lifetime of a DNS zone: - :ref:`dnssec_dynamic_zones` - only for special needs - :ref:`dnssec_tools` - discouraged, use only for debugging +.. _zone_keys: + Zone keys ^^^^^^^^^ Regardless of the :ref:`zone-signing ` method in use, cryptographic keys are diff --git a/doc/dnssec-guide/signing.rst b/doc/dnssec-guide/signing.rst index 6effd7f27c..0581b96f9b 100644 --- a/doc/dnssec-guide/signing.rst +++ b/doc/dnssec-guide/signing.rst @@ -1147,17 +1147,7 @@ looking at the actual DNSKEY record, we can tell them apart: 256 is ZSK, and 257 is KSK. The name of the file also tells us something -about the contents. The file names are of the form: - -:: - - K++ - -The "zone name" is self-explanatory. The "algorithm ID" is a number assigned -to the algorithm used to construct the key: the number appears in the -DNSKEY resource record. In -our example, 8 means the algorithm RSASHA256. Finally, the "keyid" is -essentially a hash of the key itself. +about the contents. See chapter :ref:`zone_keys` for more details. Make sure these files are readable by :iscman:`named` and make sure that the ``.private`` files are not readable by anyone else. From 7d2502789891e69c2475140d4d14370401759594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Thu, 16 Jun 2022 14:03:45 +0200 Subject: [PATCH 19/22] Deduplicate Manual Signing between DNSSEC chapter and DNSSEC Guide The two procedures were essentially the same, but each instance was missing some details from the other. They are now combined into one text in the DNSSEC Guide and linked from DNSSEC chapter. --- doc/arm/dnssec.inc.rst | 55 ++---------------------------------- doc/dnssec-guide/signing.rst | 51 +++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 64 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index 2e14d163ac..eb61a24f7b 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -338,58 +338,9 @@ There are several tools available to manually sign a zone. compatibility and should be used only by expert users with specific needs. To set up a DNSSEC secure zone manually, a series of steps -must be followed. BIND 9 ships with several tools that are used in -this process, which are explained in more detail below. In all cases, -the ``-h`` option prints a full list of parameters. Note that the DNSSEC -tools require the keyset files to be in the working directory or the -directory specified by the ``-d`` option. - -The :iscman:`dnssec-keygen` program is used to generate keys. - -The following command generates an ECDSAP256SHA256 key for the -``child.example`` zone: - -.. code-block:: shell - - dnssec-keygen -a ECDSAP256SHA256 -n ZONE child.example. - -Two output files are produced: ``Kchild.example.+013+12345.key`` and -``Kchild.example.+013+12345.private``. Structure of the file names is described -in section `Zone Keys`_. - -To generate another key with the same properties but with a different -key tag, repeat the above command. - -The :iscman:`dnssec-keyfromlabel` program is used to get a key pair from a -crypto hardware device and build the key files. Its usage is similar to -:iscman:`dnssec-keygen`. - -The public keys should be inserted into the zone file by including the -``.key`` files using ``$INCLUDE`` statements. - -The :iscman:`dnssec-signzone` program is used to sign a zone. - -Any ``keyset`` files corresponding to secure sub-zones should be -present. The zone signer generates ``NSEC``, ``NSEC3``, and ``RRSIG`` -records for the zone, as well as ``DS`` for the child zones if -:option:`-g ` is specified. If -:option:`-g ` is not specified, then DS RRsets for the -secure child zones need to be added manually. - -By default, all zone keys which have an available private key are used -to generate signatures. The following command signs the zone, assuming -it is in a file called ``zone.child.example``: - -.. code-block:: shell - - dnssec-signzone -o child.example zone.child.example - -One output file is produced: ``zone.child.example.signed``. This file -should be referenced by :iscman:`named.conf` as the input file for the zone. - -:iscman:`dnssec-signzone` also produces keyset and dsset files. These are used -to provide the parent zone administrators with the ``DNSKEYs`` (or their -corresponding ``DS`` records) that are the secure entry point to the zone. +must be followed. Please see chapter +:ref:`advanced_discussions_manual_key_management_and_signing` in the +:doc:`dnssec-guide` for more information. Monitoring with Private Type Records ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/dnssec-guide/signing.rst b/doc/dnssec-guide/signing.rst index 0581b96f9b..5495be2658 100644 --- a/doc/dnssec-guide/signing.rst +++ b/doc/dnssec-guide/signing.rst @@ -1152,6 +1152,10 @@ about the contents. See chapter :ref:`zone_keys` for more details. Make sure these files are readable by :iscman:`named` and make sure that the ``.private`` files are not readable by anyone else. +Alternativelly, the :iscman:`dnssec-keyfromlabel` program is used to get a key +pair from a crypto hardware device and build the key files. Its usage is +similar to :iscman:`dnssec-keygen`. + Setting Key Timing Information ++++++++++++++++++++++++++++++ @@ -1371,12 +1375,31 @@ including interaction with the parent. A user certainly can do all this, but why not use one of the automated methods? Nevertheless, it may be useful for test purposes, so we cover it briefly here. -The first step is to create the keys as described in :ref:`generate_keys`. -Then, edit the zone file to make sure -the proper DNSKEY entries are included in your zone file. Finally, use the -command :iscman:`dnssec-signzone`: +BIND 9 ships with several tools that are used in +this process, which are explained in more detail below. In all cases, +the ``-h`` option prints a full list of parameters. Note that the DNSSEC +tools require the keyset files to be in the working directory or the +directory specified by the ``-d`` option. -:: +The first step is to create the keys as described in :ref:`generate_keys`. + +Then, edit the zone file to make sure the proper DNSKEY entries are included. +The public keys should be inserted into the zone file by +including the ``.key`` files using ``$INCLUDE`` statements. + +Finally, use the command :iscman:`dnssec-signzone`. +Any ``keyset`` files corresponding to secure sub-zones should be +present. The zone signer generates ``NSEC``, ``NSEC3``, and ``RRSIG`` +records for the zone, as well as ``DS`` for the child zones if +:option:`-g ` is specified. If +:option:`-g ` is not specified, then DS RRsets for the +secure child zones need to be added manually. + +By default, all zone keys which have an available private key are used +to generate signatures. The following command signs the zone, assuming +it is in a file called ``zone.child.example``, using manually specified keys: + +.. code-block:: console # cd /etc/bind/keys/example.com/ # dnssec-signzone -A -t -N INCREMENT -o example.com -f /etc/bind/db/example.com.signed.db \ @@ -1395,17 +1418,21 @@ command :iscman:`dnssec-signzone`: Signatures per second: 364.634 Runtime in seconds: 0.055 -The -o switch explicitly defines the domain name (``example.com`` in -this case), while the -f switch specifies the output file name. The second line -has three parameters: the unsigned zone name -(``/etc/bind/db/example.com.db``), the ZSK file name, and the KSK file name. This -also generates a plain text file ``/etc/bind/db/example.com.signed.db``, -which you can verify for correctness. +The :option:`-o ` switch explicitly defines the domain name +(``example.com`` in this case), while the :option:`-f ` +switch specifies the output file name. The second line has three parameters: +the unsigned zone name (``/etc/bind/db/example.com.db``), the ZSK file name, +and the KSK file name. This also generates a plain-text file +``/etc/bind/db/example.com.signed.db``, which can be manually verified for correctness. + +:iscman:`dnssec-signzone` also produces keyset and dsset files. These are used +to provide the parent zone administrators with the ``DNSKEY`` records (or their +corresponding ``DS`` records) that are the secure entry point to the zone. Finally, you'll need to update :iscman:`named.conf` to load the signed version of the zone, which looks something like this: -:: +.. code-block:: none zone "example.com" IN { type primary; From f721986589e89f58385c73cc30dfac0336018a2d Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 16 Jun 2022 15:46:32 +0200 Subject: [PATCH 20/22] Add a section about key rollover Describe how to do key rollovers with dnssec-policy. Update the revert to unsigned recipe in the DNSSEC guide. --- doc/arm/dnssec.inc.rst | 47 ++++++++++++++++++- doc/dnssec-guide/recipes.rst | 91 ++++++++++++++++-------------------- 2 files changed, 84 insertions(+), 54 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index eb61a24f7b..b0f7dee3e8 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -156,8 +156,51 @@ Also: For more information about KASP configuration see :ref:`dnssec_policy_grammar`. -The :ref:`dnssec_advanced_discussions` in the DNSSEC Guide discusses the -various policy settings and may help you determining values for your special needs. +The :ref:`dnssec_advanced_discussions` section in the DNSSEC Guide discusses the +various policy settings and may be useful for determining values for specific +needs. + +Key Rollover +============ + +When using a ``dnssec-policy``, a key lifetime can be set to trigger +key rollovers. ZSK rollovers are fully automatic, but for KSK and CSK rollovers +a DS record needs to be submitted to the parent. See +:ref:`secure_delegation` for possible ways to do so. + +Once the DS is in the parent (and the DS of the predecessor key is withdrawn), +BIND needs to be told that this event has happened. This can be done automatically +by configuring parental agents: + +.. code-block:: none + :emphasize-lines: 5 + + zone "dnssec.example" { + type primary; + file "dnssec.example.db"; + dnssec-policy default; + parental-agents { 192.0.2.1; }; + }; + +Here one server, ``192.0.2.1``, is configured for BIND to send DS queries to, +to check the DS RRset for ``dnssec-example`` during key rollovers. This needs +to be a trusted server, because BIND does not validate the response. + +If setting up a parental agent is undesirable, it is also possible to tell BIND that the +DS is published in the parent with: +:option:`rndc dnssec -checkds -key 12345 published dnssec.example. `. +and the DS for the predecessor key has been removed with: +:option:`rndc dnssec -checkds -key 54321 withdrawn dnssec.example. `. +where 12345 and 54321 are the key tags of the successor and predecessor key, +respectively. + +To roll a key sooner than scheduled, or to roll a key that +has an unlimited lifetime, use: +:option:`rndc dnssec -rollover -key 12345 dnssec.example. `. + +To revert a signed zone back to an insecure zone, change +the zone configuration to use the built-in "insecure" policy. Detailed +instructions are described in :ref:`revert_to_unsigned`. .. _dnssec_dynamic_zones: diff --git a/doc/dnssec-guide/recipes.rst b/doc/dnssec-guide/recipes.rst index 8b30598035..ac66ca9497 100644 --- a/doc/dnssec-guide/recipes.rst +++ b/doc/dnssec-guide/recipes.rst @@ -986,12 +986,40 @@ Reverting to Unsigned This recipe describes how to revert from a signed zone (DNSSEC) back to an unsigned (DNS) zone. -Whether the world thinks your zone is signed is determined by the -presence of DS records hosted by your parent zone; if there are no DS records, -the world sees your zone as unsigned. So reverting to unsigned is as -easy as removing all DS records from the parent zone. +Here is what :iscman:`named.conf` looks like when it is signed: -Below is an example showing how to remove DS records using the +.. code-block:: none + :emphasize-lines: 4 + + zone "example.com" IN { + type primary; + file "db/example.com.db"; + dnssec-policy "default"; + }; + +To indicate the reversion to unsigned, change the ``dnssec-policy`` line: + +.. code-block:: none + :emphasize-lines: 4 + + zone "example.com" IN { + type primary; + file "db/example.com.db"; + dnssec-policy "insecure"; + }; + +Then use :option:`rndc reload` to reload the zone. + +The "insecure" policy is a built-in policy (like "default"). It makes sure +the zone is still DNSSEC-maintained, to allow for a graceful transition to +unsigned. It also publishes the CDS and CDNSKEY DELETE records automatically +at the appropriate time. + +If the parent zone allows management of DS records via CDS/CDNSKEY, as described in +:rfc:`8078`, the DS record should be removed from the parent automatically. + +Otherwise, DS records can be removed via the registrar. Below is an example +showing how to remove DS records using the `GoDaddy `__ web-based interface: 1. After logging in, click the green "Launch" button next to the domain @@ -1036,58 +1064,17 @@ Below is an example showing how to remove DS records using the Revert to Unsigned Step #4 -If your parent allows managing DS record via CDS/CDNSKEY, as described in -:rfc:`5155`, you could add CDS/CDNSKEY DELETE records in your zone to signal -that the corresponding DS records from the parent zone needs to be removed. -If it is unclear which format the parent zone is expecting, you should publish -both CDS and CDNSKEY DELETE records. - -To be on the safe side, wait a while before actually deleting -all signed data from your zone, just in case some validating resolvers -have cached information. After you are certain that all cached -information has expired (usually this means one TTL interval has passed), -you may reconfigure your zone. - -Here is what :iscman:`named.conf` looks like when it is signed: - -:: - - zone "example.com" IN { - type primary; - file "db/example.com.db"; - allow-transfer { any; }; - dnssec-policy "default"; - }; - -Change your ``dnssec-policy`` line to indicate you want to revert to unsigned: - -:: - - zone "example.com" IN { - type primary; - file "db/example.com.db"; - allow-transfer { any; }; - dnssec-policy "insecure"; - }; - -Then use :option:`rndc reload` to reload the zone. - -The "insecure" policy is a built-in policy (like "default"). It will make sure -the zone is still DNSSEC maintained, to allow for a graceful transition to -unsigned. It also publishes the CDS and CDNSKEY DELETE records for you when -the time is right. - When the DS records have been removed from the parent zone, use :option:`rndc dnssec -checkds -key id withdrawn example.com ` to tell :iscman:`named` that the DS is removed, and the remaining DNSSEC records will be removed in a timely -manner. Or if you have parental agents configured, the DNSSEC records will be +manner. Or, if parental agents are configured, the DNSSEC records will be automatically removed after BIND has seen that the parental agents no longer -serves the DS RRset for this zone. +serve the DS RRset for this zone. -After a while, your zone is reverted back to the traditional, insecure DNS -format. You can verify by checking that all DNSKEY and RRSIG records have been +After a while, the zone is reverted back to the traditional, insecure DNS +format. This can be verified by checking that all DNSKEY and RRSIG records have been removed from the zone. -You can then remove the ``dnssec-policy`` line from your :iscman:`named.conf` and -reload the zone. The zone will now no longer be subject to any DNSSEC +The ``dnssec-policy`` line can then be removed from :iscman:`named.conf` and +the zone reloaded. The zone will no longer be subject to any DNSSEC maintenance. From 6b1ad4dcfba41585be42b94592ee924b7b781cf5 Mon Sep 17 00:00:00 2001 From: Suzanne Goldlust Date: Fri, 17 Jun 2022 15:06:23 +0000 Subject: [PATCH 21/22] Minor grammar improvements in the Signing chapter of the DNSSEC Guide --- doc/arm/dnssec.inc.rst | 2 +- doc/dnssec-guide/signing.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index b0f7dee3e8..99515b492b 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -147,7 +147,7 @@ This ``custom`` policy, for example: rotated after one year and the ZSK after 60 days. Also: - - The configured keys also have a lifetime set and use the ECDSAP384SHA384 + - The configured keys have a lifetime set and use the ECDSAP384SHA384 algorithm. - The last line instructs BIND to generate NSEC3 records for :ref:`Proof of Non-Existence `, diff --git a/doc/dnssec-guide/signing.rst b/doc/dnssec-guide/signing.rst index 5495be2658..1d19908323 100644 --- a/doc/dnssec-guide/signing.rst +++ b/doc/dnssec-guide/signing.rst @@ -1149,7 +1149,7 @@ ZSK, and 257 is KSK. The name of the file also tells us something about the contents. See chapter :ref:`zone_keys` for more details. -Make sure these files are readable by :iscman:`named` and make sure that the +Make sure that these files are readable by :iscman:`named` and that the ``.private`` files are not readable by anyone else. Alternativelly, the :iscman:`dnssec-keyfromlabel` program is used to get a key @@ -1429,7 +1429,7 @@ and the KSK file name. This also generates a plain-text file to provide the parent zone administrators with the ``DNSKEY`` records (or their corresponding ``DS`` records) that are the secure entry point to the zone. -Finally, you'll need to update :iscman:`named.conf` to load the signed version +Finally, :iscman:`named.conf` needs to be updated to load the signed version of the zone, which looks something like this: .. code-block:: none From 146c125988bbfcb8e4024313f21014b7be5c77d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Tue, 21 Jun 2022 15:08:17 +0200 Subject: [PATCH 22/22] Mention zone storage in the DNSSEC chapter Let's not duplicate texts, link to description elsewhere instead. --- doc/arm/dnssec.inc.rst | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/doc/arm/dnssec.inc.rst b/doc/arm/dnssec.inc.rst index 99515b492b..dab187f028 100644 --- a/doc/arm/dnssec.inc.rst +++ b/doc/arm/dnssec.inc.rst @@ -106,17 +106,9 @@ This single line is sufficient to create the necessary signing keys, and generat care of any DNSSEC maintenance for this zone, including replacing signatures that are about to expire and managing :ref:`key_rollovers`. -**TODO:** -The original zone file :file:`dnssec.example.db` remains untouched and the -signed version of the zone is stored on disk in :file:`dnssec.example.db.signed`. -When setting a ``dnssec-policy`` for a zone, it typically creates a new file -with a ``.signed`` extension on disk, while the original zone file stays -untouched. This is called inline signing. - -DNSSEC configuration works slightly differently for dynamic zones. DNSSEC-related -records are applied directly to zones with an update ACL or update -policy, similarly to non-DNSSEC records, instead of storing them in a file with a -``.signed`` extension. +.. note:: + ``dnssec-policy`` needs write access to the zone. Please see + :ref:`dnssec_policy` for more details about implications for zone storage. The default policy creates one key that is used to sign the complete zone, and uses ``NSEC`` to enable authenticated denial of existence (a secure way