Since I own a domain and a bind9 DNS server, I wanted to setup hostnames that automatically update when my IP changes.
I started out with the instructions at:
http://dag.wieers.com/howto/bits/bind-ddns.php , but I had to make a few modifications.
(all the keys listed here are examples and not the real keys)
1. Generate the DNS keys
$ dnssec-keygen -a HMAC-MD5 -b 512 -n ZONE homedynamicdns
Khomedynamicdns.+157+01663
This creates two files, a .key and a .private. They have the same data, but in different formats.
2. Add the key to your named.conf, and give it access to modify your zone
key homedynamicdns {
algorithm hmac-md5;
secret "xGpyys6iQm+SeL1b40yU2LEqT88aRFv6kHExViocqHDEo8kexgf7HsyWCZ8fD+HvThNpCdW+O6Lpm76p4+lrSA==";
};
zone "dynamic.example.org" IN {
type master;
notify no;
file "dynamic.example.org.hosts";
allow-update { key homedynamicdns; };
};
3. Verify the key works
# nsupdate -d -k Khomedynamicdns.+157+01663
Creating key...
> server ns.example.org
> zone dynamic.example.org
> update add test.dynamic.example.org 60 A 127.0.0.1
> send
Sending update to x.y.z.m#53
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 24935
;; flags: ; ZONE: 1, PREREQ: 0, UPDATE: 1, ADDITIONAL: 1
;; ZONE SECTION:
;dynamic.example.org. IN SOA
;; UPDATE SECTION:
test.dynamic.example.org. 60 IN A 127.0.0.1
;; TSIG PSEUDOSECTION:
updatedns. 0 ANY TSIG hmac-md5.sig-alg.reg.int. ... NOERROR 0
Reply from update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 24935
;; flags: qr ; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 1
;; TSIG PSEUDOSECTION:
updatedns. 0 ANY TSIG hmac-md5.sig-alg.reg.int. ... NOERROR 0
The key here is that "status: NOERROR" If it shows any other statuses (NOTZONE, REFUSED, SRVERROR, ...) then check your nameserver logs.
4. setup an /sbin/send-new-ip script
Put your update key in /etc, and then create this script:
#!/bin/sh
KEY="/etc/Khomedynamicdns.+157+01663"
SERVER="ns.example.org"
ZONE="dynamic.example.org"
HOSTNAME="home-d.dynamic.example.org"
LOGFILE="/var/log/nsupdate.log"
IPADDR=$1
(
echo "$(date) Running $0 with arguments \"$*\""
echo "--------------"
cat <>$LOGFILE 2>&1
exit $RC
You can verify it works by running it and then checking the /var/log/nsupdate.log log file.
5. Create a /etc/dhclient-up-hooks script
I'm using dhclient as my DHCP client. My /sbin/dhclient-script calls /etc/dhclient-up-hooks on an IP change.
#!/bin/sh
(
if [ -n "$new_ip_address" ]; then
sleep 5 # wait for networking to finish coming up
/sbin/send-new-ip $new_ip_address
else
echo unknown IP address given >>/var/log/nsupdate.log
env >>/var/log/nsupdate.log
echo ============== >>/var/log/nsupdate.log
fi
) &
6. Add rules to selinux if you're using it.
I created the directory /etc/selinux/nsupdate and put the following files in it:
/etc/selinux/nsupdate/Makefile
all: nsupdate.pp
@echo load: semodule -i nsupdate.pp
nsupdate.pp: nsupdate.mod
semodule_package -o nsupdate.pp -m nsupdate.mod
nsupdate.mod: nsupdate.te
checkmodule -M -m -o nsupdate.mod nsupdate.te
/etc/selinux/nsupdate/nsupdate.te
module nsupdate 1.2;
require {
type var_log_t;
type dhcpc_t;
type ntpd_t;
class file append;
class file getattr;
}
allow dhcpc_t var_log_t:file getattr;
allow dhcpc_t var_log_t:file append;
allow ntpd_t var_log_t:file append;
This allows dhclient to write to the log file. Since this requires sync'ed clocks and my virtual machine's clock is all wrong, I added an NTP sync (not shown in the script above), which is what that ntpd_t allow line is for.
7. Compile selinux rules and add them to the running ruleset if needed
# make
checkmodule -M -m -o nsupdate.mod nsupdate.te
checkmodule: loading policy configuration from nsupdate.te
checkmodule: policy configuration loaded
checkmodule: writing binary representation (version 6) to nsupdate.mod
semodule_package -o nsupdate.pp -m nsupdate.mod
load: semodule -i nsupdate.pp
# semodule -i nsupdate.pp
8. Skip all the above steps and use the built-in TSIG support in dhclient. (I haven't done this part, but I get the impression it's possible)