DNSSEC HOWTO, a tutorial in disguise

Olaf Kolkman
Version 1.8.4-prerelease (svn: 101)

August 22, 2007
____________________________________________________________________

Download the most recent version of the PDF version here: http://www.nlnetlabs.nl/dnssec_howto/dnssec_howto.pdf

Contents

I  Securing DNS data
1 Configuring a recursive name server to validate answers
 1.1 Introduction
 1.2 Warning
 1.3 Configuring the caching forwarder
  1.3.1 Configuring a trust anchor
  1.3.2 Testing
 1.4 Finding trust-anchors
 1.5 Lookaside Validation
  1.5.1 Configuring lookaside validation
  1.5.1.1 testing
 1.6 Some Troubleshooting Tips
2 Securing a DNS zone
 2.1 Introduction
 2.2 Configuring authoritative servers
 2.3 Creating key pairs
  2.3.1 Key Maintenance Policy
  2.3.1.1 Key- and zone-signing keys.
  2.3.2 Creating the keys
 2.4 Zone-signing
 2.5 Caching forwarder configuration
 2.6 Zone Re-Signing
 2.7 Troubleshooting Signed Zones
 2.8 Possible problems
3 Delegating of signing authority; becoming globally secure
 3.1 Introduction
 3.2 Practical steps
 3.3 Possible problems
 3.4 Registering with a DLV registry
4 Rolling keys
 4.1 DNS traversal
 4.2 ”Pre-Publish” and ”Double Signature” rollovers
 4.3 Tools
 4.4 ZSK rollover
  4.4.1 ZSK preparation (production phase)
  4.4.2 ZSK rollover (phase1)
  4.4.3 ZSK Cleanup (phase2)
  4.4.4 Modifying zone data during a rollover
 4.5 Key-signing key rollovers
  4.5.1 KSK preparation (production phase)
  4.5.2 ZSK rollover (phase 1)
  4.5.3 KSK cleanup (phase 2)
  4.5.4 Multiple KSKs
II  Securing communication between Servers
5 Securing zone transfers
 5.1 Introduction
 5.2 Generating a TSIG key
  5.2.1 Generating a TSIG secret with dnssec-keygen
  5.2.2 Other ways to generate secrets
 5.3 Configuring TSIG keys
 5.4 Primary servers configuration of TSIG
 5.5 Secondary servers configuration of TSIG
 5.6 Securing the NOTIFY message too
 5.7 Troubleshooting TSIG configuration
 5.8 Possible problems
  5.8.1 Timing problems
  5.8.2 Multiple server directives
III  Troubleshooting tools
6 Using drill for troubleshooting
7 Using dig for troubleshooting
8 DNSSEC tools
IV  Appendices
A BIND installation
B Estimating zone size increase
C Generating random numbers
D Perl’s Net::DNS::SEC library

About This Document

This document was developed as part of the RIPE NCC project on the deployment of DNSSEC. The document started as being an addendum to the RIPE NCC DNSSEC course. It was found to be more useful as a stand alone ”HOWTO” for setting up DNSSEC in ones own environment.

In the cause of time the document has been updated during workshops and based on feedback by folk using the document. It has grown beyond the size of your typical HOWTO.

In this HOWTO, which, because of its bulky nature is more of a tutorial in disguise, we touch upon the following topics:

Part I,
about the aspects of DNSSEC that deal with data security.
  • Creating an island of security (Chapter 1, “Configuring a recursive name server to validate answers” and Chapter 2, “Securing a DNS zone”) by configuring a recursive name server to validate the signed zones served by your organisations authoritative name servers. When you have learnt and implemented this, you can be sure that DNS data in your organisation is protected from change. Once you have created an island of security it is a small step to become part of a chain of trust.
  • Delegating signing authority; building a chain of trust (Chapter 3, “Delegating of signing authority; becoming globally secure”). You will learn how to exchange keys with your parent and with your children.
  • Chapter 4, “Rolling keys” covers maintaining keys and ensuring that during the rollover process clients will be able to maintain a consistent view of your DNS data.
Part II,
covering aspects that deal with server to server security and transaction security.
  • Chapter 5, “Securing zone transfers” is on the use of transaction security (TSIG) to provide authorisation and integrity for zone transfers.
Part III,
describes a few tools that may turn out handy while figuring out what might have gone wrong.

The documentation is based on the so called DNSSEC-bis specifications that where finalised by the IETF DNSEXT working group in July 2004 and published in March 2005 as [354].

As of November 2006 the author is aware of the following open-source and or freeware implementations of the DNSSEC-bis specifications: BIND 9.3.2 and NSD 3.0.3. All our examples are based on BIND 9.4.1-P1.

This document is not intended as an introduction to DNS. Basic knowledge of DNS and acronyms used is assumed. We have tried not to use jargon but when unavoidable we have tried to explain the meaning. If you want to know more about the topic of DNS in general then Paul Albitz and Cricket Lui’s[2] or Ron Aitchinson’s [1] text books provide an excelent introduction.

This document will be subject to change. Please regularly check for new versions. <http://www.nlnetlabs.nl/dnssec_howto/>. Your corrections and additions are appreciated.

Part I
Securing DNS data

This part deals with securing data in zone files. We describe how to generate and manage keys, how to set up a recursive name server to validate signed zone data and how to sign and serve zones.

1 Configuring a recursive name server to validate answers

1.1 Introduction

We plan to configure a recursive name server to validate the data it receives. Users that use this recursive name server as their resolver will, then, only receive data that is either secure and validated or not secured in any way. As a result, secured data that fails validation will not find its way to the users1. Having a validating recursive name server protects all those that use it as a forwarder against receiving spoofed DNS data.

Figure 1 illustrates how to configure the recursive DNS servers with a trusted key for ”example.com” so that all the data served by the authoritative servers for ”example.com” is validated before it is handed to the protected infrastructure that have the recursive servers configured as their forwarder (the name servers that usually are assigned through DHCP or configured in /etc/resolv.conf).


PIC

Figure 1: DNS environment


By configuring a public key for a specific zone, we tell the caching forwarder that all data coming from that zone should be signed with the corresponding private key. The zone acts as a secure entry point into the DNS tree and the key configured in the recursive name server acts as the start for a chain of trust. In an ideal situation you have only one key configured as a secure entry point: the key of the root zone.

We assume you have configured your name server to be recursive only.

We also assume that that name server in your organisation has been configured to run as an authoritative server for a secured zone called example.net. Notes on how to set up a secured zone can be found below in Chapter 2, “Securing a DNS zone”

1.2 Warning

Your recursive name server will treat the zones for which you configured trust anchors as being secured. If the zones for which you have configured trust anchors change their keys you will also have to reconfigure your trust anchors. Failure to do so will result in the data in these zones, or any child, being marked as bogus and therefore becoming invisible to users.

1.3 Configuring the caching forwarder

See AppendixA for information on compiling BIND with the correct switches to allow for DNSSEC. Do not forget enter the dnssec-enable yes; and dnssec-validation yes; statements in the options directive of your named.conf.2

1.3.1 Configuring a trust anchor

A trust anchor is a public key that is configured as the entry point for a chain of authority. In the ideal case —where the root is signed and chains of trusts can be constructed through top-level domains to end-nodes — validating name servers would only need one of these trust anchors to be configured. During early deployment you will probably want to configure multiple trust anchors.


PIC

Figure 2: Trust anchors in the DNS tree


In Figure 2 we show a zone tree. In this tree, the domains ripe.net, 194.in-addr.arpa, 193.in-addr.arpa and 0.0.193.in-addr.arpa are assumed to be signed. It is also assumed that there is a secure delegation between 193.in-addr.arpa and 0.0.193.in-addr.arpa. In order to validate all these domains, the validating DNS client would have to configure trust anchors for ripe.net, 194.in-addr.arpa and 193.in-addr.arpa.3

