Dynamic DNS Script


#1

Hi folks - using MIAB to host my personal domains and absolutely love it! One thing I needed a little help with was some dynamic DNS capabilities…

Long story short - MIAB hosts one of my domains for email & web, but I wanted to have a subdomain I could use to access my VPN & NAS servers at home.

So, I wrote a shell script that runs on my pfSense gateway at home, which updates the subdomain records on the MIAB.

For Example:
box.mydomain.com (my MIAB) / IP address 1.2.3.4 hosts:
www.mydomain.com
mail.mydomain.com

But I want vpn.mydomain.com and nas.mydomain.com to point to 5.6.7.8 (which is my home, dynamic IP).

So I run the attached shell script via cron on my pfSense gateway, and it will update the vpn.mydomain.com and nas.mydomain.com entries on the MIAB whenever my IP address changes.

Make sense?

Hope this is useful for someone – it is for me!

Thanks,

–Dennis

--------- CONTENTS OF dm-dyndns.sh below ---------
#!/bin/sh
# dm-dyndns v1.0, dmurphy@dmurphy.com
# Shell script to provide dynamic DNS to a mail-in-the-box platform.
# Requirements:
# dig installed
# curl installed
# OpenDNS myip service availability (myip.opendns.com)
# Mailinabox host (see https://mailinabox.email)
# Mailinabox admin username/password in the CFGFILE below
# one line file of the format (curl cfg file):
# user = “username:password”
# Dynamic DNS name to be set
# DYNDNSNAMELIST file contains one hostname per line that needs to be set to this IP.

MYNAME="dm-dyndns"
CURRENTIPFILE="$MYNAME.ip"
CFGFILE="$MYNAME.cfg"
DIGCMD="/usr/local/bin/dig"
CURLCMD="/usr/local/bin/curl"
CATCMD="/bin/cat"
DOMAIN="mydomain.com"
MIABHOST="box.$DOMAIN"
DYNDNSNAMELIST="$MYNAME.dynlist"

if [ ! -x $DIGCMD ]; then
  echo "$MYNAME: dig command $DIGCMD not found.  Check and fix please."
  exit 99
fi

if [ ! -x $CURLCMD ]; then
  echo "$MYNAME: curl command $CURLCMD not found.  Check and fix please."
  exit 99
fi

if [ ! -x $CATCMD ]; then
  echo "$MYNAME: cat command $CATCMD not found.  Check and fix please."
  exit 99
fi

if [ ! -f $CFGFILE ]; then
  echo "$MYNAME: $CFGFILE not found.  Check and fix please."
  exit 99
fi

if [ ! -f $DYNDNSNAMELIST ]; then
   echo "$MYNAME: $DYNDNSNAMELIST not found.  Check and fix please."
   exit 99
fi

MYIP="`$DIGCMD +short myip.opendns.com @resolver1.opendns.com`"

  if [ -z "$MYIP" ]; then
    echo "$MYNAME: dig output was blank.  Check myip.opendns.com services."
    exit 99
  fi

for DYNDNSNAME in `$CATCMD $DYNDNSNAMELIST`
do
  PREVIP="`$DIGCMD +short $DYNDNSNAME @$MIABHOST`"
  if [ -z "$PREVIP" ]; then
    echo "$MYNAME: dig output was blank.  Check $MIABHOST DNS server."
    exit 99
  fi

    if [ "x$PREVIP" = "x$MYIP" ]; then
      echo "$MYNAME: $DYNDNSNAME hasn't changed."
    else
      echo "$MYNAME: $DYNDNSNAME changed (previously: $PREVIP, now: $MYIP)"
  STATUS="`$CURLCMD -X PUT -K $CFGFILE -s -d $MYIP https://$MIABHOST/admin/dns/custom/$DYNDNSNAME`"
  case $STATUS in
     "OK") echo "$MYNAME: mailinabox API returned OK, cmd succeded but no update.";;
     "updated DNS: $DOMAIN") echo "$MYNAME: mailinabox API updated $DYNDNSNAME OK.";;
     *) echo "$MYNAME: other status from mailinabox API. Please check.";;
     esac

    fi
done
    exit 0

----- Contents of dm-dyndns.cfg file below -----
user = "admin@mydomain.com:MYADMINPASSWORD"

------ Contents of dm-dyndns.dynlist below -----
vpn.mydomain.com
nas.mydomain.com


#2

Have you tried my Dynamic DNS script? https://github.com/mitchellurgero/mailinabox_dynamic_dns_script

Written in PHP it allows end users to create and delete DNS entries (A records only right now). With domain checking (allowing users to only delete the domains they add.) it’s alright for internal use. Probably not secure for use by external users.


#3

Thanks Mitchell! Your PHP script is a little different use case, in that it allows end users to login and create their own A records, etc. Mine is a quick and dirty hack to allow my firewall to automatically update some entries if/when my home IP address changes. I wanted something no-touch so when my ISP changes my IP address, the DNS entries get automatically updated. Right now I have cron running my script every 10 minutes, so if my IP address changes, within 10 minutes, the A records will catch up. That’s good enough for my simple use!

Great job working on your PHP scripts; you’ve got a nice GUIfied interface to allow self-support for end users. Mine is a quick and dirty hack to solve my corner case!

Thanks!

–Dennis


#4

Hoping this works out well. I have static IP at first ISP & dynamic on standby from dual wan Merlin router. Will attempt this evening.

Works fine :+1: I decided to keep the script on my server hosting the services.


#5

Awesome! So glad it’s working for you… it’s saved my bacon when traveling more than once. Enjoy the weekend!


#6

Here is another quick and dirty hack to access your home box, if you don’t necessarily need end users to access it, you just need the IP… I run basically the following in a cron job, output it to a sync’ed nextcloud directory… My address doesn’t change often (I just stick it with a name in .ssh/config for my purposes), but I can just look here on my other sync’ed systems to find it (I could theoretically write a cron job to keep a hosts file updated with the IP in this sync’ed directory if I wanted)

IP=$(/usr/bin/curl http://checkip.dyndns.org/ )
echo $IP| cut -d “>” -f 7 |cut -d “<” -f1 > /home/jay/ownCloud/home_ip.txt


#7

Even better:

IP=$(/usr/bin/curl http://icanhazip.com) && echo $IP > /home/jay/ownCloud/ip.txt

One liners always better :wink: