Free Personal Self Hosted Dynamic DNS

ID N0WHERE:171853
Type n0where
Reporter N0where
Modified 2017-07-10T14:53:28


Free Personal Self Hosted Dynamic DNS with BIND and DNSSEC


  • Server: static IP, running BIND
  • Home: dynamic IP, running Debian/*buntu

Key Generation

First step is to generate a key on the server.

/etc/bind $ sudo dnssec-keygen -a HMAC-MD5 -b 512 -n HOST

This creates two files, which will be named differently based on individual runs.
File Content: IN KEY 512 3 157 <key>

Private-key-format: v1.3
Algorithm: 157 (HMAC_MD5)
Key: <key>
Bits: AAA=
Created: 20160126233343
Publish: 20160126233343
Activate: 20160126233343

Key File

Next create a key file at /etc/bind/

key {
        algorithm HMAC-MD5;
        secret "<secret>";

Then add the following line to /etc/bind/named.conf.local to include the new key.

include "/etc/bind/";

Dynamic Zone

Add a zone for BIND.

// Dynamic zone
zone "" IN {
  type master;
  allow-transfer {none;};
  file "/etc/bind/";
  update-policy {
    key "";

Define /etc/bind/ file

$TTL 14400      ; 4 hours         IN SOA (
                                9          ; serial
                                604800     ; refresh (1 week)
                                86400      ; retry (1 day)
                                2419200    ; expire (4 weeks)
                                604800     ; minimum (1 week)

Restart BIND.


First transfer the .key and .private files down to the client system via your transport mechanism of choice. Once situated, chmod each file to 0400.

-r-------- 1 user user 128 Jan 26 17:58
-r-------- 1 user user 229 Jan 26 17:58

Update Script

The nsupdate tool in the dnsutils package will perform the update.


EXT_IP=$(wget -qO-

cat <<EOF | nsupdate -k "$KEY"
update delete A
update add 86400 A $EXT_IP

Cron Schedule

A quick test with dig will show if the record updated.

$ dig @ +short

The script can be scheduled to run automatically on the client with cron.

$ crontab -l
*/15 * * * * /path/to/<script>