To configure a trust-anchor you have to obtain the public key of the zone that you want to use as the start of the chain of authority that is to be followed when the data is validated. It is possible to get these straight from from the DNS, but there are two reasons why this may not be advisable.

Firstly, you have to establish the authenticity of the key you are about to configure as your trust anchor. How you do this depends on on what method the zone owner has made available for out of band validation of the key.

  • You could do this by visiting the zone owners secure website and validate the key information. For instance, the RIPE NCC signs a number of reverse zones. They publish their public keys on through <https://www.ripe.net/projects/disi/keys/>
  • You could give the zone owner a call if you personally know them.
  • You could trust the key that is published on the bill you just received from the zone owner.
  • You could just believe that your OS vendor did the validation on your behalf.

Secondly, you may have a choice of public keys, in which case you need to select the the proper ”Secure Entry Point” key.

In DNSSEC a difference is made between key- and zone-signing keys. Key-signing keys exclusively sign the DNSKEY RR set at the apex, while zone-signing keys sign all RR sets in a zone. 4. Key-signing keys are often used as Secure Entry Points (SEP) keys. These SEP keys are the keys intended to be first used when building a chain of authority from a trust anchor to signed data. We advise a one-to-one mapping between SEP keys and key-signing keys. In practise key-signing keys have a lower rollover frequency than zone-signing keys so you should configure the SEP i.e. key-signing keys.

In addition to having the proper public key you should either be aware of the rollover policy of the zone owner, or that you have a tool that takes care of automated rollover. Failure to modify the trust anchor before the corresponding SEP key is rolled will result in validation failures.

Assume you have obtained the key-signing keys of nlnetlabs.nl., 193.in-addr.arpa., and 195.in-addr.arpa.. To configure those key as a trust anchor you will have to include those keys using the trusted-keys directive in the named.conf of the recursive name server. See figure 3.


  

  // Trusted keys

  // These are examples only, do not use in production

  

  trusted-keys {

  "nlnetlabs.nl."  3 5

    "AQPzzTWMz8qSWIQlfRnPckx2BiVmkVN6LPupO3mbz7Fh

     LSnm26n6iG9NLby97Ji453aWZY3M5/xJBSOS2vWtco2t

     8C0+xeO1bc/d6ZTy32DHchpW6rDH1vp86Ll+ha0tmwyy

     9QP7y2bVw5zSbFCrefk8qCUBgfHm9bHzMG1UBYtEIQ==";

  

  "193.in-addr.arpa." 257 3 5

    "AwEAAc2RnCT1gjU22FbNC1baMQec77fq60z2HlCKscYl

     3idBZTp703ApMfAAFcMZQGkSmo8NP+47KqZJwG9ISLaT

     bUais3khgFVrf7lIRzPJAMlXHsmOMmpq5xBORF66EDt/

     u2dau3qqzOfb/BrKCklGgnwBosgqaSPmWBQTuzJFqzi3

     4FQIt4xFHWYyt3B5qZ9h4dpUL96etvvx1N+z8tlXjhlm

     Vauw1EPZnz2rmY6HEJFS2zjaI1FrDtY5/pooJjRWjobk

     RXL3iqjd5J/cmDikxjQCjwnbwBS+YvcwZCos4n9Xh2l5

     kf2kOcq9xCmZvEplfWJ9lWbVkfhpWaM8qXXPN8E=";

  

  

  "195.in-addr.arpa." 257 3 5

    "AwEAAaMN4kOrGaiHJBikvcf+mhPxzprL85Q40VA0hbRc

     a8FDDn6Xlkuj95Nizy2vMrOy1MjIjo7a+GACGp6C/Rdj

     6nDimsRrUBr/G/dq+zBgg8qvRXWJZhx+zNCgkfv9gs1B

     eRlPnjXr1K/x5viTzQRDK3SYfHiCMVNxuYN+T7kniDLx

     QRUI/ASF3YxqNQ+Oo+T5L6nYtO7uLeAUdxzToRdIHaey

     iSnq52boA/3Yg6X8Kbo1uAUpeU4QDD7bOwq+obmaToLU

     m/FvNUKx0l9U2P2ItcsqRCHQut/RxK2pj8GGRDCDco1J

     5UAi7hiwP1eEWmbigbPnDQg++QDjegV39vTJQ2c=";

  };   


Figure 3: trust anchor configuration


The format is similar to the DNSKEY RR except that the ”DNSKEY” label, the CLASS and the TTL, are omitted and quotes are placed around the name and the public key material.

1.3.2 Testing

As soon as a trusted-key has been configured, data from that zone or its sub zones will be validated by the caching forwarder. You can test this by querying your server5. If data is validated by the caching forwarder the ad-bit will be set by the name server (see the ’flags’ in the following example).

  

  ; <<>> DiG 9.4.1-P1 <<>> @192.168.2.204 example.net SOA +dnssec +multiline +retry=1

  ; (1 server found)

  ;; global options:  printcmd

  ;; Got answer:

  ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52761

  ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 3

  

  ;; OPT PSEUDOSECTION:

  ; EDNS: version: 0, flags: do; udp: 4096

  ;; QUESTION SECTION:

  ;example.net.           IN SOA

  

  ;; ANSWER SECTION:

  example.net.            100 IN SOA ns.example.net. olaf.nlnetlabs.nl. (

                                  2002050501 ; serial

                                  100        ; refresh (1 minute 40 seconds)

                                  200        ; retry (3 minutes 20 seconds)

                                  604800     ; expire (1 week)

                                  100        ; minimum (1 minute 40 seconds)

                                  )

  example.net.            100 IN RRSIG SOA 5 2 100 20070921083615 (

                                  20070822083615 17000 example.net.

                                  hF5zE2007NcvrGtvUQ0PIjBxVKS+fgsP5VQi3iRkbfny

                                  Av0MiSIY7+Ectq8Zg9gxZCBfUErUXIPm+xfxOtguZTTN

                                  /X3gAldOgG4Eo3FAu4pkOk95S3QM8AvCYXqigNIL6HlX

                                  PHOCR490VJAhVv28dLmwIQDMOyJEPiIHaqmcTDY= )

  

  ;; AUTHORITY SECTION:

  example.net.            100 IN NS ns.example.net.

  example.net.            100 IN RRSIG NS 5 2 100 20070921083615 (

                                  20070822083615 17000 example.net.

                                  jy/ARrpR/RwVhvCHNkNaEiXTKnw+zbWHK8zASnCrSHgd

                                  4jt7Wdz4esrD5FivpE8xuSlGuu1RQOKCtFfAFwdhgrGb

                                  Dzq+KbkgwE8yMWRrLqzp9WTeJNeVBZj2yijfxkgIyCKp

                                  xHQJJ7aUMhbb+K3UmiVshXjRHqq/brGcHAKzya0= )

  

  ;; ADDITIONAL SECTION:

  ns.example.net.         100 IN A 192.168.2.203

  ns.example.net.         100 IN RRSIG A 5 3 100 20070921083615 (

                                  20070822083615 17000 example.net.

                                  VA7RgWoOCctvEJlo6e8yIw6t9ZvcZ+df4TU0oIUzmvzY

                                  WpW/M1mxRaAhr9m0no+tLfx3rOCIl3ARTHNa/ayCEeae

                                  NiShYUlMfMvjmrowuNlDmrbAsVkYZQTp+4cqVF7IsQ88

                                  Fm846aPdTF7hPuLAMQBn/ptb8GyJ7mcxOVRq0J4= )

  

  ;; Query time: 10 msec

  ;; SERVER: 192.168.2.204#53(192.168.2.204)

  ;; WHEN: Wed Aug 22 11:36:19 2007

  ;; MSG SIZE  rcvd: 639

     

It is important that you check that the validation is working correctly. This can be done by using the BIND log facilities on the machine that is configured as the validating recursive name server.

In BIND messages of a certain category can be logged to separate channels. The channels determine where the messages go and to what severity level they will need to be reported. The relevant category for DNSSEC validation is dnssec. In the example below the errors of the dnssec category are directed to the dnssec_log channel. In order to follow the validation process the channel has to log at least severity debug 3.

  

  logging {

          channel dnssec_log {             // a DNSSEC log channel

                  file "log/dnssec" size 20m;

                  print-time yes;        // timestamp the entries

                  print-category yes;    // add category name to entries

                  print-severity yes;    // add severity level to entries

                  severity debug 3;      // print debug message <= 3 t

  

          };

  

    category dnssec  { dnssec_log;  };

  }   

The output in the log file will look similar to the output below. The attempt for positive response validation shows how the validator tries to prove that the RR set is trusted by following the chain of trust to the appropriate secure entry point, your trusted-key statement. Chains of trust (see figure 4) start by the validation of a signature over a DNSKEY RRset, then these keys are used to validate the DS RRset that point to DNSKEY RRs in a child zone – which validates the DNSKEY RRs in the child zone –, or the DNSKEYs can be used to validate the data you have queried for. The log reflects the activity of the validator following the chain of trust.


PIC

Figure 4: Chain of Trust


  validating @0x186bc00: example.net SOA: starting

  validating @0x186bc00: example.net SOA: attempting positive response validation

  validating @0x186c400: example.net DNSKEY: starting

  validating @0x186c400: example.net DNSKEY: attempting positive response validation

  validating @0x186c400: example.net DNSKEY: verify rdataset (keyid=49656): success

  validating @0x186c400: example.net DNSKEY: signed by trusted key; marking as secure

  validator @0x186c400: dns_validator_destroy

  validating @0x186bc00: example.net SOA: in fetch_callback_validator

  validating @0x186bc00: example.net SOA: keyset with trust 7

  validating @0x186bc00: example.net SOA: resuming validate

  validating @0x186bc00: example.net SOA: verify rdataset (keyid=17000): success

  validating @0x186bc00: example.net SOA: marking as secure

  validator @0x186bc00: dns_validator_destroy   

1.4 Finding trust-anchors

It is not trivial to find and maintain trust anchors. If you want to get started with validation of DNSSEC here are a few places where you can find more information.

Since maintaining trust anchors is a pain you may also want to read the section 1.5 on lookaside validation.

1.5 Lookaside Validation

Remember figure 2. If you would like to validate all these islands you will have to configure many trust-anchors, as in the example in figure 3.

In order to deal with this problem in absence of secure delegation from a small set of trust-anchors (ideally only 1, the root), BIND supports, as of version 9.3.2, a 6 mechanism called lookaside validation [1413].

In the lookaside validation a DLV registry will maintain all the trust-anchors you trust them to do the “Good Thing”. The maintainers of zones that are secure register their trust-anchors with the DLV registry and (non-standard extensions) in BIND (as of 9.3.2) will allow you, operator of a validating nameserver, to make use of all trust anchors that are present in the DLV tree.

In the DLV scheme the trust anchors are published in a dedicated domain (dlv.isc.org in the figure 5). Whenever a validating resolver recognises that a zone is signed it will first try to validate it by assessing if it is within the island of trust configured by its local trust anchors. When the validated domain is not in a trusted island the resolver will lookup perform a lookup in the DLV domain and use the trust anchor from that zone if and when available.


PIC

Figure 5: Trust anchors in the lookaside tree


1.5.1 Configuring lookaside validation

What follows is a generic description if you want to configure ISC’s DLV as your authoritative lookaside domain you may want to read http://www.isc.org/ops/dlv/.

In the example below we assume that dlv-registry.org is the registry of our choice.

You have to perform two (additional) steps in order to turn on lookaside validation.

Configure a trust anchor for the DLV registry. You do this by defining a trust anchor for the island of trust defined by dlv-registry.org in named.conf. Obviously, this trust-anchor is not exclusive, any trust-anchor configured in your trusted-keys statement will have preference over the data in the DLV registry.

  

  trusted-keys {

    //

    // this trust-anchor defines dlv-registry.org as a trusted island.

    //

    "dlv-registry.org." 257 3 5

          "AQPXP7B3JTdPPhMl ... u82ggY2BKPQ==";

    //

    // Other trust anchors below.

    //

  

    "nlnetlabs.nl."  3 5

            "AQPzzTWMz8qSWI ... zMG1UBYtEIQ==";

  

    "193.in-addr.arpa." 257 3 5

            "AwEAAc2RnCT1gj ... pWaM8qXXPN8E=";

  

  

     "195.in-addr.arpa." 257 3 5

           "AwEAAaMN4kOrGai ... DjegV39vTJQ2c=";

  };   

Configuring how the DNS name space anchors in the DLV name space. By using the dnssec-lookaside statement in the options section of named.conf. The statement takes two arguments the first one is the domain in the DNS for which lookaside validation is to be applied. Usually this will be the full name space so the "." (root) is configured. The second argument is the name of the trust-anchor where a lookup should be performed for a DLV record.

It is best to configure only one DLV trust-anchor.

  options {

    // DNSSEC should be turned on, do not forget

    dnssec-enable yes;

    dnssec-validation yes;

    // This sets the dlv registry "dlv-registry.org"

    dnssec-lookaside "." trust-anchor "dlv-registry.org.";

  

    // other options are skipped in this example

  };   

testing When you have your logging configured as described in section 1.3.2 i.e. you log errors of the dnssec category are directed to a channel that logs at least at severity debug 3, then your log output when querying for example.net SOA will be similar to what is shown below.

First, the amount of log-ouput to validate one query covers more than one page of fine print. On a production server this data for several validation sequences will be print mixed. It will be very hard to debug from logfiles on production servers if you have not first looked at what happens for a single query.

Second, the structure is that the validator first finds DNSSEC RRs, notices that those records are not secure according ’plain DNSSEC’ and then moves to DLV validation.

