xref: /netbsd-src/external/mpl/bind/dist/doc/dnssec-guide/signing.rst (revision 9689912e6b171cbda866ec33f15ae94a04e2c02d)
1.. Copyright (C) Internet Systems Consortium, Inc. ("ISC")
2..
3.. SPDX-License-Identifier: MPL-2.0
4..
5.. This Source Code Form is subject to the terms of the Mozilla Public
6.. License, v. 2.0.  If a copy of the MPL was not distributed with this
7.. file, you can obtain one at https://mozilla.org/MPL/2.0/.
8..
9.. See the COPYRIGHT file distributed with this work for additional
10.. information regarding copyright ownership.
11
12.. _dnssec_signing:
13
14Signing
15-------
16
17.. _easy_start_guide_for_authoritative_servers:
18
19Easy-Start Guide for Signing Authoritative Zones
20~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21
22This section provides the basic information needed to set up a
23DNSSEC-enabled authoritative name server. A DNSSEC-enabled (or
24"signed") zone contains additional resource records that are used to
25verify the authenticity of its zone information.
26
27To convert a traditional (insecure) DNS zone to a secure one, we need to
28create some additional records (DNSKEY, RRSIG, and NSEC or NSEC3), and
29upload verifiable information (such as a DS record) to the parent zone to
30complete the chain of trust. For more information about DNSSEC resource
31records, please see :ref:`what_does_dnssec_add_to_dns`.
32
33.. note::
34
35   In this chapter, we assume all configuration files, key files, and
36   zone files are stored in ``/etc/bind``, and most examples show
37   commands run as the root user. This may not be ideal, but the point is
38   not to distract from what is important here: learning how to sign
39   a zone. There are many best practices for deploying a more secure
40   BIND installation, with techniques such as jailed process and
41   restricted user privileges, but those are not covered
42   in this document. We trust you, a responsible DNS
43   administrator, to take the necessary precautions to secure your
44   system.
45
46For the examples below, we work with the assumption that
47there is an existing insecure zone ``example.com`` that we are
48converting to a secure zone.
49
50.. _signing_easy_start_policy_enable:
51
52Enabling Automated DNSSEC Zone Maintenance and Key Generation
53^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
54
55To sign a zone, add the following statement to its
56:any:`zone` clause in the BIND 9 configuration file:
57
58::
59
60   options {
61       directory "/etc/bind";
62       recursion no;
63       ...
64   };
65
66   zone "example.com" in {
67       ...
68       dnssec-policy default;
69       ...
70   };
71
72The :any:`dnssec-policy` statement causes the zone to be signed and turns
73on automatic maintenance for the zone. This includes re-signing the zone
74as signatures expire and replacing keys on a periodic basis. The value
75``default`` selects the default policy, which contains values suitable
76for most situations. We cover the creation of a custom policy in
77:ref:`signing_custom_policy`, but for the moment we are accepting the
78default values.
79
80Using :any:`dnssec-policy` requires dynamic DNS or :any:`inline-signing`
81to be enabled.
82
83When the configuration file is updated, tell :iscman:`named` to
84reload the configuration file by running :option:`rndc reconfig`:
85
86::
87
88   # rndc reconfig
89
90And that's it - BIND signs your zone.
91
92At this point, before you go away and merrily add :any:`dnssec-policy`
93statements to all your zones, we should mention that, like a number of
94other BIND configuration options, its scope depends on where it is placed. In
95the example above, we placed it in a :any:`zone` clause, so it applied only
96to the zone in question. If we had placed it in a :any:`view` clause, it
97would have applied to all zones in the view; and if we had placed it in
98the :namedconf:ref:`options` clause, it would have applied to all zones served by
99this instance of BIND.
100
101.. _signing_verification:
102
103Verification
104^^^^^^^^^^^^
105
106The BIND 9 reconfiguration starts the process of signing the zone.
107First, it generates a key for the zone and includes it
108in the published zone. The log file shows messages such as these:
109
110::
111
112   07-Apr-2020 16:02:55.045 zone example.com/IN (signed): reconfiguring zone keys
113   07-Apr-2020 16:02:55.045 reloading configuration succeeded
114   07-Apr-2020 16:02:55.046 keymgr: DNSKEY example.com/ECDSAP256SHA256/10376 (CSK) created for policy default
115   07-Apr-2020 16:02:55.046 Fetching example.com/ECDSAP256SHA256/10376 (CSK) from key repository.
116   07-Apr-2020 16:02:55.046 DNSKEY example.com/ECDSAP256SHA256/10376 (CSK) is now published
117   07-Apr-2020 16:02:55.046 DNSKEY example.com/ECDSAP256SHA256/10376 (CSK) is now active
118   07-Apr-2020 16:02:55.048 zone example.com/IN (signed): next key event: 07-Apr-2020 18:07:55.045
119
120It then starts signing the zone. How long this process takes depends on the
121size of the zone, the speed of the server, and how much activity is
122taking place. We can check what is happening by using :iscman:`rndc`,
123entering the command:
124
125::
126
127   # rndc signing -list example.com
128
129While the signing is in progress, the output is something like:
130
131::
132
133   Signing with key 10376/ECDSAP256SHA256
134
135and when it is finished:
136
137::
138
139   Done signing with key 10376/ECDSAP256SHA256
140
141When the second message appears, the zone is signed.
142
143Before moving on to the next step of coordinating with the parent zone,
144let's make sure everything looks good using :iscman:`delv`. We want to
145simulate what a validating resolver will check, by telling
146:iscman:`delv` to use a specific trust anchor.
147
148First, we need to make a copy of the key created by BIND. This
149is in the directory you set with the :any:`directory` statement in
150your configuration file's :namedconf:ref:`options` clause, and is named something
151like ``Kexample.com.+013.10376.key``:
152
153::
154
155   # cp /etc/bind/Kexample.com.+013+10376.key /tmp/example.key
156
157The original key file looks like this (with the actual key shortened for ease of display,
158and comments omitted):
159
160::
161
162   # cat /etc/bind/Kexample.com.+013+10376.key
163
164   ...
165   example.com. 3600 IN DNSKEY 257 3 13 6saiq99qDB...dqp+o0dw==
166
167We want to edit the copy to be in the :any:`trust-anchors` format, so that
168it looks like this:
169
170::
171
172   # cat /tmp/example.key
173   trust-anchors {
174       example.com. static-key 257 3 13 "6saiq99qDB...dqp+o0dw==";
175   };
176
177Now we can run the :iscman:`delv` command and instruct it to use this
178trusted-key file to validate the answer it receives from the
179authoritative name server 192.168.1.13:
180
181::
182
183   $ delv @192.168.1.13 -a /tmp/example.key +root=example.com example.com. SOA +multiline
184   ; fully validated
185   example.com.        600 IN SOA ns1.example.com. admin.example.com. (
186                   2020040703 ; serial
187                   1800       ; refresh (30 minutes)
188                   900        ; retry (15 minutes)
189                   2419200    ; expire (4 weeks)
190                   300        ; minimum (5 minutes)
191                   )
192   example.com.        600 IN RRSIG SOA 13 2 600 (
193                   20200421150255 20200407140255 10376 example.com.
194                   jBsz92zwAcGMNV/yu167aKQZvFyC7BiQe1WEnlogdLTF
195                   oq4yBQumOhO5WX61LjA17l1DuLWcd/ASwlUZWFGCYQ== )
196
197.. _signing_easy_start_upload_to_parent_zone:
198
199Uploading Information to the Parent Zone
200^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
201
202Once everything is complete on our name server, we need to generate some
203information to be uploaded to the parent zone to complete the chain of
204trust. The format and the upload methods are actually dictated by your
205parent zone's administrator, so contact your registrar or parent zone
206administrator to find out what the actual format should be and how to
207deliver or upload the information to the parent zone.
208
209What about your zone between the time you signed it and the time your
210parent zone accepts the upload? To the rest of the world, your
211zone still appears to be insecure, because if a validating
212resolver attempts to validate your domain name via
213your parent zone, your parent zone will indicate that you are
214not yet signed (as far as it knows). The validating resolver will then
215give up attempting to validate your domain name, and will fall back to the
216insecure DNS. Until you complete this final step with your
217parent zone, your zone remains insecure.
218
219.. note::
220
221   Before uploading to your parent zone, verify that your newly signed
222   zone has propagated to all of your name servers (usually via zone
223   transfers). If some of your name servers still have unsigned zone
224   data while the parent tells the world it should be signed, validating
225   resolvers around the world cannot resolve your domain name.
226
227Here are some examples of what you may upload to your parent zone, with
228the DNSKEY/DS data shortened for display. Note that no matter what
229format may be required, the end result is the parent zone
230publishing DS record(s) based on the information you upload. Again,
231contact your parent zone administrator(s) to find out the
232correct format for their system.
233
2341. DS record format:
235
236   ::
237
238      example.com. 3600 IN DS 10376 13 2 B92E22CAE0...33B8312EF0
239
2402. DNSKEY format:
241
242   ::
243
244      example.com. 3600 IN DNSKEY 257 3 13 6saiq99qDB...dqp+o0dw==
245
246The DS record format may be generated from the DNSKEY using the
247:iscman:`dnssec-dsfromkey` tool, which is covered in
248:ref:`parent_ds_record_format`. For more details and examples on how
249to work with your parent zone, please see
250:ref:`working_with_parent_zone`.
251
252.. _signing_easy_start_so_what_now:
253
254So... What Now?
255^^^^^^^^^^^^^^^
256
257Congratulations! Your zone is signed, your secondary servers have
258received the new zone data, and the parent zone has accepted your upload
259and published your DS record. Your zone is now officially
260DNSSEC-enabled. What happens next? That is basically it - BIND
261takes care of everything else. As for updating your zone file, you can
262continue to update it the same way as prior to signing your
263zone; the normal work flow of editing a zone file and using the :iscman:`rndc`
264command to reload the zone still works as usual, and although you are
265editing the unsigned version of the zone, BIND generates the signed
266version automatically.
267
268Curious as to what all these commands did to your zone file? Read on to
269:ref:`your_zone_before_and_after_dnssec` and find out. If you are
270interested in how to roll this out to your existing primary and
271secondary name servers, check out :ref:`recipes_inline_signing` in
272the :ref:`dnssec_recipes` chapter.
273
274.. _your_zone_before_and_after_dnssec:
275
276Your Zone, Before and After DNSSEC
277~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
278
279When we assigned the default DNSSEC policy to the zone, we provided the
280minimal amount of information to convert a traditional DNS
281zone into a DNSSEC-enabled zone. This is what the zone looked like
282before we started:
283
284::
285
286   $ dig @192.168.1.13 example.com. AXFR +multiline +onesoa
287
288   ; <<>> DiG 9.16.0 <<>> @192.168.1.13 example.com AXFR +multiline +onesoa
289   ; (1 server found)
290   ;; global options: +cmd
291   example.com.        600 IN SOA ns1.example.com. admin.example.com. (
292                   2020040700 ; serial
293                   1800       ; refresh (30 minutes)
294                   900        ; retry (15 minutes)
295                   2419200    ; expire (4 weeks)
296                   300        ; minimum (5 minutes)
297                   )
298   example.com.        600 IN NS ns1.example.com.
299   ftp.example.com.    600 IN A 192.168.1.200
300   ns1.example.com.    600 IN A 192.168.1.1
301   web.example.com.    600 IN CNAME www.example.com.
302   www.example.com.    600 IN A 192.168.1.100
303
304Below shows the test zone ``example.com`` after reloading the
305server configuration. Clearly, the zone grew in size, and the
306number of records multiplied:
307
308::
309
310   # dig @192.168.1.13 example.com. AXFR +multiline +onesoa
311
312   ; <<>> DiG 9.16.0 <<>> @192.168.1.13 example.com AXFR +multiline +onesoa
313   ; (1 server found)
314   ;; global options: +cmd
315   example.com.        600 IN SOA ns1.example.com. admin.example.com. (
316                   2020040703 ; serial
317                   1800       ; refresh (30 minutes)
318                   900        ; retry (15 minutes)
319                   2419200    ; expire (4 weeks)
320                   300        ; minimum (5 minutes)
321                   )
322   example.com.        300 IN RRSIG NSEC 13 2 300 (
323                   20200413050536 20200407140255 10376 example.com.
324                   drtV1rJbo5OMi65OJtu7Jmg/thgpdTWrzr6O3Pzt12+B
325                   oCxMAv3orWWYjfP2n9w5wj0rx2Mt2ev7MOOG8IOUCA== )
326   example.com.        300 IN NSEC ftp.example.com. NS SOA RRSIG NSEC DNSKEY TYPE65534
327   example.com.        600 IN RRSIG NS 13 2 600 (
328                   20200413130638 20200407140255 10376 example.com.
329                   2ipmzm1Ei6vfE9OLowPMsxLBCbjrCpWPgWJ0ekwZBbux
330                   MLffZOXn8clt0Ql2U9iCPdyoQryuJCiojHSE2d6nrw== )
331   example.com.        600 IN RRSIG SOA 13 2 600 (
332                   20200421150255 20200407140255 10376 example.com.
333                   jBsz92zwAcGMNV/yu167aKQZvFyC7BiQe1WEnlogdLTF
334                   oq4yBQumOhO5WX61LjA17l1DuLWcd/ASwlUZWFGCYQ== )
335   example.com.        0 IN RRSIG TYPE65534 13 2 0 (
336                   20200413050536 20200407140255 10376 example.com.
337                   Xjkom24N6qeCJjg9BMUfuWf+euLeZB169DHvLYZPZNlm
338                   GgM2czUDPio6VpQbUw6JE5DSNjuGjgpgXC5SipC42g== )
339   example.com.        3600 IN RRSIG DNSKEY 13 2 3600 (
340                   20200421150255 20200407140255 10376 example.com.
341                   maK75+28oUyDtci3V7wjTsuhgkLUZW+Q++q46Lea6bKn
342                   Xj77kXcLNogNdUOr5am/6O6cnPeJKJWsnmTLISm62g== )
343   example.com.        0 IN TYPE65534 \# 5 ( 0D28880001 )
344   example.com.        3600 IN DNSKEY 257 3 13 (
345                   6saiq99qDBb5b4G4cx13cPjFTrIvUs3NW44SvbbHorHb
346                   kXwOzeGAWyPORN+pwEV/LP9+FHAF/JzAJYdqp+o0dw==
347                   ) ; KSK; alg = ECDSAP256SHA256 ; key id = 10376
348   example.com.        600 IN NS ns1.example.com.
349   ftp.example.com.    600 IN RRSIG A 13 3 600 (
350                   20200413130638 20200407140255 10376 example.com.
351                   UYo1njeUA49VhKnPSS3JO4G+/Xd2PD4m3Vaacnd191yz
352                   BIoouEBAGPcrEM2BNrgR0op1EWSus9tG86SM1ZHGuQ== )
353   ftp.example.com.    300 IN RRSIG NSEC 13 3 300 (
354                   20200413130638 20200407140255 10376 example.com.
355                   rPADrAMAPIPSF3S45OSY8kXBTYMS3nrZg4Awj7qRL+/b
356                   sOKy6044MbIbjg+YWL69dBjKoTSeEGSCSt73uIxrYA== )
357   ftp.example.com.    300 IN NSEC ns1.example.com. A RRSIG NSEC
358   ftp.example.com.    600 IN A 192.168.1.200
359   ns1.example.com.    600 IN RRSIG A 13 3 600 (
360                   20200413130638 20200407140255 10376 example.com.
361                   Yeojg7qrJmxL6uLTnALwKU5byNldZ9Ggj5XjcbpPvujQ
362                   ocG/ovGBg6pdugXC9UxE39bCDl8dua1frjDcRCCZAA== )
363   ns1.example.com.    300 IN RRSIG NSEC 13 3 300 (
364                   20200413130638 20200407140255 10376 example.com.
365                   vukgQme6k7JwCf/mJOOzHXbE3fKtSro+Kc10T6dHMdsc
366                   oM1/oXioZvgBZ9cKrQhIAUt7r1KUnrUwM6Je36wWFA== )
367   ns1.example.com.    300 IN NSEC web.example.com. A RRSIG NSEC
368   ns1.example.com.    600 IN A 192.168.1.1
369   web.example.com.    600 IN RRSIG CNAME 13 3 600 (
370                   20200413130638 20200407140255 10376 example.com.
371                   JXi4WYypofD5geUowVqlqJyHzvcRnsvU/ONhTBaUCw5Y
372                   XtifKAXRHWrUL1HIwt37JYPLf5uYu90RfkWLj0GqTQ== )
373   web.example.com.    300 IN RRSIG NSEC 13 3 300 (
374                   20200413130638 20200407140255 10376 example.com.
375                   XF4Hsd58dalL+s6Qu99bG80PQyMf7ZrHEzDiEflRuykP
376                   DfBRuf34z27vj70LO1lp2ZiX4BB1ahcEK2ae9ASAmA== )
377   web.example.com.    300 IN NSEC www.example.com. CNAME RRSIG NSEC
378   web.example.com.    600 IN CNAME www.example.com.
379   www.example.com.    600 IN RRSIG A 13 3 600 (
380                   20200413050536 20200407140255 10376 example.com.
381                   mACKXrDOF5JMWqncSiQ3pYWA6abyGDJ4wgGCumjLXhPy
382                   0cMzJmKv2s7G6+tW3TsA6BK3UoMfv30oblY2Mnl4/A== )
383   www.example.com.    300 IN RRSIG NSEC 13 3 300 (
384                   20200413050536 20200407140255 10376 example.com.
385                   1YQ22odVt0TeP5gbNJwkvS684ipDmx6sEOsF0eCizhCv
386                   x8osuOATdlPjIEztt+rveaErZ2nsoLor5k1nQAHsbQ== )
387   www.example.com.    300 IN NSEC example.com. A RRSIG NSEC
388   www.example.com.    600 IN A 192.168.1.100
389
390But this is a really messy way to tell if the zone is set up properly
391with DNSSEC. Fortunately, there are tools to help us with that. Read on
392to :ref:`how_to_test_authoritative_server` to learn more.
393
394.. _how_to_test_authoritative_server:
395
396How To Test Authoritative Zones
397~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
398
399So we've activated DNSSEC and uploaded some data to our parent zone. How
400do we know our zone is signed correctly? Here are a few ways to check.
401
402.. _signing_verify_key_data:
403
404Look for Key Data in Your Zone
405^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
406
407One way to see if your zone is signed is to check for the
408presence of DNSKEY record types. In our example, we created a single
409key, and we expect to see it returned when we query for it.
410
411::
412
413   $ dig @192.168.1.13 example.com. DNSKEY +multiline
414
415   ; <<>> DiG 9.16.0 <<>> @10.53.0.6 example.com DNSKEY +multiline
416   ; (1 server found)
417   ;; global options: +cmd
418   ;; Got answer:
419   ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18637
420   ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
421   ;; WARNING: recursion requested but not available
422
423   ;; OPT PSEUDOSECTION:
424   ; EDNS: version: 0, flags:; udp: 4096
425   ; COOKIE: efe186423313fb66010000005e8c997e99864f7d69ed7c11 (good)
426   ;; QUESTION SECTION:
427   ;example.com.       IN DNSKEY
428
429   ;; ANSWER SECTION:
430   example.com.        3600 IN DNSKEY 257 3 13 (
431                   6saiq99qDBb5b4G4cx13cPjFTrIvUs3NW44SvbbHorHb
432                   kXwOzeGAWyPORN+pwEV/LP9+FHAF/JzAJYdqp+o0dw==
433                   ) ; KSK; alg = ECDSAP256SHA256 ; key id = 10376
434
435
436.. _signing_verify_signature:
437
438Look for Signatures in Your Zone
439^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
440
441Another way to see if your zone data is signed is to check for the
442presence of a signature. With DNSSEC, every record
443[#every_record_signed]_ now comes with at least one corresponding
444signature, known as an RRSIG.
445
446::
447
448   $ dig @192.168.1.13 example.com. SOA +dnssec +multiline
449
450   ; <<>> DiG 9.16.0 <<>> @10.53.0.6 example.com SOA +dnssec +multiline
451   ; (1 server found)
452   ;; global options: +cmd
453   ;; Got answer:
454   ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45219
455   ;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
456   ;; WARNING: recursion requested but not available
457
458   ;; OPT PSEUDOSECTION:
459   ; EDNS: version: 0, flags: do; udp: 4096
460   ; COOKIE: 75adff4f4ce916b2010000005e8c99c0de47eabb7951b2f5 (good)
461   ;; QUESTION SECTION:
462   ;example.com.       IN SOA
463
464   ;; ANSWER SECTION:
465   example.com.        600 IN SOA ns1.example.com. admin.example.com. (
466                   2020040703 ; serial
467                   1800       ; refresh (30 minutes)
468                   900        ; retry (15 minutes)
469                   2419200    ; expire (4 weeks)
470                   300        ; minimum (5 minutes)
471                   )
472   example.com.        600 IN RRSIG SOA 13 2 600 (
473                   20200421150255 20200407140255 10376 example.com.
474                   jBsz92zwAcGMNV/yu167aKQZvFyC7BiQe1WEnlogdLTF
475                   oq4yBQumOhO5WX61LjA17l1DuLWcd/ASwlUZWFGCYQ== )
476
477The serial number was automatically incremented from the old, unsigned
478version. :iscman:`named` keeps track of the serial number of the signed version of
479the zone independently of the unsigned version. If the unsigned zone is
480updated with a new serial number that is higher than the one in the
481signed copy, then the signed copy is increased to match it;
482otherwise, the two are kept separate.
483
484.. _signing_verify_zone_file:
485
486Examine the Zone File
487^^^^^^^^^^^^^^^^^^^^^
488
489Our original zone file ``example.com.db`` remains untouched, and :iscman:`named` has
490generated three additional files automatically for us (shown below). The
491signed DNS data is stored in ``example.com.db.signed`` and in the
492associated journal file.
493
494::
495
496   # cd /etc/bind
497   # ls
498   example.com.db  example.com.db.jbk  example.com.db.signed  example.com.db.signed.jnl
499
500A quick description of each of the files:
501
502-  ``.jbk``: a transient file used by :iscman:`named`
503
504-  ``.signed``: the signed version of the zone in raw format
505
506-  ``.signed.jnl``: a journal file for the signed version of the zone
507
508These files are stored in raw (binary) format for faster loading. To
509reveal the human-readable version, use :iscman:`named-compilezone`
510as shown below. In the example below, we run the command on the
511raw format zone ``example.com.db.signed`` to produce a text version of
512the zone ``example.com.text``:
513
514::
515
516   # named-compilezone -f raw -F text -o example.com.text example.com example.com.db.signed
517   zone example.com/IN: loaded serial 2014112008 (DNSSEC signed)
518   dump zone to example.com.text...done
519   OK
520
521.. _signing_verify_check_parent:
522
523Check the Parent
524^^^^^^^^^^^^^^^^
525
526Although this is not strictly related to whether the zone is
527signed, a critical part of DNSSEC is the trust relationship between the
528parent and the child. Just because we, the child, have all the correctly
529signed records in our zone does not mean it can be fully validated by a
530validating resolver, unless our parent's data agrees with ours. To check
531if our upload to the parent was successful, ask the parent name server
532for the DS record of our child zone; we should get back the DS record(s)
533containing the information we uploaded in
534:ref:`signing_easy_start_upload_to_parent_zone`:
535
536::
537
538   $ dig example.com. DS
539
540   ; <<>> DiG 9.16.0 <<>> example.com DS
541   ; (1 server found)
542   ;; global options: +cmd
543   ;; Got answer:
544   ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16954
545   ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
546
547   ;; OPT PSEUDOSECTION:
548   ; EDNS: version: 0, flags:; udp: 4096
549   ; COOKIE: db280d5b52576780010000005e8c9bf5b0d8de103d934e5d (good)
550   ;; QUESTION SECTION:
551   ;example.com.           IN  DS
552
553   ;; ANSWER SECTION:
554   example.com.  61179 IN  DS  10376 13 2 B92E22CAE0B41430EC38D3F7EDF1183C3A94F4D4748569250C15EE33B8312EF0
555
556.. [#every_record_signed]
557   Well, almost every record: NS records and glue records for
558   delegations do not have RRSIG records. If there are
559   no delegations, then every record in your zone is
560   signed and comes with its own RRSIG.
561
562.. _signing_verify_external_tools:
563
564External Testing Tools
565^^^^^^^^^^^^^^^^^^^^^^
566
567We recommend two tools, below: Verisign DNSSEC Debugger and DNSViz. Others can
568be found via a simple online search. These excellent online tools are an easy
569way to verify that your domain name is fully secured.
570
571.. _signing_verify_external_tools_dnssec_debugger:
572
573Verisign DNSSEC Debugger
574++++++++++++++++++++++++
575
576URL: `<https://dnssec-debugger.verisignlabs.com/>`__
577
578This tool shows a nice summary of checks performed on your domain name.
579You can expand it to view more details for each of the items checked, to
580get a detailed report.
581
582.. figure:: ../dnssec-guide/img/verisign-dnssec-debugger-example.png
583   :alt: Verisign DNSSEC Debugger
584
585   Verisign DNSSEC Debugger
586
587.. _signing_verify_external_tools_dnsviz:
588
589DNSViz
590++++++
591
592URL: `<https://dnsviz.net/>`__
593
594DNSViz provides a visual analysis of the DNSSEC authentication chain for
595a domain name and its resolution path in the DNS namespace.
596
597.. figure:: ../dnssec-guide/img/dnsviz-example-small.png
598   :alt: DNSViz
599   :width: 80.0%
600
601   DNSViz
602
603.. _signing_easy_start_explained:
604
605Signing Easy Start Explained
606~~~~~~~~~~~~~~~~~~~~~~~~~~~~
607
608.. _enable_automatic_maintenance_explained:
609
610Enable Automatic DNSSEC Maintenance Explained
611^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
612
613Signing a zone requires a number of separate steps:
614
615-  Generation of the keys to sign the zone.
616
617-  Inclusion of the keys into the zone.
618
619-  Signing of the records in the file (including the generation of the
620   NSEC or NSEC3 records).
621
622Maintaining a signed zone comprises a set of ongoing tasks:
623
624-  Re-signing the zone as signatures approach expiration.
625
626-  Generation of new keys as the time approaches for a key roll.
627
628-  Inclusion of new keys into the zone when the rollover starts.
629
630-  Transition from signing the zone with the old set of keys to signing
631   the zone with the new set of keys.
632
633-  Waiting the appropriate interval before removing the old keys from
634   the zone.
635
636-  Deleting the old keys.
637
638That is quite complex, and it is all handled in BIND 9 with the single
639``dnssec-policy default`` statement. We will see later on (in the
640:ref:`signing_custom_policy` section) how these actions can be tuned, by
641setting up our own DNSSEC policy with customized parameters. However, in many
642cases the defaults are adequate.
643
644:any:`dnssec-policy` is the preferred way to run DNSSEC in a zone, but sometimes
645a more "hands-on" approach to signing and key maintenance is needed. For this
646reason, we cover manual signing techniques in
647:ref:`advanced_discussions_manual_signing`.
648
649.. _working_with_parent_zone:
650
651Working With the Parent Zone
652~~~~~~~~~~~~~~~~~~~~~~~~~~~~
653
654As mentioned in :ref:`signing_easy_start_upload_to_parent_zone`,
655the format of the information uploaded to your parent zone is dictated
656by your parent zone administrator. The two main formats are:
657
6581. DS record format
659
6602. DNSKEY format
661
662Check with your parent zone to see which format they require.
663
664But how can you get each of the formats from your existing data?
665
666When :iscman:`named` turned on automatic
667DNSSEC maintenance, essentially the first thing it did was to create
668the DNSSEC keys and put them in the directory you specified in the
669configuration file. If you look in that directory, you will see three
670files with names like ``Kexample.com.+013+10376.key``,
671``Kexample.com.+013+10376.private``, and
672``Kexample.com.+013+10376.state``. The one we are interested in is the
673one with the ``.key`` suffix, which contains the zone's public key. (The
674other files contain the zone's private key and the DNSSEC state
675associated with the key.) This public key is used to generate the information we
676need to pass to the parent.
677
678.. _parent_ds_record_format:
679
680DS Record Format
681^^^^^^^^^^^^^^^^
682
683Below is an example of a DS record format generated from the KSK we
684created earlier (``Kexample.com.+013+10376.key``):
685
686::
687
688   # cd /etc/bind
689    dnssec-dsfromkey Kexample.com.+013+10376.key
690   example.com. IN DS 10376 13 2 B92E22CAE0B41430EC38D3F7EDF1183C3A94F4D4748569250C15EE33B8312EF0
691
692Some registrars ask their customers to manually specify the types of algorithm
693and digest used. In this example, 13 represents the algorithm used, and
6942 represents the digest type (SHA-256). The key tag or key ID is 10376.
695
696.. _parent_dnskey_format:
697
698DNSKEY Format
699^^^^^^^^^^^^^
700
701Below is an example of the same key ID (10376) using DNSKEY format
702(with the actual key shortened for ease of display):
703
704::
705
706   example.com. 3600 IN DNSKEY 257 3 13 (6saiq99qDB...dqp+o0dw==) ; key id = 10376
707
708The key itself is easy to find (it's difficult to miss that long
709base64 string) in the file.
710
711::
712
713   # cd /etc/bind
714   # cat Kexample.com.+013+10376.key
715   ; This is a key-signing key, keyid 10376, for example.com.
716   ; Created: 20200407150255 (Tue Apr  7 16:02:55 2020)
717   ; Publish: 20200407150255 (Tue Apr  7 16:02:55 2020)
718   ; Activate: 20200407150255 (Tue Apr  7 16:02:55 2020)
719   example.com. 3600 IN DNSKEY 257 3 13 6saiq99qDB...dqp+o0dw==
720
721.. _signing_custom_policy:
722
723Creating a Custom DNSSEC Policy
724~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
725
726The remainder of this section describes the contents of a custom DNSSEC
727policy. :ref:`dnssec_advanced_discussions` describes the concepts
728involved here and the pros and cons of choosing particular values. If
729you are not already familiar with DNSSEC, it may be worth reading that chapter
730first.
731
732Setting up your own DNSSEC policy means that you must include a
733:any:`dnssec-policy` clause in the zone file. This sets values for the
734various parameters that affect the signing of zones and the rolling of
735keys. The following is an example of such a clause:
736
737::
738
739   dnssec-policy standard {
740       dnskey-ttl 600;
741       keys {
742           ksk lifetime 365d algorithm ecdsap256sha256;
743           zsk lifetime 60d algorithm ecdsap256sha256;
744       };
745       max-zone-ttl 600;
746       parent-ds-ttl 600;
747       parent-propagation-delay 2h;
748       publish-safety 7d;
749       retire-safety 7d;
750       signatures-refresh 5d;
751       signatures-validity 15d;
752       signatures-validity-dnskey 15d;
753       zone-propagation-delay 2h;
754   };
755
756The policy has multiple parts:
757
758-  The name must be specified. As each zone can use a different policy,
759   :iscman:`named` needs to be able to distinguish between policies. This is
760   done by giving each policy a name, such as ``standard`` in the above
761   example.
762
763-  The :any:`keys` clause lists all keys that should be in the zone, along
764   with their associated parameters. In this example, we are using the
765   conventional KSK/ZSK split, with the KSK changed every year and the
766   ZSK changed every two months (the ``default`` DNSSEC policy sets a
767   CSK that is never changed). Keys are created using the
768   ECDSAPS256SHA256 algorithm; each KSK/ZSK pair must have the same
769   algorithm. A CSK combines the functionality of a ZSK and a KSK.
770
771-  The parameters ending in ``-ttl`` are, as expected, the TTLs of the
772   associated records. Remember that during a key rollover,
773   we have to wait for records to expire from caches? The values
774   here tell BIND 9 the maximum amount of time it has to wait for this to
775   happen. Values can be set for the DNSKEY records in your zone, the
776   non-DNSKEY records in your zone, and the DS records in the parent
777   zone.
778
779-  Another set of time-related parameters are those ending in
780   ``-propagation-delay``. These tell BIND how long it takes for a
781   change in zone contents to become available on all secondary servers.
782   (This may be non-negligible: for example, if a large zone is
783   transferred over a slow link.)
784
785-  The policy also sets values for the various signature parameters: how
786   long the signatures on the DNSKEY and non-DNSKEY records are valid,
787   and how often BIND should re-sign the zone.
788
789-  The parameters ending in ``-safety`` are there to give
790   you a bit of leeway in case a key roll doesn't go to plan. When
791   introduced into the zone, the :any:`publish-safety` time is the amount
792   of additional time, over and above that calculated from the other
793   parameters, during which the new key is in the zone but before BIND starts
794   to sign records with it. Similarly, the :any:`retire-safety` is the
795   amount of additional time, over and above that calculated from the
796   other parameters, during which the old key is retained in the zone before
797   being removed.
798
799-  Finally, the :any:`purge-keys` option allows you to clean up key files
800   automatically after a period of time. If a key has been removed from the
801   zone, this option will determine how long its key files will be retained
802   on disk.
803
804(You do not have to specify all the items listed above in your policy
805definition. Any that are not set simply take the default value.)
806
807Usually, the exact timing of a key roll, or how long a signature remains
808valid, is not critical. For this reason, err on the side of caution when
809setting values for the parameters. It is better to have an operation
810like a key roll take a few days longer than absolutely required, than it
811is to have a quick key roll but have users get validation failures
812during the process.
813
814Having defined a new policy called "standard", we now need to tell
815:iscman:`named` to use it. We do this by adding a ``dnssec-policy standard;``
816statement to the configuration file. Like many other configuration
817statements, it can be placed in the :namedconf:ref:`options` statement (thus applying
818to all zones on the server), a :any:`view` statement (applying to all zones
819in the view), or a :any:`zone` statement (applying only to that zone). In
820this example, we'll add it to the :any:`zone` statement:
821
822::
823
824   zone "example.net" in {
825       ...
826       dnssec-policy standard;
827       ...
828   };
829
830Finally, tell :iscman:`named` to use the new policy:
831
832::
833
834   # rndc reconfig
835
836... and that's it. :iscman:`named` now applies the "standard" policy to
837your zone.
838
839.. _signing_maintenance_tasks:
840
841Maintenance Tasks
842~~~~~~~~~~~~~~~~~
843
844Zone data is signed and the parent zone has published your DS records:
845at this point your zone is officially secure. When other
846validating resolvers look up information in your zone, they are able to
847follow the 12-step process as described in
848:ref:`how_does_dnssec_change_dns_lookup_revisited` and verify the
849authenticity and integrity of the answers.
850
851There is not that much left for you, as the DNS administrator, to do on
852an ongoing basis. Whenever you update your zone, BIND automatically
853re-signs your zone with new RRSIG and NSEC/NSEC3 records, and even
854increments the serial number for you. If you choose to split your keys
855into a KSK and ZSK, the rolling of the ZSK is completely automatic.
856Rolling of a KSK or CSK may require some manual intervention, though,
857so let's examine two more DNSSEC-related resource records, CDS and CDNSKEY.
858
859.. _cds_cdnskey:
860
861The CDS and CDNSKEY Resource Records
862^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
863
864Passing the DS record to the organization running the parent zone has
865always been recognized as a bottleneck in the key rollover process. To
866automate the process, the CDS and CDNSKEY resource records were
867introduced.
868
869The CDS and CDNSKEY records are identical to the DS and DNSKEY records,
870except in the type code and the name. When such a record appears in the
871child zone, it is a signal to the parent that it should update the DS it
872has for that zone. In essence, when the parent notices
873the presence of the CDS and/or CDNSKEY record(s) in the
874child zone, it checks these records to verify that they are
875signed by a valid key for the zone. If the record(s) successfully
876validate, the parent zone's DS RRset for the child zone is changed to
877correspond to the CDS (or CDNSKEY) records. (For more
878information on how the signaling works and the issues surrounding it,
879please refer to :rfc:`7344` and :rfc:`8078`.)
880
881.. _working_with_the_parent_2:
882
883Working with the Parent Zone (2)
884^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
885
886Once the zone is signed, the only required manual tasks are
887to monitor KSK or CSK key rolls and pass the new DS record to the
888parent zone. However, if the parent can process CDS or CDNSKEY records,
889you may not even have to do that. [#parent_zone_security_considerations]_
890
891When the time approaches for the roll of a KSK or CSK, BIND adds a
892CDS and a CDNSKEY record for the key in question to the apex of the
893zone. If your parent zone supports polling for CDS/CDNSKEY records, they
894are uploaded and the DS record published in the parent - at least ideally.
895
896If BIND is configured with :any:`parental-agents`, it will check for the DS
897presence. Let's look at the following configuration excerpt:
898
899::
900
901   parental-agents "net" {
902       10.53.0.11; 10.53.0.12;
903   };
904
905   zone "example.net" in {
906       ...
907       dnssec-policy standard;
908       parental-agents { "net"; };
909       checkds explicit;
910       ...
911   };
912
913BIND will check for the presence of the DS record in the parent zone by querying
914its parental agents (defined in :rfc:`7344` to be the entities that the child
915zone has a relationship with to change its delegation information). In the
916example above, The zone `example.net` is configured with two parental agents,
917at the addresses 10.53.0.11 and 10.53.0.12. These addresses are used as an
918example only. Both addresses will have to respond with a DS RRset that
919includes the DS record identifying the key that is being rolled. If one or
920both don't have the DS included yet the rollover is paused, and the check for
921DS presence is retried after an hour. The same applies for DS withdrawal.
922
923The example also has :any:`checkds` set to `explicit`. This means that only
924the addresses defined in :any:`parental-agents` are being queried. If set to
925`yes`, the parental agents are being looked up by querying for the parent NS
926records.
927
928Alternatively, you can use the :iscman:`rndc` tool to tell :iscman:`named` that the DS
929record has been published or withdrawn. For example:
930
931::
932
933   # rndc dnssec -checkds published example.net
934
935This command should also be used when :any:`checkds` is set to `no`.
936
937If your parent zone doesn't support CDS/CDNSKEY, you will have to supply
938the DNSKEY or DS record to the parent zone manually when a new KSK appears in
939your zone, presumably using the same mechanism you used to upload the
940records for the first time. Again, you need to use the :iscman:`rndc` tool
941to tell :iscman:`named` that the DS record has been published.
942
943.. [#parent_zone_security_considerations]
944   For security reasons, a parent zone that supports CDS/CDNSKEY may require
945   the DS record to be manually uploaded when we first sign the zone.
946   Until our zone is signed, the parent cannot be sure that a CDS or CDNSKEY
947   record it finds by querying our zone really comes from our zone; thus, it
948   needs to use some other form of secure transfer to obtain the information.
949
950.. _advanced_discussions_manual_signing:
951
952Manual Signing
953~~~~~~~~~~~~~~
954
955Manual signing of a zone was the first method of signing introduced into
956BIND and offers, as the name suggests, no automation. The user must
957handle everything: create the keys, sign the zone file with them, load
958the signed zone, periodically re-sign the zone, and manage key rolls,
959including interaction with the parent. A user certainly can do all this,
960but why not use one of the automated methods?
961
962Although use of the automatic :any:`dnssec-policy` is the preferred way to
963sign zones in BIND, there are occasions where a manual approach may be needed.
964:any:`dnssec-policy` does not currently support the use of external hardware,
965so if your security policy requires it, you need to use manual signing.
966
967BIND 9 ships with several tools that are used in this process, which are
968explained in more detail below. In all cases, the ``-h`` option prints a full
969list of parameters. Note that the DNSSEC tools require the keyset files to be
970in the working directory or the directory specified by the ``-d`` option.
971
972To convert a traditional (insecure) DNS zone to a secure one, we need to
973create various additional records (DNSKEY, RRSIG, NSEC/NSEC3) and, as with
974fully automatic signing, to upload verifiable information (such as a DS
975record) to the parent zone to complete the chain of trust.
976
977The first step is to create the keys as described in
978:ref:`manual_signing_generate_keys`, then using the BIND-provided tools
979:iscman:`dnssec-keygen` to create the keys and
980:iscman:`dnssec-signzone` to sign the zone. The signed zone is stored in
981another file and is the one you tell BIND to load. To update the zone (for
982example, to add a resource record), you update the unsigned zone, re-sign it,
983and tell :iscman:`named` to load the updated signed copy. The same goes for
984refreshing signatures or rolling keys; the user is responsible for providing
985the signed zone served by :iscman:`named`. (In the case of rolling keys, you
986are also responsible for ensuring that the keys are added and removed at the
987correct times.)
988
989Why would you want to sign your zone this way? You probably wouldn't in the
990normal course of events, but as there may be circumstances in which it is
991required, the scripts have been left in the BIND distribution.
992
993.. note::
994
995   Again, we assume all configuration files, key files, and zone files are
996   stored in ``/etc/bind``, and most examples show commands run as the root
997   user. This may not be ideal, but the point is not to distract from what is
998   important here: learning how to sign a zone. There are many best practices
999   for deploying a more secure BIND installation, with techniques such as
1000   jailed process and restricted user privileges, but those are not covered
1001   in this document. We trust you, a responsible DNS administrator, to take
1002   the necessary precautions to secure your system.
1003
1004   For our examples below, we work with the assumption that there is an
1005   existing insecure zone ``example.com`` that we are converting to a secure
1006   version. The secure version uses both a KSK and a ZSK.
1007
1008.. _manual_signing_generate_keys:
1009
1010Generate Keys
1011^^^^^^^^^^^^^
1012
1013Everything in DNSSEC centers around keys, so we begin by generating our own
1014keys.
1015
1016.. code-block:: console
1017
1018   # cd /etc/bind/keys
1019   # dnssec-keygen -a ECDSAP256SHA256 example.com
1020   Generating key pair...........................+++++ ......................+++++
1021   Kexample.com.+013+34371
1022   # dnssec-keygen -a ECDSAP256SHA256 -f KSK example.com
1023   Generating key pair........................+++ ..................................+++
1024   Kexample.com.+013+00472
1025
1026This command generates four key files in ``/etc/bind/keys``:
1027
1028-  Kexample.com.+013+34371.key
1029
1030-  Kexample.com.+013+34371.private
1031
1032-  Kexample.com.+013+00472.key
1033
1034-  Kexample.com.+013+00472.private
1035
1036The two files ending in ``.key`` are the public keys. These contain the
1037DNSKEY resource records that appear in the zone. The two files
1038ending in ``.private`` are the private keys, and contain the information
1039that :iscman:`named` actually uses to sign the zone.
1040
1041Of the two pairs, one is the zone-signing key (ZSK), and one is the
1042key-signing key (KSK). [#signal_zone_presence]_ We can tell which is
1043which by looking at the file contents (the actual keys are shortened
1044here for ease of display):
1045
1046.. code-block:: console
1047
1048   # cat Kexample.com.+013+34371.key
1049   ; This is a zone-signing key, keyid 34371, for example.com.
1050   ; Created: 20200616104249 (Tue Jun 16 11:42:49 2020)
1051   ; Publish: 20200616104249 (Tue Jun 16 11:42:49 2020)
1052   ; Activate: 20200616104249 (Tue Jun 16 11:42:49 2020)
1053   example.com. IN DNSKEY 256 3 13 AwEAAfel66...LqkA7cvn8=
1054   # cat Kexample.com.+013+00472.key
1055   ; This is a key-signing key, keyid 472, for example.com.
1056   ; Created: 20200616104254 (Tue Jun 16 11:42:54 2020)
1057   ; Publish: 20200616104254 (Tue Jun 16 11:42:54 2020)
1058   ; Activate: 20200616104254 (Tue Jun 16 11:42:54 2020)
1059   example.com. IN DNSKEY 257 3 13 AwEAAbCR6U...l8xPjokVU=
1060
1061The first line of each file tells us what type of key it is. Also, by
1062looking at the actual DNSKEY record, we can tell them apart: 256 is
1063ZSK, and 257 is KSK.
1064
1065The name of the file also tells us something
1066about the contents. See chapter :ref:`zone_keys` for more details.
1067
1068Make sure that these files are readable by :iscman:`named` and that the
1069``.private`` files are not readable by anyone else.
1070
1071Alternativelly, the :iscman:`dnssec-keyfromlabel` program is used to get a key
1072pair from a crypto hardware device and build the key files. Its usage is
1073similar to :iscman:`dnssec-keygen`.
1074
1075.. _manual_signing_key_timing_information:
1076
1077Setting Key Timing Information
1078^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1079
1080Key files contain time information related to rolling keys. This is placed
1081there by :iscman:`dnssec-keygen` when the file is created, and it can be
1082modified using :iscman:`dnssec-settime`. By default, only a limited amount of
1083timing information is included in the file, as illustrated in the examples in
1084the previous section.
1085
1086Note that :any:`dnssec-policy` does set key timing information, but it uses its
1087own state machine to determine what actions to perform.
1088
1089But when performing manual signing the key parameters and the timing
1090information in the key files, you can implement any DNSSEC policy you want for
1091your zones.
1092
1093All the dates are the same, and are the date and time that
1094:iscman:`dnssec-keygen` created the key. We can use
1095:iscman:`dnssec-settime` to modify the dates. The dates can also be
1096modified using an editor, but that is likely to be more error-prone than
1097using :iscman:`dnssec-settime`.  For example, to publish this key in the
1098zone on 1 July 2020, use it to sign records for a year starting on 15
1099July 2020, and remove it from the zone at the end of July 2021, we can
1100use the following command:
1101
1102.. code-block:: console
1103
1104   # dnssec-settime -P 20200701 -A 20200715 -I 20210715 -D 20210731 Kexample.com.+013+34371.key
1105   ./Kexample.com.+013+34371.key
1106   ./Kexample.com.+013+34371.private
1107
1108which would set the contents of the key file to:
1109
1110.. code-block:: none
1111
1112   ; This is a zone-signing key, keyid 34371, for example.com.
1113   ; Created: 20200616104249 (Tue Jun 16 11:42:49 2020)
1114   ; Publish: 20200701000000 (Wed Jul  1 01:00:00 2020)
1115   ; Activate: 20200715000000 (Wed Jul 15 01:00:00 2020)
1116   ; Inactive: 20210715000000 (Thu Jul 15 01:00:00 2021)
1117   ; Delete: 20210731000000 (Sat Jul 31 01:00:00 2021)
1118   example.com. IN DNSKEY 256 3 13 AwEAAfel66...LqkA7cvn8=
1119
1120(The actual key is truncated here to improve readability.)
1121
1122Below is a complete list of each of the metadata fields, and how each
1123one affects the signing of your zone:
1124
11251. *Created*: This records the date on which the key was created. It is
1126   not used in calculations; it is useful simply for documentation
1127   purposes.
1128
11292. *Publish*: This sets the date on which a key is to be published to the
1130   zone. After that date, the key is included in the zone but is
1131   not used to sign it. This allows validating resolvers to get a
1132   copy of the new key in their cache before there are any resource
1133   records signed with it. By default, if not specified at creation
1134   time, this is set to the current time, meaning the key is
1135   published as soon as :iscman:`named` picks it up.
1136
11373. *Activate*: This sets the date on which the key is to be activated. After
1138   that date, resource records are signed with the key. By default,
1139   if not specified during creation time, this is set to the current
1140   time, meaning the key is used to sign data as soon as :iscman:`named`
1141   picks it up.
1142
11434. *Revoke:* This sets the date on which the key is to be revoked. After that
1144   date, the key is flagged as revoked, although it is still included in the
1145   zone and used to sign it. This is used to notify validating
1146   resolvers that this key is about to be removed or retired from the
1147   zone. (This state is not used in normal day-to-day operations. See
1148   :rfc:`5011` to understand the circumstances where it may be used.)
1149
11505. *Inactive*: This sets the date on which the key is to become inactive.
1151   After that date, the key is still included in the zone, but it
1152   is no longer used to sign it. This sets the "expiration" or "retire"
1153   date for a key.
1154
11556. *Delete*: This sets the date on which the key is to be deleted. After that
1156   date, the key is no longer included in the zone, but it
1157   continues to exist on the file system or key repository.
1158
1159This can be summarized as follows:
1160
1161.. table:: Key Metadata Comparison
1162
1163   +----------+------------------+------------------+------------------+
1164   | Metadata | Included in Zone | Used to Sign     | Purpose          |
1165   |          | File?            | Data?            |                  |
1166   +==========+==================+==================+==================+
1167   | Created  | No               | No               | Recording of     |
1168   |          |                  |                  | key creation     |
1169   +----------+------------------+------------------+------------------+
1170   | Publish  | Yes              | No               | Introduction of  |
1171   |          |                  |                  | a key soon to be |
1172   |          |                  |                  | active           |
1173   +----------+------------------+------------------+------------------+
1174   | Activate | Yes              | Yes              | Activation date  |
1175   |          |                  |                  | for new key      |
1176   +----------+------------------+------------------+------------------+
1177   | Revoke   | Yes              | Yes              | Notification of  |
1178   |          |                  |                  | a key soon to be |
1179   |          |                  |                  | retired          |
1180   +----------+------------------+------------------+------------------+
1181   | Inactive | Yes              | No               | Inactivation or  |
1182   |          |                  |                  | retirement of a  |
1183   |          |                  |                  | key              |
1184   +----------+------------------+------------------+------------------+
1185   | Delete   | No               | No               | Deletion or      |
1186   |          |                  |                  | removal of a key |
1187   |          |                  |                  | from a zone      |
1188   +----------+------------------+------------------+------------------+
1189
1190The publication date is the date the key should be introduced into the zone.
1191The activation date can be used to determine when to sign resource records.
1192With "Inactive" you signal when the signer should stop generating new
1193signatures with the given key, and the "Delete" metadata specifies when the key
1194should be removed from the zone.
1195
1196Finally, we should note that the :iscman:`dnssec-keygen` command supports the
1197same set of switches so we could have set the dates
1198when we created the key.
1199
1200.. [#signal_zone_presence]
1201   Only one key file - for either a KSK or ZSK - is needed to signal the
1202   presence of the zone. :iscman:`dnssec-keygen` creates files of both
1203   types as needed.
1204
1205.. _manual_signing_the_zone:
1206
1207Signing the Zone
1208^^^^^^^^^^^^^^^^
1209
1210Now, edit the zone file to make sure the proper DNSKEY entries are included.
1211The public keys should be inserted into the zone file by including the
1212``.key`` files using ``$INCLUDE`` statements.
1213
1214Use the command :iscman:`dnssec-signzone`. Any ``keyset`` files corresponding
1215to secure sub-zones should be present. The zone signer generates ``NSEC``,
1216``NSEC3``, and ``RRSIG`` records for the zone, as well as ``DS`` for the child
1217zones if :option:`-g <dnssec-signzone -g>` is specified. If
1218:option:`-g <dnssec-signzone -g>` is not specified, then DS RRsets for the
1219secure child zones need to be added manually.
1220
1221The following command signs the zone, assuming it is in a file called
1222``zone.child.example``, using manually specified keys:
1223
1224.. code-block:: console
1225
1226   # cd /etc/bind/keys/example.com/
1227   # dnssec-signzone -t -N INCREMENT -o example.com -f /etc/bind/db/example.com.signed.db \
1228       /etc/bind/db/example.com.db Kexample.com.+013+17694.key Kexample.com.+013+06817.key
1229   Verifying the zone using the following algorithms: ECDSAP256SHA256.
1230   Zone fully signed:
1231   Algorithm: ECDSAP256SHA256: KSKs: 1 active, 0 stand-by, 0 revoked
1232                               ZSKs: 1 active, 0 stand-by, 0 revoked
1233   /etc/bind/db/example.com.signed.db
1234   Signatures generated:                       17
1235   Signatures retained:                         0
1236   Signatures dropped:                          0
1237   Signatures successfully verified:            0
1238   Signatures unsuccessfully verified:          0
1239   Signing time in seconds:                 0.046
1240   Signatures per second:                 364.634
1241   Runtime in seconds:                      0.055
1242
1243The :option:`-o <dnssec-signzone -o>` switch explicitly defines the domain name
1244(``example.com`` in this case), while the :option:`-f <dnssec-signzone -f>`
1245switch specifies the output file name. The second line has three parameters:
1246the unsigned zone name (``/etc/bind/db/example.com.db``), the ZSK file name,
1247and the KSK file name. This also generates a plain-text file
1248``/etc/bind/db/example.com.signed.db``, which can be manually verified for correctness.
1249
1250:iscman:`dnssec-signzone` also produces keyset and dsset files. These are used
1251to provide the parent zone administrators with the ``DNSKEY`` records (or their
1252corresponding ``DS`` records) that are the secure entry point to the zone.
1253
1254By default, all zone keys which have an available private key are used
1255to generate signatures. You can use the :option:`-S <dnssec-signzone -S>` to
1256only include keys that have the "Activate" timing metadata in the past and
1257the "Inactive" timing metadata in the future (or not present).
1258
1259.. _manual_signing_reloading_zone:
1260
1261Reloading the Zone
1262^^^^^^^^^^^^^^^^^^
1263
1264Now it is time to inform BIND that a new signed zonefile is available. We can
1265do this with the :option:`rndc reload example.com <rndc reload>` command.
1266
1267.. _manual_signing_verification:
1268
1269Verifying That the Zone Is Signed Correctly
1270^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1271
1272You should now check that the zone is signed. Follow the steps in
1273:ref:`signing_verification`.
1274
1275.. _manual_signing_upload_ds:
1276
1277Uploading the DS Record to the Parent
1278^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1279
1280As described in :ref:`signing_easy_start_upload_to_parent_zone`, we must now
1281upload the new information to the parent zone. The format of the information
1282and how to generate it is described in :ref:`working_with_parent_zone`,
1283although it is important to remember that you must use the contents of the
1284KSK file that you generated above as part of the process.
1285
1286The file ``dsset-example.com`` (created by :iscman:`dnssec-signzone` when it
1287signed the ``example.com`` zone) contains the DS record for the zone's KSK.
1288
1289If not yet done so, you will need to pass that to the administrator of the
1290parent zone, to be placed in the zone. When the DS record is published in the
1291parent zone, your zone is fully signed.
1292
1293.. _manual_signing_validation:
1294
1295Checking That Your Zone Can Be Validated
1296^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1297
1298Finally, follow the steps in :ref:`how_to_test_authoritative_server`
1299to confirm that a query recognizes the zone as properly signed and
1300vouched for by the parent zone.
1301
1302.. _manual_signing_resigning:
1303
1304Re-signing the Zone
1305^^^^^^^^^^^^^^^^^^^
1306
1307Since this is a manual process, you will need to re-sign periodically,
1308as well as every time the zone data changes. You will also need to manually
1309roll the keys by adding and removing DNSKEY records (and interacting with the
1310parent) at the appropriate times.
1311
1312So... What Now?
1313^^^^^^^^^^^^^^^
1314
1315Once the zone is signed, it must be monitored as described in
1316:ref:`signing_maintenance_tasks`. However, as the time approaches for a key
1317roll, you must create the new key. Of course, it is possible to create keys
1318for the next fifty years all at once and set the key times appropriately.
1319Whether the increased risk in having the private key files for future keys
1320available on disk offsets the overhead of having to remember to create a new
1321key before a rollover depends on your organization's security policy.
1322
1323.. _advanced_discussions_offline_ksk:
1324
1325Offline KSK
1326~~~~~~~~~~~
1327
1328For operational reasons, it is possible to keep the KSK offline. Doing so
1329minimizes the risk of the key being compromised through theft or loss.
1330
1331This effectively means that the private keys of the KSKs and the ZSKs are
1332located in two physically separate places. The KSK is kept completely offline,
1333and the ZSK is used in the primary DNS server to sign the zone data. The
1334DNSKEY, CDS, and CDNSKEY RRsets are signed separately by the KSK.
1335
1336Because of this, CSKs are incompatible with Offline KSK.
1337
1338To enable Offline KSK in BIND 9, add the following to the :any:`dnssec-policy`
1339configuration:
1340
1341::
1342
1343   dnssec-policy "offline-ksk" {
1344     ...
1345     offline-ksk yes;
1346   };
1347
1348With this configuration, BIND 9 will no longer generate signatures for the
1349DNSKEY, CDS, and CDNSKEY RRsets, nor will it generate keys for rollovers.
1350
1351Before enabling Offline KSK, the keys and signed RRsets must be pregenerated.
1352This can be done with the :iscman:`dnssec-ksr` program, which is used to
1353create Signed Key Response (SKR) files that can be imported into BIND 9.
1354
1355Creating SKR files is a four-step process. First, the ZSKs must be
1356pregenerated; then, a Key Signing Request (KSR) is created. This file is
1357presented to the KSK operators to be signed. The result is a SKR file that
1358is returned to the ZSK operators, to be imported into the DNS server.
1359
1360Pregenerating ZSKs
1361^^^^^^^^^^^^^^^^^^
1362
1363First we need to pregenerate ZSKs for the future. Let's say we want to
1364generate enough keys for the next two years; this will create several key
1365files, depending on the :any:`dnssec-policy` used. If the ZSK lifetime
1366is six months, this will create about four keys (other timing metadata may
1367cause an extra key to be generated).
1368
1369This can be done with the :iscman:`dnssec-ksr` program:
1370
1371.. code-block:: none
1372
1373    # dnssec-ksr -i now -e +2y -k offline-ksk -l named.conf keygen example.net
1374    Kexample.net.+013+63278
1375    Kexample.net.+013+13211
1376    Kexample.net.+013+50958
1377    Kexample.net.+013+12403
1378
1379The timing metadata is set accordingly in the key files. Keys that already
1380exist in the :any:`key-directory` are taken into consideration when
1381pregenerating keys; if the above command is run multiple times quickly in
1382succession, no additional keys are generated.
1383
1384Key Signing Request
1385^^^^^^^^^^^^^^^^^^^
1386
1387Now that we have keys that can be published in the zone, we need to get
1388signatures for the DNSKEY RRset to be used in the future. For that,
1389we generate a Key Signing Request (KSR). In this example, we are using the
1390same DNSSEC policy and interval.
1391
1392.. code-block:: none
1393
1394    # dnssec-ksr -i now -e +2y -k offline-ksk -l named.conf keygen example.net
1395    ;; KeySigningRequest 1.0 20240813133035 (Tue Aug 13 15:30:35 2024)
1396    example.net. 3600 IN DNSKEY	256 3 13 Z8WRuXJr9v7cSUZpJuQKN/1pZuLPEgoWx4eQOhVI8Edz49F7xpbxnGar aLelIIIlWuRyjdvUtsnitAfWvyGjqQ==
1397    ;; KeySigningRequest 1.0 20250215111826 (Sat Feb 15 12:18:26 2025)
1398    example.net. 3600 IN DNSKEY	256 3 13 ph7zZ/QgvwHuq2U1aYoMT3MqPUZYEq6y4qNwOb8uzurVISxL0XyhYH+Q ngEOV2ECgndMjn8e1ujH/d0H3cPX8A==
1399    example.net. 3600 IN DNSKEY	256 3 13 Z8WRuXJr9v7cSUZpJuQKN/1pZuLPEgoWx4eQOhVI8Edz49F7xpbxnGar aLelIIIlWuRyjdvUtsnitAfWvyGjqQ==
1400    ;; KeySigningRequest 1.0 20250225142826 (Tue Feb 25 15:28:26 2025)
1401    example.net. 3600 IN DNSKEY	256 3 13 ph7zZ/QgvwHuq2U1aYoMT3MqPUZYEq6y4qNwOb8uzurVISxL0XyhYH+Q ngEOV2ECgndMjn8e1ujH/d0H3cPX8A==
1402    ...
1403
1404The output shows that the ZSK rollovers are pre-planned, which will result
1405in a number of key bundles. Each bundle contains a start time and the ZSKs that
1406need to be published from that time.
1407
1408The data needs to be stored in a file and can be handed over to the KSK
1409operators, and can be secured by encryption and/or digital signature.
1410
1411Signed Key Response
1412^^^^^^^^^^^^^^^^^^^
1413
1414The KSK operators receive a KSR file that contain ZSK sets for a given
1415interval. By signing the KSR, a Signed Key Response (SKR) is created that
1416consists of numerous response bundles; for each bundle, the DNSKEY RRset
1417needs to be constructed by combining the records of the KSK and ZSKs. Then,
1418a signature is generated for the constructed RRset. In addition, the signed
1419CDS and CDNSKEY RRsets are added.
1420
1421Again the same interval and DNSSEC policy should be used. Below is the command
1422for signing a KSR file "example.net.ksr".
1423
1424.. code-block:: none
1425
1426    # dnssec-ksr -i now -e +2y -k offline-ksk -l named.conf -K ksk -f example.net.ksr sign example.net
1427    ;; SignedKeyResponse 1.0 20240813134020 (Tue Aug 13 15:40:20 2024)
1428    example.net. 3600 IN DNSKEY	257 3 13 vV2+6W+cFd3nn8eLrswUnhrPIxdgmslFWwF45MlCPIhjXIp6PpvaHC8k Y2RH46UrbWINDEo7k5wqvUncakKhJw==
1429    example.net. 3600 IN DNSKEY	256 3 13 Z8WRuXJr9v7cSUZpJuQKN/1pZuLPEgoWx4eQOhVI8Edz49F7xpbxnGar aLelIIIlWuRyjdvUtsnitAfWvyGjqQ==
1430    example.net. 3600 IN RRSIG DNSKEY 13 2 3600 20240827134020 20240813124020 6221 example.net. gkiw6M72Gi8XDu8XEAnPVR+AF4K7j1fApt2puLWgChayvaWrMPIbG2jP gvd/RJiJSsdGBx4P3GYdNqfFskNKIA==
1431    example.net. 3600 IN CDNSKEY 257 3 13 vV2+6W+cFd3nn8eLrswUnhrPIxdgmslFWwF45MlCPIhjXIp6PpvaHC8k Y2RH46UrbWINDEo7k5wqvUncakKhJw==
1432    example.net. 3600 IN RRSIG CDNSKEY 13 2 3600 20240827134020 20240813124020 6221 example.net. 1hAwRv2Nbkwfv8KWXdM9eBedgFZapECZJN4iTKj/yb50mjrPjK9JiQ92 m/xSFUC6gRxMkoPnaULYs+3Qc/XqDA==
1433    example.net. 3600 IN CDS 6221 13 2 A9EEDE51FA154B90259A1B8788D26C53C20AFE759D3B5FEA0349675A EEC0479D
1434    example.net. 3600 IN RRSIG CDS 13 2 3600 20240827134020 20240813124020 6221 example.net. TtbCbxTP4WEm5W8ZOdD3DgVlDSz0sdimm5YO28Bi+kP2ZVEM72A0B9QP pCiXKrRjCLN2aguqNlRzupWiwb22cA==
1435    ;; SignedKeyResponse 1.0 20240822134020 (Thu Aug 22 15:40:20 2024)
1436    example.net. 3600 IN DNSKEY	257 3 13 vV2+6W+cFd3nn8eLrswUnhrPIxdgmslFWwF45MlCPIhjXIp6PpvaHC8k Y2RH46UrbWINDEo7k5wqvUncakKhJw==
1437    example.net. 3600 IN DNSKEY	256 3 13 Z8WRuXJr9v7cSUZpJuQKN/1pZuLPEgoWx4eQOhVI8Edz49F7xpbxnGar aLelIIIlWuRyjdvUtsnitAfWvyGjqQ==
1438    ...
1439
1440The output is stored in a file and can be given back to the ZSK operators.
1441
1442Importing the SKR
1443^^^^^^^^^^^^^^^^^
1444
1445Now that we have an SKR file, it needs to be imported into the DNS server,
1446via the :option:`rndc skr` command. Let's say the SKR is stored
1447in a file "example.net.skr":
1448
1449.. code-block:: none
1450
1451    # rndc skr -import example.net.skr example.net
1452
1453From now on, when it is time for a new signature for the DNSKEY, CDS, or CDNSKEY
1454RRset, instead of it being generated, it will be looked up in the SKR data.
1455
1456When the SKR data is nearing the end of its lifetime, simply repeat the
1457four-step process for the next period.
1458