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 his 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, or DSA). 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 DSA -b 1024 -n HOST -T KEY pc.sig0.aa
    Generating key pair...+.....................+++++++++++++++++++++++++++++++++++++++++++++++++++* ...............+.......+..+....+.+.....+.+.....+........+........+.........+.................+......+..+..+.+...........+.+.....+......+..........................+...+.........+...............+.+++++++++++++++++++++++++++++++++++++++++++++++++++* 

Here again we see the filename prefix (Kpc.sig0.aa.+003+04200); 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:

    pc.sig0.aa. IN KEY 512 3 3 CLbJ46RdXfSEY3pR+EJeNO ... gaNM

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

    zone "sig0.aa" IN {
      type master;
      file "master/sig0.aa";
      allow-update {
        key "pc.sig0.aa.";

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:

    use strict;
    use Net::DNS;
    use Net::DNS::Update;
    use Net::DNS::SEC;
    my $zone = "sig0.aa";
    # 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"));
    # Sign the update packet
    $update->sign_sig0( "Kpc.sig0.aa.+003+04200.private");
    # Send the update to the zone's primary master.
    my $res = Net::DNS::Resolver->new;
    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