look at the first one, NSEC, next.
.. _advanced_discussions_nsec:
+.. _NSEC:
NSEC
^^^^
::
- example.com. 300 IN NSEC alice.example.com. A RRSIG NSEC
+ example.com. 300 IN NSEC alice.example.com. A RRSIG NSEC
alice.example.com. 300 IN NSEC edward.example.com. A RRSIG NSEC
edward.example.com. 300 IN NSEC susan.example.com. A RRSIG NSEC
susan.example.com. 300 IN NSEC example.com. A RRSIG NSEC
in DNS! Consider using DNS views (split DNS) and only display your
sensitive names to a select audience.
-The second drawback of NSEC is actually increased operational
-overhead: there is no opt-out mechanism for insecure child zones. This generally
-is a problem for parent-zone operators dealing with a lot of insecure
-child zones, such as ``.com``. To learn more about opt-out, please see
-:ref:`advanced_discussions_nsec3_optout`.
+The second potential drawback of NSEC is a bigger zone file and memory consumption;
+there is no opt-out mechanism for insecure child zones, so each name
+in the zone will get an additional NSEC record and a RRSIG record to go with
+it. In practice this is a problem only for parent-zone operators dealing with
+mostly insecure child zones, such as ``com.``. To learn more about opt-out,
+please see :ref:`advanced_discussions_nsec3_optout`.
.. _advanced_discussions_nsec3:
+.. _nsec3:
NSEC3
^^^^^
NSEC3 basically runs the names through a one-way hash before giving them
out, so the recipients can verify the non-existence without any
-knowledge of the actual names.
+knowledge of the other names in the zone.
So let's tell our little story for the third time, this
time with NSEC3. In this version, our intern is not given a list of actual
::
- FSK5....example.com. 300 IN NSEC3 1 0 10 1234567890ABCDEF JKMA... A RRSIG
- JKMA....example.com. 300 IN NSEC3 1 0 10 1234567890ABCDEF NTQ0... A RRSIG
- NTQ0....example.com. 300 IN NSEC3 1 0 10 1234567890ABCDEF FSK5... A RRSIG
+ FSK5....example.com. 300 IN NSEC3 1 0 0 - JKMA... A RRSIG
+ JKMA....example.com. 300 IN NSEC3 1 0 0 - NTQ0... A RRSIG
+ NTQ0....example.com. 300 IN NSEC3 1 0 0 - FSK5... A RRSIG
.. note::
Just because we employed one-way hash functions does not mean there is
no way for a determined individual to figure out our zone data.
- Someone could still gather all of our NSEC3 records and hashed
- names and perform an offline brute-force attack by trying all
- possible combinations to figure out what the original name is. In our
- meat-grinder analogy, this would be like someone
- buying all available cuts of meat and grinding them up at home using
- the same model of meat grinder, and comparing the output with the meat
- you gave him. It is expensive and time-consuming (especially with
- real meat), but like everything else in cryptography, if someone has
- enough resources and time, nothing is truly private forever. If you
- are concerned about someone performing this type of attack on your
- zone data, read more about adding salt as described in
- :ref:`advanced_discussions_nsec3_salt`.
+
+Most names published in the DNS are rarely secret or unpredictable. They are
+published to be memorable, used and consumed by humans. They are often recorded
+in many other network logs such as email logs, certificate transparency logs,
+web page links, intrusion detection systems, malware scanners, email archives,
+etc. Many times a simple dictionary of commonly used domain-name prefixes
+(www, mail, imap, login, database, etc.) can be used to quickly reveal a large
+number of labels within a zone. Additionally, if an adversary really wants to
+expend significant CPU resources to mount an offline dictionary attack on a
+zone's NSEC3 chain, they will likely be able to find most of the "guessable"
+names despite any level of hashing.
+
+Also, it is still possible to gather all of our NSEC3 records and hashed
+names and perform an offline brute-force attack by trying all
+possible combinations to figure out what the original name is. In our
+meat-grinder analogy, this would be like someone
+buying all available cuts of meat and grinding them up at home using
+the same model of meat grinder, and comparing the output with the meat
+you gave him. It is expensive and time-consuming (especially with
+real meat), but like everything else in cryptography, if someone has
+enough resources and time, nothing is truly private forever. If you
+are concerned about someone performing this type of attack on your
+zone data, use some of the special techniques described in :rfc:`4470`.
.. _advanced_discussions_nsec3param:
NSEC3PARAM
++++++++++
-The above NSEC3 examples used four parameters: 1, 0, 10, and
-1234567890ABCDEF. 1 represents the algorithm, 0 represents the opt-out
-flag, 10 represents the number of iterations, and 1234567890ABCDEF is the
+.. warning::
+ Before we dive into the details of NSEC3 parametrization, please note:
+ the defaults should not be changed without a strong justification and a full
+ understanding of the potential impact.
+
+The above NSEC3 examples used four parameters: 1, 0, 0, and
+zero-length salt. 1 represents the algorithm, 0 represents the opt-out
+flag, 0 represents the number of additional iterations, and - is the
salt. Let's look at how each one can be configured:
-- *Algorithm*: The only currently defined value is 1 for SHA-1, so there
- is no configuration field for it.
+.. glossary::
-- *Opt-out*: Set this to 1 for NSEC3 opt-out, which we
- discuss in :ref:`advanced_discussions_nsec3_optout`.
+ Algorithm
+ NSEC3 Hashing Algorithm
+ The only currently defined value is 1 for SHA-1, so there
+ is no configuration field for it.
-- *Iterations*: Iterations defines the number of additional times to
- apply the algorithm when generating an NSEC3 hash. More iterations
- yield more secure results, but consume more resources for both
- authoritative servers and validating resolvers. The considerations
- here are similar to those seen in :ref:`key_sizes`, of
- security versus resources.
+ Opt-out
+ Setting this bit to 1 enables NSEC3 opt-out, which is
+ discussed in :ref:`advanced_discussions_nsec3_optout`.
-- *Salt*: The salt cannot be configured explicitly, but you can provide
- a salt length and ``named`` generates a random salt of the given length.
- We learn more about salt in :ref:`advanced_discussions_nsec3_salt`.
+ Iterations
+ Iterations defines the number of _additional_ times to
+ apply the algorithm when generating an NSEC3 hash. More iterations
+ consume more resources for both authoritative servers and validating
+ resolvers. The considerations here are similar to those seen in
+ :ref:`key_sizes`, of security versus resources.
-If you want to use these NSEC3 parameters for a zone, you can add the
-following configuration to your ``dnssec-policy``. For example, to create an
-NSEC3 chain using the SHA-1 hash algorithm, with no opt-out flag,
-5 iterations, and a salt that is 8 characters long, use:
+ .. warning::
+ Do not use values higher than zero. A value of zero provides one round
+ of SHA-1 hashing and protects from non-determined attackers.
-::
+ A greater number of additional iterations causes interoperability problems
+ and opens servers to CPU-exhausting DoS attacks, while providing
+ only doubtful security benefits.
- dnssec-policy "nsec3" {
- ...
- nsec3param iterations 5 optout no salt-length 8;
- };
+ Salt
+ A salt value, which can be combined with an FQDN to influence the
+ resulting hash. Salt is discussed in more detail in
+ :ref:`advanced_discussions_nsec3_salt`.
-To set the opt-out flag, 15 iterations, and no salt, use:
+.. _advanced_discussions_nsec3_optout:
-::
+NSEC3 Opt-Out
++++++++++++++
+
+First things first: For most DNS administrators who do not manage a huge number
+of insecure delegations, the NSEC3 opt-out featuere is not relevant.
+
+Opt-out allows for blocks of unsigned delegations to be covered by a single NSEC3
+record. In other words, use of the opt-out allows large registries to only sign as
+many NSEC3 records as there are signed DS or other RRsets in the zone; with
+opt-out, unsigned delegations do not require additional NSEC3 records. This
+sacrifices the tamper-resistance proof of non-existence offered by NSEC3 in
+order to reduce memory and CPU overheads, and decreases the effectiveness of the cache
+(:rfc:`8198`).
+
+Why would that ever be desirable? If a significant number of delegations
+are not yet securely delegated, meaning they lack DS records and are still
+insecure or unsigned, generating DNSSEC records for all their NS records
+might consume lots of memory and is not strictly required by the child zones.
+
+This resource-saving typically makes a difference only for *huge* zones like ``com.``.
+Imagine that you are the operator of busy top-level domains such as ``com.``,
+with millions of insecure delegated domain names.
+As of mid-2022, around 3% of all ``com.`` zones are signed. Basically,
+without opt-out, with 1,000,000 delegations, only 30,000 of which are secure, you
+still have to generate NSEC RRsets for the other 970,000 delegations; with
+NSEC3 opt-out, you will have saved yourself 970,000 sets of records.
+
+In contrast, for a small zone the difference is operationally negligible
+and the drawbacks outweigh the benefits.
+
+If NSEC3 opt-out is truly essential for a zone, the following
+configuration can be added to ``dnssec-policy``; for example, to create an
+NSEC3 chain using the SHA-1 hash algorithm, with the opt-out flag,
+no additional iterations, and no extra salt, use:
+
+.. code-block:: none
dnssec-policy "nsec3" {
...
- nsec3param iterations 15 optout yes salt-length 0;
+ nsec3param iterations 0 optout yes salt-length 0;
};
-.. _advanced_discussions_nsec3_optout:
-
-NSEC3 Opt-Out
-+++++++++++++
-One of the advantages of NSEC3 over NSEC is the ability for a parent zone
-to publish less information about its child or delegated zones. Why
-would you ever want to do that? If a significant number of your
-delegations are not yet DNSSEC-aware, meaning they are still insecure or
-unsigned, generating DNSSEC-records for their NS and glue records is not
-a good use of your precious name server resources.
-
-The resources may not seem like a lot, but imagine that you are the
-operator of busy top-level domains such as ``.com`` or ``.net``, with
-millions of insecure delegated domain names: it quickly
-adds up. As of mid-2020, less than 1.5% of all ``.com`` zones are
-signed. Basically, without opt-out, with 1,000,000 delegations,
-only 5 of which are secure, you still have to generate NSEC RRsets for
-the other 999,995 delegations; with NSEC3 opt-out, you will have saved
-yourself 999,995 sets of records.
-
-For most DNS administrators who do not manage a large number of
-delegations, the decision whether to use NSEC3 opt-out is
-probably not relevant.
To learn more about how to configure NSEC3 opt-out, please see
:ref:`recipes_nsec3_optout`.
NSEC3 Salt
++++++++++
-As described in :ref:`advanced_discussions_nsec3`, while NSEC3
-does not put your zone data in plain public display, it is still not
-difficult for an attacker to collect all the hashed names and perform
-an offline attack. All that is required is running through all the
-combinations to construct a database of plaintext names to hashed names,
-also known as a "rainbow table."
-
-There is one more feature NSEC3 gives us to provide additional
-protection: salt. Basically, salt gives us the ability to introduce further
-randomness into the hashed results. Whenever the salt is changed, any
-pre-computed rainbow table is rendered useless, and a new rainbow table
-must be re-computed. If the salt is changed periodically, it
-becomes difficult to construct a useful rainbow table, and thus difficult to
-walk the DNS zone data programmatically. How often you want to change
-your NSEC3 salt is up to you.
-
-To learn more about the steps to take to change NSEC3, please see
-:ref:`recipes_nsec3_salt`.
+.. warning::
+ Contrary to popular belief, adding salt provides little value.
+ Each DNS zone is always uniquely salted using the zone name. **Operators should
+ use a zero-length salt value.**
+
+The properties of this extra salt are complicated and beyond scope of this
+document. For detailed description why the salt in the context of DNSSEC
+provides little value please see `IETF draft ietf-dnsop-nsec3-guidance version
+10 section 2.4
+<https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-nsec3-guidance-10#section-2.4>`__.
.. _advanced_discussions_nsec_or_nsec3:
NSEC or NSEC3?
^^^^^^^^^^^^^^
-So which one should you choose: NSEC or NSEC3? There is not a
-single right answer here that fits everyone; it comes down to your
-network's needs or requirements.
-
-If you prefer not to make your zone easily enumerable, implementing
-NSEC3 paired with a periodically changed salt provides a certain
-level of privacy protection. However, someone could still randomly guess
-the names in your zone (such as "ftp" or "www"), as in the traditional
-insecure DNS.
-
-If you have many delegations and need to be able to opt-out to save
-resources, NSEC3 is for you.
+So which is better: NSEC or NSEC3? There is no single right
+answer here that fits everyone; it comes down to a given network's needs or
+requirements.
-In other situations, NSEC is typically a good choice for most zone
-administrators, as it relieves the authoritative servers of the
-additional cryptographic operations that NSEC3 requires, and NSEC is
-comparatively easier to troubleshoot than NSEC3.
+In most cases, NSEC is a good choice for zone administrators. It
+relieves the authoritative servers and resolver of the additional cryptographic
+operations that NSEC3 requires, and NSEC is comparatively easier to
+troubleshoot than NSEC3.
-NSEC3 in conjunction with ``dnssec-policy`` is supported in BIND
-as of version 9.16.9.
+NSEC3 comes with many drawbacks and should be implemented only if zone
+enumeration prevention is really needed, or when opt-out provides a
+significant reduction in memory and CPU overheads (in other words, with a
+huge zone with mostly insecure delegations).
.. _advanced_discussions_key_generation:
actually signed. What this means is, even if your company's zone is
signed today, fewer than 30% of the Internet's servers are taking
advantage of this extra security. It gets worse: with less than 1.5%
- of the ``.com`` domains signed, even if your DNSSEC validation is enabled today,
+ of the ``com.`` domains signed, even if your DNSSEC validation is enabled today,
it's not likely to buy you or your users a whole lot more protection
until these popular domain names decide to sign their zones.
To enable NSEC3, update your ``dnssec-policy`` and add the desired NSEC3
parameters. The example below enables NSEC3 for zones with the ``standard``
-DNSSEC policy, using 10 iterations, no opt-out, and a random string that is
-16 characters long:
+DNSSEC policy, using 0 additional iterations, no opt-out, and a zero-length salt:
::
dnssec-policy "standard" {
- nsec3param iterations 10 optout no salt-length 16;
+ nsec3param iterations 0 optout no salt-length 0;
};
Then reconfigure the server with ``rndc``. You can tell that it worked if you
::
Oct 21 13:47:21 received control channel command 'reconfig'
- Oct 21 13:47:21 zone example.com/IN (signed): zone_addnsec3chain(1,CREATE,10,1234567890ABCDEF)
+ Oct 21 13:47:21 zone example.com/IN (signed): zone_addnsec3chain(1,CREATE,0,-)
You can also verify that it worked by querying for a name that you know
does not exist, and checking for the presence of the NSEC3 record.
$ dig @192.168.1.13 thereisnowaythisexists.example.com. A +dnssec +multiline
...
- TOM10UQBL336NFAQB3P6MOO53LSVG8UI.example.com. 300 IN NSEC3 1 0 10 1234567890ABCDEF (
+ 5A03TL362CS8VSIH69CVA4MJIKRHFQH3.example.com. 300 IN NSEC3 1 0 0 - (
TQ9QBEGA6CROHEOC8KIH1A2C06IVQ5ER
NS SOA RRSIG DNSKEY NSEC3PARAM )
...
-Our example used four parameters: 1, 0, 10, and 1234567890ABCDEF, in
+Our example used four parameters: 1, 0, 0, and -, in
order. 1 represents the algorithm, 0 represents the
-opt-out flag, 10 represents the number of iterations, and
-1234567890ABCDEF is the salt. To learn more about each of these
+opt-out flag, 0 represents the number of additional iterations, and
+- denotes no salt is used. To learn more about each of these
parameters, please see :ref:`advanced_discussions_nsec3param`.
.. _recipes_nsec3_to_nsec:
::
named[14093]: received control channel command 'reconfig'
- named[14093]: zone example.com/IN: zone_addnsec3chain(1,REMOVE,10,1234567890ABCDEF)
+ named[14093]: zone example.com/IN: zone_addnsec3chain(1,REMOVE,0,-)
You can also query for a name that you know does not exist,
and you should no longer see any traces of NSEC3 records.
ns1.example.com. 300 IN NSEC web.example.com. A RRSIG NSEC
...
-.. _recipes_nsec3_salt:
-
-Changing the NSEC3 Salt
-^^^^^^^^^^^^^^^^^^^^^^^
-
-In :ref:`advanced_discussions_nsec3_salt`, we discuss the
-reasons why you may want to change your salt periodically for better
-privacy. In this recipe, we look at what command to execute to
-actually change the salt, and how to verify that it has been changed.
-
-The ``dnssec-policy`` currently has no easy way to re-salt using the
-same salt length, so to change your NSEC3 salt you need to change the
-``salt-length`` value and reconfigure your server. You should see
-the following messages in the log, assuming your old salt was
-"1234567890ABCDEF" and ``named`` created "FEDCBA09" (salt length 8)
-as the new salt:
-
-::
-
- named[15848]: zone example.com/IN: zone_addnsec3chain(1,REMOVE,10,1234567890ABCDEF)
- named[15848]: zone example.com/IN: zone_addnsec3chain(1,CREATE|OPTOUT,10,FEDCBA0987654321)
-
-To verify that it worked, you can query the name server (192.168.1.13 in our
-example) for a name that you know does not exist, and check the NSEC3 record
-returned:
-
-::
-
- $ dig @192.168.1.13 thereisnowaythisexists.example.com. A +dnssec +multiline
-
- ...
- TOM10UQBL336NFAQB3P6MOO53LSVG8UI.example.com. 300 IN NSEC3 1 0 10 FEDCBA09 (
- TQ9QBEGA6CROHEOC8KIH1A2C06IVQ5ER
- NS SOA RRSIG DNSKEY NSEC3PARAM )
- ...
-
-If you want to use the same salt length, you can repeat the above steps and
-go back to your original length value.
-
.. _recipes_nsec3_optout:
NSEC3 Opt-Out
that can help conserve resources on parent zones with many
delegations that have not yet been signed.
+.. warning::
+ NSEC3 Opt-Out feature brings benefit only to _extremely_ large zones with lots
+ of insecure delegations. It's use is counterproductive in all other cases as
+ it decreases tamper-resistance of the zone and also decreases efficiency of
+ resolver cache (see :rfc:`8198`).
+
+ In other words, don't enable Opt-Out unless you are serving an equivalent of
+ ``com.`` zone.
+
Because the NSEC3PARAM record does not keep track of whether opt-out is used,
it is hard to check whether changes need to be made to the NSEC3 chain if the flag
is changed. Similar to changing the NSEC3 salt, your best option is to change
NSEC3 records; below is the list with the plain text name before the actual
NSEC3 record:
-- *aaa.example.com*: 9NE0VJGTRTMJOS171EC3EDL6I6GT4P1Q.example.com.
+- *aaa.example.com*: IFA1I3IE7EKCTPHM6R58URO3Q846I52M.example.com
-- *bbb.example.com*: AESO0NT3N44OOSDQS3PSL0HACHUE1O0U.example.com.
+- *bbb.example.com*: ROJUF3VJSJO6LQ2LC1DNSJ5GBAUJPVHE.example.com
-- *ccc.example.com*: SF3J3VR29LDDO3ONT1PM6HAPHV372F37.example.com.
+- *ccc.example.com*: 0VPUT696LUVDPDS5NIHSHBH9KLV20V5K.example.com
-- *ddd.example.com*: TQ9QBEGA6CROHEOC8KIH1A2C06IVQ5ER.example.com.
+- *ddd.example.com*: UHPBD5U4HRGB84MLC2NQOVEFNAKJU0CA.example.com
-- *eee.example.com*: L16L08NEH48IFQIEIPS1HNRMQ523MJ8G.example.com.
+- *eee.example.com*: NF7I61FA4C2UEKPMEDSOC25FE0UJIMKT.example.com
-- *ftp.example.com*: JKMAVHL8V7EMCL8JHIEN8KBOAB0MGUK2.example.com.
+- *ftp.example.com*: 8P15KCUAT1RHCSDN46HBQVPI5T532IN1.example.com
-- *ns1.example.com*: FSK5TK9964BNE7BPHN0QMMD68IUDKT8I.example.com.
+- *ns1.example.com*: GUFVRA2SFIO8RSFP7UO41E8AD1KR41FH.example.com
-- *web.example.com*: D65CIIG0GTRKQ26Q774DVMRCNHQO6F81.example.com.
+- *web.example.com*: CVQ4LA4ALPQIAO2H3N2RB6IR8UHM91E7.example.com
-- *www.example.com*: NTQ0CQEJHM0S17POMCUSLG5IOQQEDTBJ.example.com.
+- *www.example.com*: MIFDNDT3NFF3OD53O7TLA1HRFF95JKUK.example.com
-- *example.com*: TOM10UQBL336NFAQB3P6MOO53LSVG8UI.example.com.
+- *example.com*: ONIB9MGUB9H0RML3CDF5BGRJ59DKJHVK.example.com
We can enable NSEC3 opt-out with the following configuration, changing
the ``optout`` configuration value from ``no`` to ``yes``:
::
dnssec-policy "standard" {
- nsec3param iterations 10 optout yes salt-length 16;
+ nsec3param iterations 0 optout yes salt-length 0;
};
After NSEC3 opt-out is enabled, the number of NSEC3 records is reduced.
Notice that the unsigned delegations ``aaa``, ``ccc``, ``ddd``, and
``eee`` no longer have corresponding NSEC3 records.
-- *bbb.example.com*: AESO0NT3N44OOSDQS3PSL0HACHUE1O0U.example.com.
+- *bbb.example.com*: ROJUF3VJSJO6LQ2LC1DNSJ5GBAUJPVHE.example.com
-- *ftp.example.com*: JKMAVHL8V7EMCL8JHIEN8KBOAB0MGUK2.example.com.
+- *ftp.example.com*: 8P15KCUAT1RHCSDN46HBQVPI5T532IN1.example.com
-- *ns1.example.com*: FSK5TK9964BNE7BPHN0QMMD68IUDKT8I.example.com.
+- *ns1.example.com*: GUFVRA2SFIO8RSFP7UO41E8AD1KR41FH.example.com
-- *web.example.com*: D65CIIG0GTRKQ26Q774DVMRCNHQO6F81.example.com.
+- *web.example.com*: CVQ4LA4ALPQIAO2H3N2RB6IR8UHM91E7.example.com
-- *www.example.com*: NTQ0CQEJHM0S17POMCUSLG5IOQQEDTBJ.example.com.
+- *www.example.com*: MIFDNDT3NFF3OD53O7TLA1HRFF95JKUK.example.com
-- *example.com*: TOM10UQBL336NFAQB3P6MOO53LSVG8UI.example.com.
+- *example.com*: ONIB9MGUB9H0RML3CDF5BGRJ59DKJHVK.example.com
To undo NSEC3 opt-out, change the configuration again:
::
dnssec-policy "standard" {
- nsec3param iterations 10 optout no salt-length 16;
+ nsec3param iterations 0 optout no salt-length 0;
};
.. note::
::
- # nsec3hash 1234567890ABCDEF 1 10 www.example.com.
- NTQ0CQEJHM0S17POMCUSLG5IOQQEDTBJ (salt=1234567890ABCDEF, hash=1, iterations=10)
+ # nsec3hash - 1 0 www.example.com.
+ MIFDNDT3NFF3OD53O7TLA1HRFF95JKUK (salt=-, hash=1, iterations=0)
.. _revert_to_unsigned: