A quick and simple guide to running your own dynamic dns with your own domain.

Webmin plug

I’ve always hosted my own dns, it’s pretty simple and gives you a lot of flexibility both internally and externally. I use webmin for a simple quick dns server with a nice interface. I made a docker for this a couple years ago and it can be found on my old github docker-webmin-bind

The good dns stuff

To do this we will need a couple things. Locally we need bind9dnsutils package if you’re on a debian or ubuntu OS.

sudo apt update && sudo apt install bind9utils

Now we need to generate a key to use for our dns server:

dnssec-keygen -a HMAC-MD5 -b 128 -n USER mysubdomain.mydomain.com

This will generate a couple files:

Kmysubdomain.mydomain.com.+157+25246.key Kmysubdomain.mydomain.com.+157+25246.private

Now we want to add our key to bind:

In webmin this will be the DNS Keys section on the main bind page.

named.conf

key mysubdomain.mydomain.com {
    algorithm hmac-md5;
    secret "GdMy3GWso6Ys0dBtuy9QkA==";
    };

this will add a key to bind named mysubdomain.mydomain.com. Now we can reference that that key.

Then we need to add the allow-update line to our zone configuration:

In webmin this will be the Zone Options section on the domain page.

named.conf.local

zone "mydomain.com" {
    type master;
    file "/var/lib/bind/mydomain.com.hosts";
    allow-update { key "mysubdomain.mydomain.com"; };
    };

For webmin: Allow updates from.. key mysubdomain.mydomain.com

NOTE: You do not need to add a subomain in bind yet, this will be handled by our script.

Updating your subdomain

Now that we have keys in place for our subomain. Here is a simple script to manage construcint and sending a dns update with nsupdate:

#!/usr/bin/env bash

#Set our parameters
WGET=$(which wget)
ECHO=$(which echo)
NSUPDATE=$(which nsupdate)
UPDATEFILE="/tmp/nsupdate"
DNSSERVER=mydns.server.com
ZONE=mydomain.com.
UPDATE=mysubdomain.mydomain.com.
KEY="/path/to/Kmysubdomain.mydomain.com.+157+25246.private"

#Get our current IP
IP=$($WGET -q -O - checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//')

#Create the update file for the update
$ECHO "server $DNSSERVER" > $UPDATEFILE
$ECHO "zone " >> $UPDATEFILE
$ECHO "update delete $UPDATE" >> $UPDATEFILE
$ECHO "update add $UPDATE 60 A $IP" >> $UPDATEFILE
$ECHO "send" >> $UPDATEFILE

#Do the update
$NSUPDATE -k $KEY -v $UPDATEFILE 2>&1

NOTE: The zone and updates will likely need a period at the end.

Make your script executable and add to your crontab at whatever interval you feel like.

chmod +x dns-updater.sh