Dynamic DNS Update Script for DNSoMatic.com

From MikroTik Wiki
Revision as of 00:12, 11 November 2013 by Hjoelr (talk | contribs) (Updated to work with ROS 6.0+)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

This script is a solution made of others solutions (nothing new). Much of this was adapted from the deprecated version of Dynamic DNS Update Script for DNSoMatic.com behind NAT.

The goal is to update your account on DNSoMatic.com. The main advantage of this solution is that DNSoMatic offers the possibility of propagating DNS updates to thirth party DNSlike systems like OpenDNS, DynDNS, Change IP and other 27 more.

Note: The script below is RouterOS 5.14 & 6.6 Tested!

The following permissions are required for this script to run:

  • write
  • test
  • read
  • policy (for ROS 6.0+)
# DNSoMatic automatic DNS updates

#--------------- Change Values in this section to match your setup ------------------

# User account info of DNSoMatic

:local maticuser "dnsomatic-username"
:local maticpass "dnsomatic-password"

# Set the hostname or label of network to be updated. This is the part after the double colon (::) on the DNSoMatic services page.
# Hostnames with spaces are unsupported. Replace the value in the quotations below with your host names.
# To specify multiple hosts, separate them with commas. 
# Use "all.dnsomatic.com" for the matichost to update all items in dnsomatic with this IP.

:local matichost "hostname1,hostname2"

# Change to the name of interface that gets the changing IP address

:local inetinterface "ether1-gateway"

#------------------------------------------------------------------------------------

# No more changes need

:global previousIP;

:if ([/interface get $inetinterface value-name=running]) do={
# Get the current IP on the interface
    :local currentIP [/ip address get [find interface="$inetinterface" disabled=no] address];
    
# Strip the net mask off the IP address
    :for i from=( [:len $currentIP] - 1) to=0 do={
        :if ( [:pick $currentIP $i] = "/") do={ 
            :set currentIP [:pick $currentIP 0 $i]
        } 
    }
    
    :if ($currentIP != $previousIP) do={
        :log info "DNSoMatic: Update needed"
        :set previousIP $currentIP
        
# The update URL. Note the "\3F" is hex for question mark (?). Required since ? is a special character in commands.
        :local url "http://updates.dnsomatic.com/nic/update\3Fmyip=$currentIP&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG"
        :local matichostarray;
        :set matichostarray [:toarray $matichost];
        :foreach host in=$matichostarray do={
            :log info "DNSoMatic: Sending update for $host"
            /tool fetch url=($url . "&hostname=$host") user=$maticuser password=$maticpass mode=http dst-path=("dnsomaticupdate-" . $host . ".txt")
            :log info "DNSoMatic: Host $host updated on DNSoMatic with IP $currentIP"
        }
    }  else={
        :log info "DNSoMatic: Previous IP $previousIP and current IP equal, no update need"
    }
} else={
    :log info "DNSoMatic: $inetinterface is not currently running, so therefore will not update."
}

This will also need you to configure scheduler entry for periodical runs (maybe every minute or so). You will probably want a second scheduler event run this script upon RouterOS startup.

If for whatever reason the update fails, the script will not update DNSoMatic until the IP address changes again. This is rare, but could happen. It would be recommended to set up a third scheduler with longer intervals (maybe 1 hour) to run a script with the following code:

:global previousIP;
:set previousIP ""

:log info "Cleared previousIP to force DNS-O-Matic update on next run."

The following permissions are required for this script to run:

  • write
  • test (for ROS 6.0+)
  • read (for ROS 6.0+)
  • policy (for ROS 6.0+)

It will silently fail if it doesn't have this permission.

hjoelr 10/nov/2013