Third, small chains of trust are build, from the DLV trust-anchor, via DNSKEY RRs to the signatures over the data. Trie to follow these trust anchors in the example output so it will be easier to identify them in production logs.

  validating @0x186bc00: . NS: starting

  validating @0x186bc00: . NS: looking for DLV

  validating @0x186bc00: . NS: plain DNSSEC returns unsecure (.): looking for DLV

  validating @0x186bc00: . NS: looking for DLV dlv-registry.org

  validating @0x186bc00: . NS: DLV lookup: wait

  validating @0x186c400: example.net SOA: starting

  validating @0x186c400: example.net SOA: looking for DLV

  validating @0x186c400: example.net SOA: plain DNSSEC returns unsecure (.): looking for DLV

  validating @0x186c400: example.net SOA: looking for DLV example.net.dlv-registry.org

  validating @0x186c400: example.net SOA: DNS_R_COVERINGNSEC

  validating @0x186c400: example.net SOA: covering nsec: trust 1

  validating @0x186c400: example.net SOA: DLV lookup: wait

  validating @0x1876200: dlv-registry.org DLV: starting

  validating @0x1876200: dlv-registry.org DLV: attempting negative response validation

    validating @0x1876a00: dlv-registry.org SOA: starting

    validating @0x1876a00: dlv-registry.org SOA: attempting positive response validation

  validating @0x1877200: dlv-registry.org DNSKEY: starting

  validating @0x1877200: dlv-registry.org DNSKEY: attempting positive response validation

  validating @0x1877200: dlv-registry.org DNSKEY: verify rdataset (keyid=8916): success

  validating @0x1877200: dlv-registry.org DNSKEY: signed by trusted key; marking as secure

  validator @0x1877200: dns_validator_destroy

    validating @0x1876a00: dlv-registry.org SOA: in fetch_callback_validator

    validating @0x1876a00: dlv-registry.org SOA: keyset with trust 7

    validating @0x1876a00: dlv-registry.org SOA: resuming validate

    validating @0x1876a00: dlv-registry.org SOA: verify rdataset (keyid=27467): success

    validating @0x1876a00: dlv-registry.org SOA: marking as secure

  validating @0x1877200: example.net.dlv-registry.org DLV: starting

  validating @0x1877200: example.net.dlv-registry.org DLV: attempting positive response validation

  validating @0x1877200: example.net.dlv-registry.org DLV: keyset with trust 7

  validating @0x1877200: example.net.dlv-registry.org DLV: verify rdataset (keyid=27467): success

  validating @0x1877200: example.net.dlv-registry.org DLV: marking as secure

  validator @0x1877200: dns_validator_destroy

  validating @0x186c400: example.net SOA: in dlvfetched: success

  validating @0x186c400: example.net SOA: DLV example.net found

  validating @0x186c400: example.net SOA: dlv_validator_start

  validating @0x186c400: example.net SOA: restarting using DLV

  validating @0x186c400: example.net SOA: attempting positive response validation

    validator @0x1876a00: dns_validator_destroy

  validating @0x1876200: dlv-registry.org DLV: in authvalidated

  validating @0x1876200: dlv-registry.org DLV: resuming nsecvalidate

    validating @0x1876a00: dlv-registry.org NSEC: starting

    validating @0x1876a00: dlv-registry.org NSEC: attempting positive response validation

    validating @0x1876a00: dlv-registry.org NSEC: keyset with trust 7

    validating @0x1876a00: dlv-registry.org NSEC: verify rdataset (keyid=27467): success

    validating @0x1876a00: dlv-registry.org NSEC: marking as secure

    validator @0x1876a00: dns_validator_destroy

  validating @0x1876200: dlv-registry.org DLV: in authvalidated

  validating @0x1876200: dlv-registry.org DLV: looking for relevant nsec

  validating @0x1876200: dlv-registry.org DLV: nsec proves name exists (owner) data=0

  validating @0x1876200: dlv-registry.org DLV: resuming nsecvalidate

  validating @0x1876200: dlv-registry.org DLV: nonexistence proof(s) found

  validator @0x1876200: dns_validator_destroy

  validating @0x186bc00: . NS: in dlvfetched: ncache nxrrset

  validating @0x186bc00: . NS: DLV not found

  validating @0x186bc00: . NS: marking as answer

  validator @0x186bc00: dns_validator_destroy

  validating @0x186bc00: example.net DNSKEY: starting

  validating @0x186bc00: example.net DNSKEY: looking for DLV

  validating @0x186bc00: example.net DNSKEY: plain DNSSEC returns unsecure (.): looking for DLV

  validating @0x186bc00: example.net DNSKEY: looking for DLV example.net.dlv-registry.org

  validating @0x186bc00: example.net DNSKEY: DLV example.net found

  validating @0x186bc00: example.net DNSKEY: dlv_validator_start

  validating @0x186bc00: example.net DNSKEY: restarting using DLV

  validating @0x186bc00: example.net DNSKEY: attempting positive response validation

  validating @0x186bc00: example.net DNSKEY: dlv_validatezonekey

  validating @0x186bc00: example.net DNSKEY: Found matching DLV record: checking for signature

  validating @0x186bc00: example.net DNSKEY: verify rdataset (keyid=17000): RRSIG failed to verify

  validating @0x186bc00: example.net DNSKEY: verify rdataset (keyid=49656): success

  validating @0x186bc00: example.net DNSKEY: marking as secure

  validator @0x186bc00: dns_validator_destroy

  validating @0x186c400: example.net SOA: in fetch_callback_validator

  validating @0x186c400: example.net SOA: keyset with trust 7

  validating @0x186c400: example.net SOA: resuming validate

  validating @0x186c400: example.net SOA: verify rdataset (keyid=17000): success

  validating @0x186c400: example.net SOA: marking as secure

  validator @0x186c400: dns_validator_destroy   

