Run your own DDNS updates for your home server

Update 28th Feb 2015: RFC 2136

I came across RFC 2136, which is ironically the same thing what I am describing below.

You can find here (taken from pfSense) a documentation how to set it up according to RFC 2136.


I managed to run my own nifty DDNS update service for/from my home server. Best is that you have a nameserver running with your own domain on it... I am using $DOMAIN as the main zone here.

Nameserver setup

You can either just have a specific entry like home.$DOMAIN or you can create a specific zone for doing your DDNS updates. I went with the latter, as I might want to put more in it in future. From a security point of view it doesn't matter, as you can restrict DDNS updates to specific records only, ie. don't won't allow access to the whole domain this way. And you grant access with a DDNS shared secret - you won't do it based on IP addresses, do you?

So I guess creating zones with your BIND server should not be a problem, the crux of the matter is to allow/restrict the DDNS upgrade:

update-policy {
  grant home.$HOME.$DOMAIN. name home.$HOME.$DOMAIN. A;
};

Important note: I had a problem this way on my very first update, "nsupdate" reported a TSIG error. I then changed to the more common "allow-update" statement, run my script as below, and then it worked. After doing the initial creation of the record this way "grant" also worked.

I also create a specific shared secret for this purpose:

$ dnssec-keygen -a HMAC-SHA512 -b 512 -n USER home.$HOME.$DOMAIN.

This shared secret needs to go into the relevant "key" section, and we also gonna need the files on that machine doing the DDNS upgrades actually.

Script to do automatic DDNS upgrades

#!/bin/bash

if [ -z "$1" ] ; then
  exit 1
fi

logger -t do-home-ddns.sh "Param: $1"

IP="$1"
nsupdate -k /etc/ddclient/Khome.<strong>$HOME.$DOMAIN</strong>.+xxx+yyyyy.private << EOT
server $NAMESERVERIP
update delete home.<strong>$HOME.$DOMAIN</strong>. A
update add home.<strong>$HOME.$DOMAIN</strong>. 5 A $IP
send
EOT

Not much to it. I am creating my records with a fairly low TTL, but you can change that if you want. Try it, whether it works when you pass an IP, whether it actually updates the record.

Using ddclient to do the magic

  ssl=yes
  quiet=no
  syslog=yes
  daemon=5m
  pid=/var/run/ddclient-allddns.pid
  cache=/var/cache/ddclient/all-ddns.cache

  use=if
  if=enp6s1
  postscript=/etc/ddclient/do-home-ddns.sh

  server=updates.opendns.com
  protocol=dyndns2
  [..]

  protocol=dyndns2
  server=ipv4.tunnelbroker.net
  [...]

I did not know that you can run multiple DDNS updates within one file, so originally I had one for my OpenDNS update and another one for HE Tunnelbroker (for updating my IPv4 endpoint of my IPv6 tunnel). Now this looks tidier and I am calling the script here as a "postscript" parameter as well.

Show Comments