DNSSEC: Create DS RRs Using Pencil and Paper Shell


When setting up DNSSEC for your domain, after you signed the zone, you need to generate appropriate DS RRs and report their parameters to your domain name registrar.

On this page you can find a very simple, portable script that generates DNSSEC DS RRs from a zone file that contains DNSSEC DNSKEY RRs. The script is signed with my PGP key.

DS RRs created by this script pass validation successfully.

The script is very easy to use: all it expects is the (signed) zone file on its standard input. The script generates two (one using SHA-1 and another using SHA256) commented DS RRs that contain everything that you need when configuring DNSSEC using your domain name registrar's control panel. The script runs on OpenBSD (using its ksh(1)) and on Linux (GNU Bash and Dash are supported).

The script is written as a companion to ldns-signzone(1), hence it accepts only single-line records and it accepts only numeric algorithm identifiers (algoritm mnemonics, as described in RFC 4034, appendix A.1, cannot be used). To appreciate the difference, please consider the following example given in RFC 4034, section 5.4, DS RR Example:

dskey.example.com. 86400 IN DNSKEY 256 3 RSASHA1 ( AQOeiiR0GOMYkDshWoSKz9Xz
                                                   fwJr1AYtsmx3TGkJaNXVbfi/
                                                   2pHm822aJ5iI9BMzNXxeYCmZ
                                                   DRD99WYwYqUSdjMmmAphXdvx
                                                   egXd/M5+X7OrzKBaMbCVdFLU
                                                   Uh6DhweJBjEVv5f2wwjM9Xzc
                                                   nOf+EPbtG9DMBmADjFDc2w/r
                                                   ljwvFw==
                                                 ) ;  key id = 60485
ldns-signzone(1) would format that record as one line of text (while removing parentheses and pasting together the pieces of the Base64 encoding of octets of the public key and replacing the mnemonic of the algorithm with its numeric identifier):
dskey.example.com. 86400 IN DNSKEY 256 3 5 AQOeiiR0GOMYkDshWoSKz9XzfwJr1AYtsmx3TG→
kJaNXVbfi/2pHm822aJ5iI9BMzNXxeYCmZDRD99WYwYqUSdjMmmAphXdvxegXd/M5+X7OrzKBaMbCVdFL→
UUh6DhweJBjEVv5f2wwjM9XzcnOf+EPbtG9DMBmADjFDc2w/rljwvFw== ;{id = 60485 (zsk), siz→
e = 1024b}
(Right arrow (→) at the end of each line above designates line wrapping on a terminal, not a newline character—I inserted those arrows followed by a line break manually for readability. Of course, both variants are a perfectly valid representation of a DNSKEY RR. You can download the second version for quick testing here.)

For this example, the script produces the following output:

;;; Key Tag: 60485
;;; Key Usage: ZSK
;;; DNSKEY Algorightm: RSASHA1 (5)
;;; RSA exponent: 3
;;; RSA modulus (1024 bits):
;;;     9e8a247418e318903b215a848acfd5f37f026bd4062db26c774c690968d5d56d
;;;     f8bfda91e6f36d9a279888f41333357c5e6029990d10fdf5663062a512763326
;;;     980a615ddbf17a05ddfcce7e5fb3abcca05a31b0957452d4521e838707890631
;;;     15bf97f6c308ccf57cdc9ce7fe10f6ed1bd0cc0660038c50dcdb0feb963c2f17
;;; SHA1 DS RR (algorithm: 1; digest: 2bb183af5f22588179a53b0a98631fad1a292118)
dskey.example.com. 86400 IN DS 60485 5 1 2bb183af5f22588179a53b0a98631fad1a292118
;;; SHA256 DS RR (algorithm: 2; digest: d4b7d520e7bb5f0f67674a0cceb1e3e0614b93c4f9e99b8383f6a1e4469da50a)
dskey.example.com. 86400 IN DS 60485 5 2 d4b7d520e7bb5f0f67674a0cceb1e3e0614b93c4f9e99b8383f6a1e4469da50a
(Note that, for the lack of a better idea, the script copies the values of TTL from the DNSKEY RR. If you are going to use DS RRs that the script generates with a name server, you might like to change them manually.)

Usually, the domain name registrar will be interesed in values of digests (as well as the corresponding digest algorithm identifiers) that the script produces for those DNSKEY RRs that describe key singing keys (KSKs).

The script has the followind dependencies: basename(1), uname(1), cat(1), hexdump(1), dd(1), cut(1), grep(1), tr(1), printf(1), openssl(1), and sed(1). In addition, on OpenBSD: sha1(1) and sha256(1), and on Linux: sha1sum(1), sha256sum(1), and echo(1) (when the script is processed by a shell other than GNU Bash).

Vadim Penzin, June 14th, 2019


I hereby place this article along with the accompanying source code into the public domain.
I publish this information in the hope that it will be useful, but without ANY WARRANTY.
You are responsible for any and all consequences that may arise as the result of using this information.