When using lookaside validation assessing the log output in case of corrupted zone data is a challenge. Below is the output of the validator when it tries to figure out if a query that returns a corrupted result is valid or not. The conclusion is reached in the last few lines.

  validating @0x186bc00: . NS: starting

  validating @0x186bc00: . NS: looking for DLV

  validating @0x186bc00: . NS: plain DNSSEC returns unsecure (.): looking for DLV

  validating @0x186bc00: . NS: looking for DLV dlv-registry.org

  validating @0x186bc00: . NS: DLV lookup: wait

  validating @0x1875200: corrupt.example.net A: starting

  validating @0x1875200: corrupt.example.net A: looking for DLV

  validating @0x1875200: corrupt.example.net A: plain DNSSEC returns unsecure (.): looking for DLV

  validating @0x1875200: corrupt.example.net A: looking for DLV corrupt.example.net.dlv-registry.org

  validating @0x1875200: corrupt.example.net A: DNS_R_COVERINGNSEC

  validating @0x1875200: corrupt.example.net A: covering nsec: trust 1

  validating @0x1875200: corrupt.example.net A: DLV lookup: wait

  validating @0x186c400: dlv-registry.org DLV: starting

  validating @0x186c400: dlv-registry.org DLV: attempting negative response validation

    validating @0x1876a00: dlv-registry.org SOA: starting

    validating @0x1876a00: dlv-registry.org SOA: attempting positive response validation

  validating @0x1877200: corrupt.example.net.dlv-registry.org DLV: starting

  validating @0x1877200: corrupt.example.net.dlv-registry.org DLV: attempting negative response validation

    validating @0x1877a00: dlv-registry.org SOA: starting

    validating @0x1877a00: dlv-registry.org SOA: attempting positive response validation

  validating @0x1878200: dlv-registry.org DNSKEY: starting

  validating @0x1878200: dlv-registry.org DNSKEY: attempting positive response validation

  validating @0x1878200: dlv-registry.org DNSKEY: verify rdataset (keyid=8916): success

  validating @0x1878200: dlv-registry.org DNSKEY: signed by trusted key; marking as secure

  validator @0x1878200: dns_validator_destroy

    validating @0x1876a00: dlv-registry.org SOA: in fetch_callback_validator

    validating @0x1876a00: dlv-registry.org SOA: keyset with trust 7

    validating @0x1876a00: dlv-registry.org SOA: resuming validate

    validating @0x1876a00: dlv-registry.org SOA: verify rdataset (keyid=27467): success

    validating @0x1876a00: dlv-registry.org SOA: marking as secure

    validator @0x1876a00: dns_validator_destroy

  validating @0x186c400: dlv-registry.org DLV: in authvalidated

  validating @0x186c400: dlv-registry.org DLV: resuming nsecvalidate

    validating @0x1877a00: dlv-registry.org SOA: in fetch_callback_validator

    validating @0x1877a00: dlv-registry.org SOA: keyset with trust 7

    validating @0x1877a00: dlv-registry.org SOA: resuming validate

    validating @0x1877a00: dlv-registry.org SOA: verify rdataset (keyid=27467): success

    validating @0x1877a00: dlv-registry.org SOA: marking as secure

    validator @0x1877a00: dns_validator_destroy

  validating @0x1877200: corrupt.example.net.dlv-registry.org DLV: in authvalidated

  validating @0x1877200: corrupt.example.net.dlv-registry.org DLV: resuming nsecvalidate

    validating @0x1877a00: example.net.dlv-registry.org NSEC: starting

    validating @0x1877a00: example.net.dlv-registry.org NSEC: attempting positive response validation

    validating @0x1877a00: example.net.dlv-registry.org NSEC: keyset with trust 7

    validating @0x1877a00: example.net.dlv-registry.org NSEC: verify rdataset (keyid=27467): success

    validating @0x1877a00: example.net.dlv-registry.org NSEC: marking as secure

    validator @0x1877a00: dns_validator_destroy

  validating @0x1877200: corrupt.example.net.dlv-registry.org DLV: in authvalidated

  validating @0x1877200: corrupt.example.net.dlv-registry.org DLV: looking for relevant nsec

  validating @0x1877200: corrupt.example.net.dlv-registry.org DLV: nsec range ok

  validating @0x1877200: corrupt.example.net.dlv-registry.org DLV: resuming nsecvalidate

  validating @0x1877200: corrupt.example.net.dlv-registry.org DLV: in checkwildcard: *.example.net.dlv-registry.org

  validating @0x1877200: corrupt.example.net.dlv-registry.org DLV: looking for relevant nsec

  validating @0x1877200: corrupt.example.net.dlv-registry.org DLV: nsec range ok

  validating @0x1877200: corrupt.example.net.dlv-registry.org DLV: nonexistence proof(s) found

  validator @0x1877200: dns_validator_destroy

  validating @0x1875200: corrupt.example.net A: in dlvfetched: ncache nxdomain

  validating @0x1875200: corrupt.example.net A: looking for DLV example.net.dlv-registry.org

  validating @0x1875200: corrupt.example.net A: DLV lookup: wait

    validating @0x1876a00: dlv-registry.org NSEC: starting

    validating @0x1876a00: dlv-registry.org NSEC: attempting positive response validation

    validating @0x1876a00: dlv-registry.org NSEC: keyset with trust 7

    validating @0x1876a00: dlv-registry.org NSEC: verify rdataset (keyid=27467): success

    validating @0x1876a00: dlv-registry.org NSEC: marking as secure

    validator @0x1876a00: dns_validator_destroy

  validating @0x186c400: dlv-registry.org DLV: in authvalidated

  validating @0x186c400: dlv-registry.org DLV: looking for relevant nsec

  validating @0x186c400: dlv-registry.org DLV: nsec proves name exists (owner) data=0

  validating @0x186c400: dlv-registry.org DLV: resuming nsecvalidate

  validating @0x186c400: dlv-registry.org DLV: nonexistence proof(s) found

  validator @0x186c400: dns_validator_destroy

  validating @0x186bc00: . NS: in dlvfetched: ncache nxrrset

  validating @0x186bc00: . NS: DLV not found

  validating @0x186bc00: . NS: marking as answer

  validator @0x186bc00: dns_validator_destroy

  validating @0x186bc00: example.net.dlv-registry.org DLV: starting

  validating @0x186bc00: example.net.dlv-registry.org DLV: attempting positive response validation

  validating @0x186bc00: example.net.dlv-registry.org DLV: keyset with trust 7

  validating @0x186bc00: example.net.dlv-registry.org DLV: verify rdataset (keyid=27467): success

  validating @0x186bc00: example.net.dlv-registry.org DLV: marking as secure

  validator @0x186bc00: dns_validator_destroy

  validating @0x1875200: corrupt.example.net A: in dlvfetched: success

  validating @0x1875200: corrupt.example.net A: DLV example.net found

  validating @0x1875200: corrupt.example.net A: dlv_validator_start

  validating @0x1875200: corrupt.example.net A: restarting using DLV

  validating @0x1875200: corrupt.example.net A: attempting positive response validation

  validating @0x186bc00: example.net DNSKEY: starting

  validating @0x186bc00: example.net DNSKEY: looking for DLV

  validating @0x186bc00: example.net DNSKEY: plain DNSSEC returns unsecure (.): looking for DLV

  validating @0x186bc00: example.net DNSKEY: looking for DLV example.net.dlv-registry.org

  validating @0x186bc00: example.net DNSKEY: DLV example.net found

  validating @0x186bc00: example.net DNSKEY: dlv_validator_start

  validating @0x186bc00: example.net DNSKEY: restarting using DLV

  validating @0x186bc00: example.net DNSKEY: attempting positive response validation

  validating @0x186bc00: example.net DNSKEY: dlv_validatezonekey

  validating @0x186bc00: example.net DNSKEY: Found matching DLV record: checking for signature

  validating @0x186bc00: example.net DNSKEY: verify rdataset (keyid=17000): RRSIG failed to verify

  validating @0x186bc00: example.net DNSKEY: verify rdataset (keyid=49656): success

  validating @0x186bc00: example.net DNSKEY: marking as secure

  validator @0x186bc00: dns_validator_destroy

  validating @0x1875200: corrupt.example.net A: in fetch_callback_validator

  validating @0x1875200: corrupt.example.net A: keyset with trust 7

  validating @0x1875200: corrupt.example.net A: resuming validate

  validating @0x1875200: corrupt.example.net A: verify rdataset (keyid=17000): RRSIG failed to verify

  validating @0x1875200: corrupt.example.net A: failed to verify rdataset

  validating @0x1875200: corrupt.example.net A: verify failure: RRSIG failed to verify

  validating @0x1875200: corrupt.example.net A: no valid signature found

  validator @0x1875200: dns_validator_destroy   

1.6 Some Troubleshooting Tips

Suppose that you have configured a trust anchor and you are experiencing problems. For instance, your nameserver returns “SERVFAIL” for particular queries. Well, “SERVFAIL” is the default return code that a validating nameserver returns when it flags data as being bogus. Bogus data can be caused by two things. Either you are under attack or you experiencing a configuration error either by the operator of one of the zones in the chain of trust or by the operator of the validating recursive nameserver.

In addition to looking at the logs there are a number of tools at your disposal (see III). To assess if problems occur because of misconfiguration, or bugs, in you validating nameserver, or because of problems with the signed zones you will need a troubleshooting strategy.

One of the approaches you could take is to first use drill (see 6) or dig (see 7) to perform a ’sigchase’ or a ’trace’ with a key copied to your local file system, circumventing you validating recursive nameserver. In that way you will be able to check if the chain of trust can actually be built from the data. Make sure you use the correct trust-anchor when tracing data.

When you have verified that the chain of trust can be build from the data in the DNS it is time to troubleshoot the validating nameserver. This is easy when you have access to the log files but may be more troublesome if you don’t. You could use dig to query the validating nameservers with and without the +cd flag. That flag sets a bit in the query that instructs the nameserver not to perform validation. When the individual pieces in the chain of trust (drill returned those when using the trace option) you may be able to find inconsistencies that indicate that an expired trust anchor has been configured. You start by querying the DNSKEY RRset for which you assume there is a trust-anchor considered and work your way down. Or, alternatively, you query for the data you were looking for, use the data in the RRSIG RR to find for which DNSKEY RR to query, then query for a DS RR at the same name and work your way up (similar to the ’sigchase’ in drill).

While troubleshooting there are a number of failures that are easily introduced. Take the following example.

In his ISP column [876], Geoff Huston documented his experiences as an early deployer. He blindly configured a trust-anchor for the “nlnetlabs.nl” zone. While this zone was signed it was done in an experimental setup whereby not all servers for the zone were configured with the same version of the protocol. In this case one of the servers would not provide RRSIGs with the answer, something which may give rise to re-occurring but hard to predict failures.

There are two things to learn from this: Never blindly configure trust anchors in validating resolvers and make sure that when you serve zones all your servers conform to the DNSSEC protocol specification.

