The PowerDNS authoritative name server is renown (and loved) for its support of a variety of database back-ends from which the server answers DNS queries. (If you’re new to PowerDNS, you might want to read about it: I have a chapter about this server in my book.)

When PowerDNS receives a DNS query, it checks the back-end database(s) you’ve configured and tries to obtain one or more records to reply to the query.

Say you’re using a relational database as a PowerDNS back-end (such as MySQL or PostgreSQL), to update your DNS data you typically use a database client (or a Web interface or custom-built utility) to perform SQL updates on your back-end database.

I suggested DNS UPDATE for PowerDNS quite a while ago, and Ruben d’Arco has taken upon himself the task of implementing support for RFC 2136 dynamic DNS updates in PowerDNS and, being a fan of dynamic DNS updates, I’ve been invited to test this new functionality. First off: it works. :-)

PowerDNS will accept a dynamic DNS update (currently from a configured IP address), and it then updates its back-end database, inserting, updating, or deleting database records accordingly. I modified my pdns.conf file and added the following statement, to enable DNS UPDATE from the specified address.

experimental-dnsupdate=yes
allow-dnsupdate-from=127.0.0.1

Alternatively, I can add a list of addresses on a per-domain basis to the domainmetadata table:

INSERT INTO domainmetadata (domain_id, kind, content) VALUES (3, 'ALLOW-2136-FROM', '127.0.0.1');

I use nsupdate to modify the zone a.aa on the server running on 127.0.0.1:

nsupdate <<!
server 127.0.0.1 53
zone a.aa.
update add ruben.a.aa. 120 TXT "Hello Ruben!"
update add ip.a.aa. 3600 A 10.0.12.1
update add ip.a.aa. 3600 AAAA fe80::20c:29ff:fef2:c247
send
!

PowerDNS processes the updates, and commits the result into the back-end database (MySQL in this particular instance). Here’s what I see when I look at the records table in the database:

*************************** 4. row ***************************
         id: 3206720
  domain_id: 3
       name: ip.a.aa
       type: A
    content: 10.0.12.1
        ttl: 3600
       prio: 0
change_date: NULL
  ordername: NULL
       auth: 1
*************************** 5. row ***************************
         id: 3206719
  domain_id: 3
       name: ip.a.aa
       type: AAAA
    content: fe80::20c:29ff:fef2:c247
        ttl: 3600
       prio: 0
change_date: NULL
  ordername: NULL
       auth: 1
*************************** 6. row ***************************
         id: 3206717
  domain_id: 3
       name: ruben.a.aa
       type: TXT
    content: "Hello Ruben!"
        ttl: 120
       prio: 0
change_date: NULL
  ordername: NULL
       auth: 1

and a DNS query to the server is correctly answered:

$ dig +norec @127.0.0.1 ruben.a.aa. txt
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; ANSWER SECTION:
ruben.a.aa.		120	IN	TXT	"Hello Ruben!"

TSIG

Support for authorizing updates with TSIG keys is mostly complete. Currently (2012-06-30) the updater’s IP address must be authorized by configuring allow-2136-from (either as configuration switch or in domainmetadata) and a key must be set. Whether or not the combined setting will remain is open for discussion; I personally think authorizing via TSIG key is sufficient.

I create a TSIG key with, say, the BIND utility, making a note of the key name (rk01 in this particular case) and the Base-64 blob. (I’ve chosen a very short key for clarity.)

$ dnssec-keygen -a hmac-md5 -b 128 -n HOST rk01
Krk01.+157+53162
$ cat Krk01.+157+53162.key
rk01. IN KEY 512 3 157 4imFLvMHKDmtc2oJldCaJg==

I then add both the key name and blob to the tsigkeys table, and associate that particular TSIG key with the domain, by adding a row to the domainmetadata table:

INSERT INTO tsigkeys (name, algorithm, secret) VALUES ('rk01', 'hmac-md5', '4imFLvMHKDmtc2oJldCaJg==');
INSERT INTO domainmetadata (domain_id, kind, content) VALUES (3, 'TSIG-ALLOW-2136', 'rk01');

Then I attempt the update, specifying the TSIG key to use, either as a filename or, like I do here, on the command line:

$ nsupdate -y 'hmac-md5:rk01:4imFLvMHKDmtc2oJldCaJg==' 
> server 127.0.0.1
> zone a.aa
> update add ts01.a.aa. 120 TXT "Ruben made TSIG-updates work!"
> send
> quit
$ 

At the moment, Dynamic DNS support for PowerDNS is experimental, but our friends at PowerDNS intend to merge the code into mainstream as soon as it’s ready. I’m hoping Ruben will have the inclination to add support for TSIG updates, which avoids having to authorize updates from a particular IP address. (TSIG support in PowerDNS was added a while back.) ( Of course SIG(0) and GSS-TSIG would also be nice to have … :-)

Great job, Ruben; thank you and keep up the good work!

DNS, DNSSEC, and PowerDNS :: 21 Jun 2012 :: e-mail