Providing a dynamic DNS service
(This blogpost is still work-in-progress)
Some months ago dyndns.org
had problems with their service, which caused me to
log into my dyndns.org
control panel to update my A record (keks.selfip.org
)
manually. Before that dyndns.org
made wildcard support a premium feature, so I
lost my wildcard entry when I updated the A record. I was seriously not amused.
I started to search for other dyndns providers, but did not find what I searched for, which is:
- Subdomain included
- Dynamic A records
- Support for AAAA records
- Support for wildcards
- All that for free
The nearest I got was freedns.afraid.org.
They lacked the wildcards
and imposed annoying limits (e.g. a maximum of 5 records). I managed to work
around this limits by tricking their system into accepting an external
nameserver for keks.upful.org. This nameserver (keks-ns1.upful.org
) is just a
simple dyndns-domain pointing to my computer. This gave me total control over
the keks.upful.org.
zone.
In theory this is a valid way to achieve the above mentioned goal. But, imho, my solution is a bit complicated. So I decided to make my nameserver useful for the public by providing a dyndns-service with the features I needed.
I probably won't be able to provide a user/noob-friendly service with 24/7 uptime (After all, I am hosting the nameserver on my desktop pc, using a DSL-connection that reconnects at least once every day) but I will see this as an opportunity to work out techniques to provide a DynDNS-service. This might be useful some day :-P.
Des Pudels Kern
My nameserver uses bind 9.8.0. named.conf
(excerpt):
key "keks.upful.org." {
algorithm hmac-md5;
secret "s7gf6s9d86g89s6fg78sd6==";
};
key "fred.keks.upful.org." {
algorithm hmac-md5;
secret "d6g9sd876g98d6sg876dfg==";
};
zone "keks.upful.org" IN {
type master;
file "pri/keks.upful.org.zone";
update-policy {
grant keks.upful.org. subdomain keks.upful.org. ANY;
grant fred.keks.upful.org. subdomain fred.keks.upful.org. ANY;
};
notify no;
};
The keys are generated using
$ dnssec-keygen -a HMAC-MD5 -b 128 -n host fred.keks.upful.org.
The secret (needed for the key
section of named.conf
) is saved in the
file Kfred.keks.upful.org.+157+16611.private:
$ cat Kfred.keks.upful.org.+157+16611.private
Private-key-format: v1.3
Algorithm: 157 (HMAC_MD5)
Key: d6g9sd876g98d6sg876dfg==
Bits: AAA=
Created: 20120328235137
Publish: 20120328235137
Activate: 20120328235137
The records can be updated using
$ nsupdate -v -k bind-dyndns/Kfred.keks.upful.org.+157+16611.key
> server localhost
> zone keks.upful.org
> update add fred.keks.upful.org. 300 A 23.23.23.23
> send
Updating of A records via GET request to a cgi-script
Interface:
- Choosen subdomain as HTTP-auth user
- nsupdate-key's secret as password (maybe hashed..)
- record to update as GET-parameter
A wget-invocation could look like this:
wget --user=fred.keks.upful.org --password=4242424242424242424242== \
http://keks.upful.org/dyndns/update/?eugene.fred.keks.upful.org.
Authentication is done by the httpd (.htaccess or similar)
The script does the following:
- searches for
$http_user.+*.key
in the key folder - optional: checks if the ip has changed, if not, exit
- calls nsupdate using the key to update the A record (see below)
- checks nsupdate's exit status (it has none?!)
- sends http response
- 200 OK: ip was updated
- 200 No change: ip did not change
- ...?
nsupdate input:
server localhost
zone keks.upful.org
update delete $domain A
update add $domain 300 A $http_remote_ip
send
The finished script can be found here.