Another failure is that one of the RRsets in the chain of trust has expired signatures. Check this by looking at the date fields in the RRSIG RRs.

More problematic to find may be a rollover, where DNSKEY RRs or RRSIG RRs have been removed to early so that there is an inconsistency between data in cache and data that needs to be validated (also see section 4). Using the +cd to with dig and looking at the TTLs might help to distinguish if you are trying to validate RRSIGs for which there are no DNSKEYs available (or vice versa).

2 Securing a DNS zone

2.1 Introduction

If a zone has been signed and its key has been configured in a validating recursive name server we usually refer to it as being an ”island of security”. It apparently does not have a secured parent and stands alone in the sea of other unsecured domains. Usually creating an ”island of security” is the first step to becoming part of the secure DNS. The ”island of security” will remain ”insecure” for resolvers that have no trust anchor configured for the domain.

If a zone owner decides to create ”an island of security” she will sign her zones and distribute the ”secure entry points” to the system administrators that want to validate her zone data. Once the island of security has been set up the island can become part of the secure tree by exchanging the ”secure entry point” with the parent.

After creation of the key-pairs used for signing and validation we want to sign the zone data for our own organisation (e.g. example.net.) and configure the caching forwarders on our organisations network to validate data against the public key of our organisation.

In the text below, we assume that your organisation’s domain names are maintained in one zone. If domain name administration is delegated to sub-zones, see section Chapter 3, “Delegating of signing authority; becoming globally secure”.

Signing the zone data is the task of the zone administrator, configuring the caching forwarder is a task of system administrators.

The examples are based on the example zone in section Figure 7.

2.2 Configuring authoritative servers

All the authoritative servers will need to be configured to deal with the DNSSEC protocol. How this is done for BIND is explained in AppendixA. The essential steps are compiling bind with openssl and enabling dnssec through the use of the dnssec-enable yes; directive in the options section of named.conf.

That is all there is to it.

2.3 Creating key pairs

2.3.1 Key Maintenance Policy

Before generating keys, you will need to think about your key maintenance policy. Such policy should address

  • What will be the sizes of your keys?
  • Will you separate the key- and zone-signing keys functionality?
  • How often will you roll the keys?
  • How will system administrators that intend to use your zone as a trust anchor get hold of the appropriate public key and what mechanism will you provide to enable them to validate the authenticity of your public key?
  • How will you signal a key rollover or how can you make sure that all interested parties are aware of a rollover?

Some of these issues may be easy to address. For example, your organisation may have established mechanisms to distribute the public keys, there may be obvious ways to publish an upcoming rollover such as the possibility of publishing the event in a corporate newspaper. Alternatively, it may be possible to notify all relevant parties by mail when a corporate X.509 hierarchy is available for e-mail validation.

Key- and zone-signing keys. The author thinks it is good practise to use zone-signing keys and key-signing keys (also see Chapter 4, “Rolling keys”). The key-signing keys are usually the first keys from your zone that are used to build a chain of authority to the data that needs to be validated. Therefore, these keys are often called a secure entry point key (or SEP key). These SEP keys are the ones that you should exchange with your parents or that validating resolvers configure as their trust anchors.

Throughout this document we assume that you use separate key- and zone-signing keys and that the key-signing keys are exclusively used as secure entry point keys and can be identified by the SEP[10] bit in the flag field; the flag field is odd.

2.3.2 Creating the keys


  Usage:

      dnssec-keygen -a alg -b bits -n type [options] name

  

  Version: 9.4.1-P1

  Required options:

      -a algorithm: RSA | RSAMD5 | DH | DSA | RSASHA1 | HMAC-MD5 | HMAC-SHA1 | HMAC-SHA224 | HMAC-SHA256 |  HMAC-SHA384 | HMAC-SHA512

      -b key size, in bits:

          RSAMD5: [512..4096]

          RSASHA1: [512..4096]

          DH: [128..4096]

          DSA: [512..1024] and divisible by 64

          HMAC-MD5: [1..512]

          HMAC-SHA1: [1..160]

          HMAC-SHA224: [1..224]

          HMAC-SHA256: [1..256]

          HMAC-SHA384: [1..384]

          HMAC-SHA512: [1..512]

      -n nametype: ZONE | HOST | ENTITY | USER | OTHER

      name: owner of the key

  Other options:

      -c <class> (default: IN)

      -d <digest bits> (0 => max, default)

      -e use large exponent (RSAMD5/RSASHA1 only)

      -f keyflag: KSK

      -g <generator> use specified generator (DH only)

      -t <type>: AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF (default: AUTHCONF)

      -p <protocol>: default: 3 [dnssec]

      -s <strength> strength value this key signs DNS records with (default: 0)

      -r <randomdev>: a file containing random data

      -v <verbose level>

      -k : generate a TYPE=KEY key

  Output:        K<name>+<alg>+<id>.key, K<name>+<alg>+<id>.private


Figure 6: dnssec-keygen arguments


dnssec-keygen is the tool that we use to generate key pairs. The arguments that we have to provide dnssec-keygen are shown in Figure 6.

The output can be found in two files. The name of the files contain relevant information:

Kdomain_name+algorithm_id+key_id.extension

The domain_name is the name specified on the command line. It is used by other BIND DNSSEC tools, if you use a different name from the domain name, you might confuse those tools. The algorithm_id identifies the algorithm used: 1 for RSAMD5, 3 for DSA, 5 for RSASHA1 and 54 for HMAC-MD5 (TSIG only). The key_id is an identifier for the key material. This key_id is used by the RRSIG Resource Record. The extension is either key or private, the first is the public key, the second is the private key.

We create an RSASHA1 zone-signing key pair for example.net:

  

  

  # dnssec-keygen -r/dev/random  -a RSASHA1 -b 1024 -n ZONE example.net

  Kexample.net.+005+17000   

Because of the considerations in Section 2.3.1 you will also need to create SEP keys. Create keys with the SEP bit set by specifying the -f KSK flag with dnssec-keygen.

  # dnssec-keygen -r/dev/random  -f KSK -a RSASHA1 -b 1280  -n ZONE example.net

  Kexample.net.+005+49656   

Lets have a look at the content of these files7

  cat Kexample.net.+005+17000.key

  example.net. IN DNSKEY 256 3 5 (

              AQPI4+0M1V055RS2Hqv+8w8V20Dh+SQmFzHQtZMuzLH3UxWE0GmG5Gfj

              ijandJeAZTKLpERXB6RfHTHGG8lD3IO1azWN6DiVFEVzgr0otAdDonfY

               +oEsRw== )

     

The public key (.key extension) is exactly as it appears in your zone file. Note, that the TTL value is not specified. This key has a ”flag” value of 256. Since this value is an even number, the key is not marked as a SEP key and should be used for zone-signing.

The private key (.private extension) contains all the parameters that make an RSASHA1 private key. The private key of a RSA key contains different parameters to DSA. Here is the private key (with base64 material truncated):

  cat Kexample.net.+005+17000.private

  Private-key-format: v1.2

  Algorithm: 5 (RSASHA1)

  Modulus: yOPtDNVdOeUUth6r/vMPFdtA4fkkJhcx0LWTLsyx91MVhNBphu...

  PublicExponent: Aw==

  PrivateExponent: he1Iszjo0UNjJBRyqfdfY+eAlqYYGWTL4HkMyd3L+j...

  Prime1: +X0kNW1JrepBnVw5o9fDUyWAT5zqxKt0YR4vJZ19991tLZAmdO4...

  Prime2: ziIX5qfpZGBuzfd847TqtDfYcwv5UfUrPAIa/11g3leUUNERmsB...

  Exponent1: plNtePOGc/GBE5LRF+Us4hkANRNHLcei62l0w75T+pOeHmAZ...

  Exponent2: iWwP7xqbmEBJ3qT97SNHIs/logf7i/jHfVa8qj5AlDpi4Ith...

  Coefficient: rmmgD9P7/ywQJ4F0epdGqOUoQZmqrPQsraDTD8vkU1wLju...   

This private key should be kept secure8 i.e. the file permissions should be set so that the zone administrator will be able to access them when a zone needs to be signed. The BIND tools will, by default,9 look for the keys in the directory where signing is performed (see Section 2.4), that might not be the most secure place on your OS.

2.4 Zone-signing

When you create key pairs, you should include them in your zone file. Refer to the example in Figure7, where we use the $include directive to include the keys. We increase the serial number in the SOA record before signing.

In the example below we will use the RSASHA1 type keys for zone and key-signing keys.


  ; example.net zone

  ;

  $TTL 100

  $ORIGIN example.net.

  @                       100     IN      SOA     ns.example.net. (

                                                  olaf.nlnetlabs.nl.

                                                  2002050501

                                                  100

                                                  200

                                                  604800

                                                  100

                                                  )

  

  

                          NS              ns.example.net.

  ns.example.net.         A               192.168.2.203

  

  a                      A               192.168.2.1

  b                      A               192.168.2.2

  

  

  *                      A               192.168.2.10

  b.a                    A               192.168.2.11

  

  

  ; These are the keys that need to be publised in the DNSKEY RRset

  ;

  $include Kexample.net.+005+17000.key    ; ZSK

  $include Kexample.net.+005+49656.key    ; KSK   


Figure 7: example.net example zone


Once the key is included in the zone file we are ready to sign the zone using the dnssec-signzone tool (see Figure 8 for all the arguments). We use the -o flag to specify the origin of the zone; by default the origin is deduced from the zone file name.

With the ’-k key_name’ we specify which key is to be used as the key-signing key. That key will only sign the DNSKEY RR set in the apex of the zone. The keys that come as arguments at the end of the command are used to sign all the RR data for which the zone is authoritative. If you do not specify the keys, BIND will use the ones for which the public keys are included in the zone and use the SEP flag to distinguish between key- and zone-signing keys.

In practise you would not want to rely on the default, since in key rollover scenarios you will have a public key in your zone file but you would not want to use that for zone-signing (in order to avoid double signatures and therefore longer signature generation times and more resource consumption on your name server). Below is the command issued to sign a zone with the 49656 key as key-signing key and the 17000 key as zone-signing key.

  /usr/local/sbin/dnssec-signzone  \

     -o example.net  \

     -k Kexample.net.+005+49656 \

     db.example.net \

     Kexample.net.+005+17000.key   

The signed zone file is reproduced in figure 2.4 . Note that the apex DNSKEY RRset is the only RRset with two signatures, made with the zone- and key-signing keys. The other RRsets are only signed with the zone-signing keys.

The signing process completed the following:

  • Sorted the zone in ’canonical’ order10.
  • Inserted NSEC records for every label.
  • Added the key-id as a comment to each DNSKEY-record.
  • Signed the DNSKEY RR set with two keys; the key-signing key and the zone-signing key.
  • Signed the other RRs with the zone-signing key.
  • It created two files, dsset-example.net and keyset-example.net. These two files are relevant when building a chain of trust. Per default the files are created in the ’current directory’ i.e. the directory in which you ran thednssec-signzone command, but when specifying the -d, with its directory, then the files end up there.

The signatures were created with a default life time of 30 days from the moment of signing. Once signatures have expired data can not be validated and your zone will marked ’bogus’. Therefore you will have to re-sign your zone within 30 days. Zone re-signing is discussed below.

The signed zone is stored in db.example.net.signed, make sure you have configured named to use this file to serve the zones from.


  Usage:

   dnssec-signzone [options] zonefile [keys]

  

  Version: 9.4.1-P1

  Options: (default value in parenthesis)

   -c class (IN)

   -d directory

   directory to find keyset files (.)

   -g: generate DS records from keyset files

   -s [YYYYMMDDHHMMSS|+offset]:

   RRSIG start time - absolute|offset (now - 1 hour)

   -e [YYYYMMDDHHMMSS|+offset|"now"+offset]:

   RRSIG end time  - absolute|from start|from now (now + 30 days)

   -i interval:

   cycle interval - resign if < interval from end ( (end-start)/4 )

   -j jitter:

   randomize signature end time up to jitter seconds

   -v debuglevel (0)

   -o origin:

   zone origin (name of zonefile)

   -f outfile:

   file the signed zone is written in (zonefile + .signed)

   -I format:

   file format of input zonefile (text)

   -O format:

   file format of signed zone file (text)

   -N format:

   soa serial format of signed zone file (keep)

   -r randomdev:

   a file containing random data

   -a: verify generated signatures

   -p: use pseudorandom data (faster but less secure)

   -t: print statistics

   -n ncpus (number of cpus present)

   -k key_signing_key

   -l lookasidezone

   -z: ignore KSK flag in DNSKEYs

  Signing Keys: (default: all zone keys that have private keys)    keyfile (Kname+alg+tag)


