Benjamin Schieder


2014 May 07

I have long been using the free service that DynDNS provided. But feeling that a “” address looks kinda unprofessional I discontinued using that site for anything important and just used it every now and then to connect to my MythTV based video recorder to schedule a recording from afar.

When DynDNS announced the full stop of their free service, I was looking for an alternative. And I found it built into the functionality of bind, the DNS server software I am already using for all my other websites. Here’s how I set it up:

The first thing to realize is that the update works by using signing similiar to how GPG works for emails. Since this is a pretty simple setup, I used HMAC-MD5 keys:

dnssec-keygen -a HMAC-MD5 -b 512 -n USER $( echo "" | sed 's,[^a-zA-Z],.,g' )

This creates a public/private keypair called and The .key file is the public and the .private (surprise!) is the private key.

[08:09:15][root@pallas:/data/home/blindcoder]# cat IN KEY 0 3 157 Hb6pTgRDIQb5WgLwKgGZS+aeKa8t6CDL3c+xulZIvsjz6ba6yQQudyeh AgM/2DsX0mZID0oXUkCHCMddmncJhg==
[08:09:17][root@pallas:/data/home/blindcoder]# cat 
Private-key-format: v1.3
Algorithm: 157 (HMAC_MD5)
Key: Hb6pTgRDIQb5WgLwKgGZS+aeKa8t6CDL3c+xulZIvsjz6ba6yQQudyehAgM/2DsX0mZID0oXUkCHCMddmncJhg==
Bits: AAA=
Created: 20140507180728
Publish: 20140507180728
Activate: 20140507180728

No, you do not need to try, I created these keys purely for the sake of this blog entry.

I copied the public key to my homeserver and the Key: part of the private key got added to my named.conf file:

key {
	algorithm HMAC-MD5;
	secret "Hb6pTgRDIQb5WgLwKgGZS+aeKa8t6CDL3c+xulZIvsjz6ba6yQQudyehAgM/2DsX0mZID0oXUkCHCMddmncJhg==";

zone "" IN {
	type master; 
	file "";
	allow-update { key };

After restarting bind, this key would now be allowed to update the DNS zone of And I repeat: This is NOT my live configuration. So stop trying already!

On the client side I now have a very small shellscript to update the DNS entry of “” to a new IP address:


exec >> /var/log/ddns.log 2>&1

IP="$(curl -s"
if [ -z "${IP}" ] ; then
	echo "[$(date)] Could not get IP address from"
	exit 1;
read OLDIP < /var/run/ddns/oldip
if [ "${IP}" == "${OLDIP}" ] ; then
	echo "[$(date)] IP has not changed. Not updating."
	exit 0

[ -z "${tmp}" ] && exit 1
trap 'rm -f "${tmp}"' EXIT

cat > "${tmp}" <<<-EOF
update delete A
update add 3600 A

sed -e "s,,${IP},g" -i "${tmp}"

nsupdate -y "${tmp}"

exit 0

I run this script via a cronjob once an hour.



Tags: dyndns bind shellscript