My recipe for doing dynamic dns on my local network
When I used the nuclear option to deal with wireless script kiddies last week, part of the total thermonuclear war was to move all of the machines onto a private network. Since I didn't want to go out and redo my dns for the new IP addresses, I decided I would try to implement dynamic dns and have all of the machines, from minor servers to all of the windows (and, sooner or later, Mac) workstations, tell the dhcp server what their names were. The, um, simple way of doing this was to use the already written code that the ISC gives away without any (as they mention at every possible opportunity) support, so that's the approach I took.
The documentation for how to do this sucks. I mean it really sucks. So here's how I did it.
- The first thing is to upgrade the software to recent versions. I upped dhcpd to version 3.0.2 and named to 9.2.2. You need to build named with a really new version of openssl, so I upped openssl to version 0.9.7e, built that, then configureed named with --with-openssl=/usr/local/src/openssl-0.9.7e. I make installed everything, tweaked my system so that it would use the new and improved dhcp and named, and then went off to the races.
- In the dhcpd.conf manpage, it mentions using dnssec-keygen to generate md5 keys. The description is somewhat sketchy (dnssec-keygen looks at /dev/random to get random junk, and on a not-too-busy system this means that dnssec-keygen takes forever to generate a 128 bit key. I didn't want to wait, so I used /kernel as a source of random input. dnssec-keygen produces a private and public key, which for a md5 key are exactly the same. Grab the key (in the .private file, it's nicely labelled as Key:) and then you can throw away the public key file.
- dhcpd.conf is pretty simple. Sort of. Here's the one I use:
authoritative; ddns-update-style interim; # this has to be the same key as is used in named.conf key dns { algorithm HMAC-MD5.SIG-ALG.REG.INT; secret "Key: line goes here without the Key: part, of course"; }; zone pell.portland.or.us. { primary 127.0.0.1; key dns; } zone 5.0.10.in-addr.arpa. { primary 127.0.0.1; key dns; } subnet 10.0.5.0 netmask 255.255.255.0 { get-lease-hostnames true; do-forward-updates true; range 10.0.5.10 10.0.5.254; default-lease-time 32000; max-lease-time 32000; option nis-domain "PELL-AT-HOME"; option nis-servers 10.0.5.1; option routers 10.0.5.1; option time-servers 10.0.5.1; option domain-name "pell.portland.or.us"; option domain-name-servers 10.0.5.1,199.245.177.2; allow unknown-clients; }
I don't know if you need anything else, but the important part is that you have to make your dhcp authoritative for it to even work (dunno why), you need to tell it ddns-update-style interim; -- apparently the style they use before dhcp 3.0.2 isn't even supported any more, and interim is their way of saying "yup, we're going to change it again. Lucky you!". And I have to set the zone information up to tell dhcpd to ask named to please make updates to the given zones. (the pell.portland.or.us zone is what you'd expect, the 5.0.10.in-addr.arpa zone is the ip address -> name zone that you need to have both the name->ip and ip->name dns mappings.)
The allow unknown-clients line in the subnet section appears to be needed, but I'm not sure why.
- named.conf (if you build bind9 from sources, this will be in /etc. If you build bind9 from (shudder) BSD ports, it may be in /etc/named or it may be in /usr/local/etc -- I've taken to avoiding ports because they've falled prey to "new version disease" and will thus happily fill your system with 37,000 versions of every software package that each port needs), is, on the other hand, not quite so simple:
options { directory "/var/namedb"; }; key dns { algorithm HMAC-MD5.SIG-ALG.REG.INT; secret "ey: line goes here without the Key: part, of course"; }; logging { channel update_debug { file "/var/log/named.log"; severity debug 3; print-category yes; print-severity yes; print-time yes; }; category update { update_debug; }; }; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { dns; }; }; zone "." { type slave; file "root.db"; masters { 192.156.98.10; 199.245.177.2; }; }; zone "pell.portland.or.us" { type master; file "pell.portland.or.us"; allow-update { key dns; }; }; zone "5.0.10.IN-ADDR.ARPA" { type master; file "10.0.5.rev"; allow-update { key dns; }; }; zone "0.0.127.IN-ADDR.ARPA" { type master; file "localhost.rev"; }; zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.INT" { type master; file "localhost.rev"; };
Notice, first of all, the key dns section is exactly the same as the one in ?dhcpd.conf. You need this. You also need the controls line to set up a command pipe that dhcpd and any script kiddy that breaks onto your machine can use to add and delete dns records. You also need to do the allow-update lines on the zones that you mentioned in the dhcpd.conf file, so that these zones will know that dhcpd will be around to mess with them. Note that you can't do allow-update on a slave zone; since pell.portland.or.us/ is a real zone that serves real internet connected machines, I needed to hand-copy the zone over to downbelow and pretend to be a master.The logging is a complete waste of time. I put it in because the ISC documentation suggested it, but the only logging it puts in is "I'm adding an A record! I'm deleting an A record! I'm adding a RR! I'm deleting an RR! I'm erasing the root zone because I can!" without telling any details (like, oh, the name of the record) about the records it's adding or deleting.
- Windows is happy as a clam with this. Windows machines know what their names are and cheerfully announce those names when they ask for IP addresses. Unix machines (particularly ones that run dhclient, which sucks) think that if they tell you their machine name it will cause civilization to vanish, so you have to tell dhclient to send a particular hostname. Did I mention that dhclient sucks? Well, it does; if you're on machine foo, you can't tell it to send host-name, you need to tell it to send host-name "foo", which is pretty stupid. And on some of my freebsd machines, I need to duplicate that line in the dhclient configuration file because it doesn't think I'm being serious when I only put it in once.
One other fun Unix thing is that if you give a machine a name that's already in the dns, dhcpd's tiny brain will pop and it not only won't try to override that machine name (a good idea), it won't even bother to tell you why (not such a good idea.) It's almost as fun as when dhcpd reports "no hostname" for a dhcp request, and then sends back the request mentioning the hostname that was supplied.
Comments
Comments are closed
I have to admit that getting my new firewall configured to do dhcp and dns has been about the most frustrating thing I've done in a while :-( I read your and several other config "howto"s and I have everything working but ddns for my windows xp boxes. They get an address and are correctly configured domain, nameserver etc wise, but I cannot find them in my nameserver using dig, or nslookup or ping. Thanks for the howto... I think I'll just static ip these guys... wcn