Figure 8: dnssec-signzone arguments



  ; File written on Wed Aug 22 11:36:14 2007

  ; dnssec\_signzone version 9.4.1-P1

  example.net.            100     IN SOA  ns.example.net. olaf.nlnetlabs.nl. (

                                          2002050501 ; serial

                                          100        ; refresh (1 minute 40 seconds)

                                          200        ; retry (3 minutes 20 seconds)

                                          604800     ; expire (1 week)

                                          100        ; minimum (1 minute 40 seconds)

                                          )

                          100     RRSIG   SOA 5 2 100 20070921083614 (

                                          20070822083614 17000 example.net.

                                          U9hMfeJiAs6aNn7bj++g1FDVslHoTfvMCXMB

                                          y94EwaJMwKsukQ+pHUheStvxF4iksEOmcV0v

                                          ab2ZuwAazATZLzsWfjn4RbcM7U9EE3WQoaiT

                                          AWuADMM8OGPDX1lR5Ynk4c9bpL5MNKSd/u9G

                                          AOvceMDEjGFkebgBKWS9Z/PtAA0= )

                          100     NS      ns.example.net.

                          100     RRSIG   NS 5 2 100 20070921083614 (

                                          20070822083614 17000 example.net.

                                          rOzRinjHQzWqNvLUhzk/oXlyx59kyZf0zV5U

                                          MF+HzWxIlGHZtYWOJGE09sibWPl8L9k6/JbX

                                          dsWdPKiyNn5MvCZ+y9BdmuFVUW305SXiwynG

                                          /vzZW6UdC/rmQPCY7MP8uyUaHX/POPVtSIkb

                                          K75G1a4jKMWWb1qcqb2IiHo/2VQ= )

                          100     NSEC    *.example.net. NS SOA RRSIG NSEC DNSKEY

                          100     RRSIG   NSEC 5 2 100 20070921083614 (

                                          20070822083614 17000 example.net.

                                          LXBHKZzPLfN7UxmsUnbx1gtUXxgHuTF6mpio

                                          mfJpTA2+g4vXmL4T0PkLcgob1TlnwsMtrH4f

                                          h7+HnNmOFEe+kqbXDa+tcCm6PtVu7TqEBO2x

                                          IIew271xiqS+Ia4f9ksPWF+pD6c4Z3SnuEwL

                                          /0ta6G/AupVD2sX7urHD0As2auY= )

                          100     DNSKEY  256 3 5 (

                                          AQPI4+0M1V055RS2Hqv+8w8V20Dh+SQmFzHQ

                                          tZMuzLH3UxWE0GmG5GfjijandJeAZTKLpERX

                                          B6RfHTHGG8lD3IO1azWN6DiVFEVzgr0otAdD

                                          onfYF8gUT03ZnRcXlkJk41h12NOfq6rkODaF

                                          nfMHCppI3WZ/MJqe+9hLJtis+oEsRw==

                                          ) ; key id = 17000

                          100     DNSKEY  257 3 5 (

                                          AQOzgs4qea+ImJ1OCworkabHqFnvPKybVT7b

                                          nDIkJ2HvXWslbwNWJ66Ox3N6ftpCTc9wWBMw

                                          5+xOh7ilTwFPruMa2gURwEywZaMG9ipILOXm

                                          KO4a5I+8R2QTH4BM0WaIKnv5jCHose/l9LL3

                                          Y8MApsjP6gOWNM8b9aVTjBFnf0xEF7sOSBBB

                                          E4G2/og5Fr+H8DYaotqgJ3nrzRfYA0gSXwwb

                                          ) ; key id = 49656

                          100     RRSIG   DNSKEY 5 2 100 20070921083614 (   


Figure 9: Example of a signed zone file



                                          20070822083614 17000 example.net.

                                          LXLxA/ECoylvwW2yo8D9DNaMZ59PBS+lXDAF

                                          PJg19e935p7lr8tLtBmxhhMUctcfANobkBA9

                                          IJZRXD/hCCxzq6yEtVeWPyCc2hX0ZlV5PtAM

                                          bmTOWYFebEta9oaFUrC5qop+S28Di62bfclD

                                          FgqnCPOPZkFD3ueCqlBdbtV3TVo= )

                          100     RRSIG   DNSKEY 5 2 100 20070921083614 (

                                          20070822083614 49656 example.net.

                                          SWlHzmbvNGNsBGlqdx/K7RF3FMMMRKzkFKok

                                          XeOH82lm/apBjBQ5J+IwModHCfDtWWEu/QLw

                                          areD3iDGNy3rk530CGtYeRomqiNb/Xrv6X0v

                                          n/8krbcV/6QxNwmlPs1cBC84dXmaOQ5jttOJ

                                          mBKj9o9I+sjdujp6nxb3emsnTVmNK+Siv78k

                                          mBdTJgnG6rNCxwfNJMOa1+3FBNx6HfuwKg== )

  *.example.net.          100     IN A    192.168.2.10

                          100     RRSIG   A 5 2 100 20070921083614 (

                                          20070822083614 17000 example.net.

                                          VVMxoTePJsLt/ZaTC9zpMySxWtNcz+R7RuIM

                                          zQSpEPSlm9wF1bApKNJC9xf1kUWFUmmN+cXj

                                          IsGrfMB4JW1/e+HVMRfIibzIcbQg3xmt42eo

                                          qudbBFgjgTUpjNj6HEYywPqUecFAD8TLLL9B

                                          vHx0HwlRFnxSGzO0f/1s4NQWmiY= )

                          100     NSEC    a.example.net. A RRSIG NSEC

                          100     RRSIG   NSEC 5 2 100 20070921083614 (

                                          20070822083614 17000 example.net.

                                          lKGp1n+j6a65GPgvsgKPohZH8ITlEVcYtdKe

                                          SUfWsEWe+Fm0h6dfTvRQb2ylqIsPTMjzIJXS

                                          088lKhUX5emSV7Pp9/elY8h0E6cXRdrzEJKk

                                          Jhh1fdDG4caGu6yHAaoAotI1Mo6yrL/Kr+wH

                                          mzGd+wSB3r3/GYTZsDqDPp1aah8= )

  a.example.net.          100     IN A    192.168.2.1

                          100     RRSIG   A 5 3 100 20070921083614 (

                                          20070822083614 17000 example.net.

                                          H81aKqnGh2+Q7R7vA+O1Eepwn/5AnjDJGHl+

                                          yCU7uf+zgfI28d/bp23aJROzZABq04EBdc7v

                                          48cqEf4jcpwgHykW4LRgy9o3c162RWaDoRrX

                                          oWHubYHJU6HEY69Pl7pbD4ryz3itmghYUlwz

                                          15nJ5wVQjYSJgMOcZ8MpHO20HzU= )

                          100     NSEC    b.a.example.net. A RRSIG NSEC

                          100     RRSIG   NSEC 5 3 100 20070921083614 (

                                          20070822083614 17000 example.net.

                                          iiYhMLbmgdunr/HrhcCRZ+0COsJsFe7/9BNN

                                          WWwjgyZfFvhAnxak5EFxsB31jbT52hsLUsn9

                                          XQNoBcWaZgHjnkrEgw+2UyeNOOSG8nNPpDMw

                                          UF4FVBBS3PE2HCJ6EhtJzm21yWvAA2nkcxI4

                                          8b+Vrv2C/HoZFXZ6iWjsXWDfiDI= )

  b.a.example.net.        100     IN A    192.168.2.11

                          100     RRSIG   A 5 4 100 20070921083614 (

                                          20070822083614 17000 example.net.

                                          bVs86Y1RTYaDs0PbbnAifV4qKsxjhfC9hSCA   


Figure 9: continued



                                          pMxWIdaaCl8eOhooY7NVc38TqLSN2mTPdTU8

                                          WRU0t9iXXfqMlbdzVbCKgW4HPpEilCjABo1M

                                          U3o0vpZagr8odp9Q6Oxlb1MntSA= )

                          100     NSEC    b.example.net. A RRSIG NSEC

                          100     RRSIG   NSEC 5 4 100 20070921083614 (

                                          20070822083614 17000 example.net.

                                          eIeNU2T4VFcdZPEeWRlup2TRP51EQbVNkvnu

                                          /mexajPrqbnbfq1JV3EnIMszE+RSXOMwJ+OU

                                          kMUAhKyta5PhnnDfbwOrfTrD/z8DOcd13bQv

                                          6NqRaPVUolObj7OrRBH+iZBedLBG8P3aPgsb

                                          6RfRk9CKE1eigygUg7rspISmjc4= )

  b.example.net.          100     IN A    192.168.2.2

                          100     RRSIG   A 5 3 100 20070921083614 (

                                          20070822083614 17000 example.net.

                                          PePJMo5cgNumk1lGVCjl0iG/fxNxyry/Fzfz

                                          0wiiWj5T0qHMDMCeBr99IisPo5NfqkXFxA6i

                                          uK46Hflaja0AvY151WN186bE/zZh/LoT6CZu

                                          jFI21bOpL9+AegQLovjW41MV4aXHWu6a2gzU

                                          cikVYyJ377g5yTndy/dIJFTkUZ4= )

                          100     NSEC    ns.example.net. A RRSIG NSEC

                          100     RRSIG   NSEC 5 3 100 20070921083614 (

                                          20070822083614 17000 example.net.

                                          rK7hoZHGtTFuzep/yoh4QbQDSFxo20mC7F+U

                                          IEm6CEgfrli9q1yL58Ikuxgg9BcahKI/QGup

                                          ukfqo9kVRqspojtH7cUqRyYPr7m7WUDfNimn

                                          doYZ6/99tb4cXFa0WS3wAPwPCE3GCKslZNbH

                                          PMGP59PQIPseqsNIDc0toQxxdpI= )

  ns.example.net.         100     IN A    192.168.2.203

                          100     RRSIG   A 5 3 100 20070921083614 (

                                          20070822083614 17000 example.net.

                                          oQIH3uWW4J8DmgRZE+9Pp5yPzL0zTxXTVM0/

                                          BKFoKHfrt4ujKhySWV0L2v7lwjFG3N7G9c4n

                                          4oweuTHQlKkzM+jiX2j3GFDdJdJEVQvh0Y3p