When talking about performing dynamic DNS updates on your DNS servers the other day, I concentrated on using TSIG keys, but there are some disadvantages in using those:

  • A TSIG key is a symmetric key (or a shared key) that both parties (i.e. client and server) must know.
  • TSIG keys have to be configured in named.conf, which means that whenever the key is changed, you have to update your server’s configuration.
  • Most importantly perhaps, a client cannot change its key at will because of the first two reasons: she needs the cooperation of the server’s administrator to change the shared key.

SIG(0) keys are asymmetric key-pairs; there is a private key which must be known to the client, and a public key. Together, these form a SIG(0) key-pair. They can be of any of the asymmetric key algorithms (RSAMD5, RSASHA1, ECSDA, etc.). To create a SIG(0) key pair, I use the dnssec-keygen utility supplied as part of a BIND distribution. Note how I use the -C option to generate what is called a backward-compatible key; this omits all dates in the private key, and I can use the key file with Net::DNS, as I’ll show you in a moment.

dnssec-keygen  -C -a 13 -n HOST -T KEY jp.example
Generating key pair.
Kjp.example.+013+64258

Here again we see the filename prefix (Kjp.example.+013+64258) dnssec-keygen has created a .private and a .key file. The content of the .key file is a DNS resource record that goes in to the zone to be protected:

jp.example. IN KEY 512 3 13 cfBQzVgQHb8/DDaHL ... ULirdfNFvfZpYA==

When I’ve done that, I can configure my BIND name server as we discussed recently:

zone "example" IN {
      type primary;
      file "example";
    
      allow-update {
        key "jp.example.";
      };
};

Update 2021: nowadays I’d go with the much more granular update-policy which allows me to finely tune which key may update which records. For example, the key jp.example might be permitted to update TXT, A, and AAAA records in the hosts.example subdomain and update itself:

zone "example" {
   update-policy {
     grant "jp.example." subdomain hosts.example. TXT A AAAA;
     grant "jp.example." name jp.example. KEY;
   };
};

Note how the key name in the allow-update clause specifies the domain name I supplied during key generation. Also take note that the key itself isn’t in named.conf; it is in the zone. The client uses the private key (contained in the .private file) to sign update requests. I can use the nsupdate utility for performing dynamic updates, but I can also use Perl’s Net::DNS modules:

#!/usr/bin/perl

use strict;
use Net::DNS;
use Net::DNS::Update;
use Net::DNS::SEC;

my $zone = "example";

# Create the update packet.
my $update = Net::DNS::Update->new($zone);

# Add an A record for the name.
$update->push(update => rr_add("aa.$zone. 120 A 127.0.0.8"));

# Sign the update packet
$update->sign_sig0("Kjp.example.+013+64258.private");
 
# Send the update to the zone's primary.
my $res = Net::DNS::Resolver->new;
$res->nameservers('127.0.0.1');
 
my $reply = $res->send($update);
 
# Did it work?
if ($reply) {
     if ($reply->header->rcode eq 'NOERROR') {
         print "Update succeeded\n";
     } else {
         print 'Update failed: ', $reply->header->rcode, "\n";
     }
} else {
     print 'Update failed: ', $res->errorstring, "\n";
}

An important thing to remember is to not rename the K* files generated by dnssec-keygen; Net::DNS needs the filename to determine the algorithm and the key tag. So what do we now have? We have a BIND zone that can be remotely updated, but we have something else: the client (i.e. the owner of the private key) can generate a new key pair and update (i.e. replace) the key in the dynamic zone whenever she feels like it. (And, of course, if the update-policy on the server allows her to do that.) Compared with TSIG, SIG(0) offers the following advantages:

  • Only the client has to know the private key. The client can send the public key (in the DNS RR) to the server operator for first-time inclusion into the zone.
  • Divulging the key in the zone is not a problem because it is the public portion only.
  • Clients can dynamically update their keys because the public key is in the zone.

There is one disadvantage, though: SIG(0) is probably not as widely implemented as TSIG. In fact IIRC, ISC’s dhcpd server doesn’t support it.

DNS, CLI, BIND, and nsupdate :: 01 Dec 2010 :: e-mail