AW: DDNS updates

Kleinfeld, Ralf Ralf.Kleinfeld at
Wed Aug 2 07:02:30 UTC 2006

Hi John,

thank you for the great explanation. Aboslutely sounds clear for me.

So, focusing on your remarks on the Windows deployment ... that's some
sort of my problem.

I would like to move using the ISC DHCP Server. But, there are lots of
locations where MS DHCP is running.

And there are lots of people traveling from one location to another. 
But they should all remain in the same domain.

An immidiate switch to a ISC DHCP-only network will not be possible. 
This means, there are instances (clients, MS DHCP server) which will
update the domain. 
When traveling to a location with an ISC DHCP server, I would like to
only have the ISC do the updates. This does not work, because it does
not touch the record, in regards of the missing TXT record.
So I would like to FORCE the ISC DHCP server doing the update although
the TXT record is missing.


-----Ursprüngliche Nachricht-----
Von: dhcp-users-bounce at [mailto:dhcp-users-bounce at] Im Auftrag
von John Hascall
Gesendet: Dienstag, 1. August 2006 17:14
An: dhcp-users at
Betreff: Re: DDNS updates 

> IIRC the update is done as :
>    If there is no A record, perform an update and skip to step 3.
>    If there is an A record and the TXT record matches, perform the update.
>    If the A record update succeeds, update the PTR record.
> The A record update is done as a conditional script
>    If <condition>
>    then
>      delete fqdn A
>      delete fqdn TXT
>      insert fqdn A ipaddr
>      insert fqdn TXT hash-value

Actually, it goes like this:

The dhcp server computes a unique hash (called "id" below).
The first thing DHCP sends is essentially a mini-program to the DNS server
(expressed in psuedo-code below):

    if (exists(fqdn, A, any) == FALSE) { add(fqdn, A, ip); add(fqdn, TXT,
id); }

if the DNS server returns "YXDOMAIN" (there was an fqdn A record) then DHCP
sends this mini-program:

    if (get(fqdn, TXT) == id) { delete(fqdn, A, any); add(fqdn, A, ip); }

if this fails (because there was no fqdn TXT record or it was there but was
not the same as id) then it concludes that the name is in use by somebody
else (and it checks for other odd failures of course).

if either the first or second DNS transactions above succeeded, then it
sends this mini-program:

    delete(ip, PTR, any); add(ip, PTR, fqdn);

Note that all the mini-programs are either completely successful or
completely unsuccessful -- the idea is that they can never half-complete
which would leave your DNS in an inconsistent state.

> >Furthermore, I have noticed that the dhcp server is NOT updating an A 
> >record, if the appropriate TXT record is missing. Is there a way to
> >the dhcp server to touch the record?
> No, this is a security mechanism - it prevents a malicious (or just
> ignorant) user setting their hostname to "server" and your important 
> server named "server" just disappears because the DNS has been 
> changed.

    Well, you can force it to update by computing and manually
    adding (vis the nsupdate program) a correct TXT record, but
    this is sort of ugly.   Or you can delete the A record manually.

We found one place where this can be a problem.  And to be honest, we are
bending dhcp a fair bit here.  Our users pretty much inisst that thier
machines have the same dns name regardless of whether they are using their
wired or wireless NICs (something to do with stupidity in Windows Active
Directory).  And, of course, Windows' use of dhcp client ids is also stupid
(so much so that we use the patch to ignore them entirely).  The means that
DHCP can update their DNS when they go from one NIC to the other because the
"id" in the text record is a hash of their NIC's mac address.

       machine bob gets IP using NIC 00:11:00:11:00:11
       so dhcp installs:
           bob A
           bob TXT hash(00:11:00:11:00:11)
  PTR bob

       bob switches to his wireless NIC (00:22:00:22:00:22) and gets
       do dhcp tries:
           if (exists(bob, A, any) == FALSE) {
               add(bob, A,; add(bob, TXT,
       which fails because (bob,A, does exist.

       so then it tries:
           if (get(bob, TXT) == hash(00:22:00:22:00:22)) {
               delete(bob, A, any); add(bob, A,; }
       which also fails because get(bob,TXT) == hash(00:11:00:11:00:11)

What we did was modify the second transaction to be:
           if (exists(bob, TXT, any)) {
               delete(bob, A, any); add(bob, A,; }

so that if *any* TXT record is there then DHCP feels ok replacing the A &
PTR records.  This works for us because:
   a) only DHCP ever puts in (fqdn,TXT,...) records, so any TXT
      record was put in by it.
   b) who can update our DNS servers is tightly controlled so
      no rogue agent can install a TXT record for mischief making

The lazy (i.e., no configfile option) implementation of this turns out to be
a two line change to the routine ddns_update_a in the common/dns.c file:

#ifdef  ANY_DHCID
        updrec -> r_data = (unsigned char *)0;
        updrec -> r_size = 0;
        updrec -> r_data = ddns_dhcid -> data;
        updrec -> r_size = ddns_dhcid -> len; #endif
        updrec -> r_opcode = YXRRSET;


More information about the dhcp-users mailing list