Dynamic DNS Update Script for ChangeIP.com - MikroTik Script RouterOS

The following script should be created when you wish to update your ChangeIP.com Dynamic DNS account. Once created you should schedule this to run once in a while. The :global variables should be edited to include your unique username and password, interface name, etc.

The script below is RouterOS 4.2 Tested! It should also continue to work under 3.x series RouterOS.

Below the plain text script is an export that can be used to paste directly into terminal window. That method is recommended as word wrapping is common. The second code window is also recommended because it includes a scheduler entry.

Note: A copy of the latest Dynamic DNS update script should be at ChangeIP.com.

# Dynamic DNS Update / Simple Edition
# Written by Sam Norris, ChangeIP.com
# Copyright ChangeIP.com 2009-2010
# For support send mail to Support@ChangeIP.com
#
# 2009-06-22 RouterOS 3.25 Tested
# 2009-10-05 RouterOS 4.01rc1 Tested
#
# OVERVIEW:         %
#  This script will update a ChangeIP.com dynamic dns hostname
#  with an ip address located directly on an interface.
#                   %
# NOTES:            %
#  IF THIS SCRIPT DOES NOT PRODUCE ANY OUTPUT PLEASE COPY AND PASTE IT
#  AGAIN.  THERE PROBABLY IS A LINE BREAK IN THE WRONG PLACE! Once you
#  have created this script and tested that it works by running it
#  manually you can schedule it to run every few minutes.
#                   %
# CONFIGURATION FIELD DEFINITIONS:
#  ddnsuser:  Enter your ChangeIP.com user id.
#  ddnspass:  Enter your ChangeIP.com password.
#  ddnshost:  Enter the hostname (www.example.com) to update.
#  ddnsinterface:  Enter an interface name - case sensative.
#                   %
#                   %
#                   %
#                   %
#               %   %   %
#                %  %  %
#                 % % %
#                   %
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EDIT YOUR DETAILS / CONFIGURATION HERE
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:global ddnsuser "YourChangeIPUserID"
:global ddnspass "PASSWORD"
:global ddnshost "MyRouterHostname.example.org"
:global ddnsinterface "ether1"
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# END OF USER DEFINED CONFIGURATION
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:global ddnssystem ("mt-" . [/system package get [/system package find name=system] version] )
:global ddnsip [ /ip address get [/ip address find interface=$ddnsinterface] address ]
:global ddnslastip

:if ([:len [/interface find name=$ddnsinterface]] = 0 ) do={ :log info "DDNS: No interface named $ddnsinterface, please check configuration." }

:if ([ :typeof $ddnslastip ] = "nothing" ) do={ :global ddnslastip 0.0.0.0/0 }

:if ([ :typeof $ddnsip ] = "nothing" ) do={

:log info ("DDNS: No ip address present on " . $ddnsinterface . ", please check.")

} else={

  :if ($ddnsip != $ddnslastip) do={

    :log info "DDNS: Sending UPDATE!"
    :log info [ :put [/tool dns-update name=$ddnshost address=[:pick $ddnsip 0 [:find $ddnsip "/"] ] key-name=$ddnsuser key=$ddnspass ] ]
    :global ddnslastip $ddnsip

  } else={ 

    :log info "DDNS: No changes necessary."

  }

}

# END OF SCRIPT

You may copy and paste the script below into the terminal window to import a script. This will also configure the scheduler entry for you. THIS OPTION IS RECOMMENDED.

# oct/05/2009 21:28:27 by RouterOS 4.0rc1
/system script

add name=HomingBeacon-Simple policy=\
    ftp,reboot,read,write,policy,test,winbox,password source="# Dynamic DNS Up\
    date / Simple Edition\r\
    # Written by Sam Norris, ChangeIP.com\r\
    # Copyright ChangeIP.com 2009\r\
    # For support send mail to Support@ChangeIP.com\r\
    #\r\
    # 2009-06-22 RouterOS 3.25 Tested\r\
    # 2009-10-05 RouterOS 4.01rc1 Tested\r\
    #\r\
    # OVERVIEW:         %\r\
    #  This script will update a ChangeIP.com dynamic dns hostname\r\
    #  with an ip address located directly on an interface.\r\
    #                   %\r\
    # NOTES:            %\r\
    #  IF THIS SCRIPT DOES NOT PRODUCE ANY OUTPUT PLEASE COPY AND PASTE IT\r\
    #  AGAIN.  THERE PROBABLY IS A LINE BREAK IN THE WRONG PLACE! Once you\r\
    #  have created this script and tested that it works by running it\r\
    #  manually you can schedule it to run every few minutes.\r\
    #                   %\r\
    # CONFIGURATION FIELD DEFINITIONS:\r\
    #  ddnsuser:  Enter your ChangeIP.com user id.\r\
    #  ddnspass:  Enter your ChangeIP.com password.\r\
    #  ddnshost:  Enter the hostname (www.example.com) to update.\r\
    #  ddnsinterface:  Enter a list of interface names - case sensative.\r\
    #                   %\r\
    #                   %\r\
    #                   %\r\
    #                   %\r\
    #               %   %   %\r\
    #                %  %  %\r\
    #                 % % %\r\
    #                   %\r\
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\
    # EDIT YOUR DETAILS / CONFIGURATION HERE\r\
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\
    :global ddnsuser \"YourChangeIPUserID\"\r\
    :global ddnspass \"PASSWORD\"\r\
    :global ddnshost \"MyRouterHostname.example.org\"\r\
    :global ddnsinterface \"ether1\"\r\
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\
    # END OF USER DEFINED CONFIGURATION\r\
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\
    \r\
    :global ddnssystem (\"mt-\" . [/system package get [/system package find\
    \_name=system] version] )\r\
    :global ddnsip [ /ip address get [/ip address find interface=\$ddnsinter\
    face] address ]\r\
    :global ddnslastip\r\
    \r\
    :if ([:len [/interface find name=\$ddnsinterface]] = 0 ) do={ :log info \
    \"DDNS: No interface named \$ddnsinterface, please check configuration.\" \
    }\r\
    \r\
    :if ([ :typeof \$ddnslastip ] = \"nothing\" ) do={ :global ddnslastip 0.\
    0.0.0/0 }\r\
    \r\
    :if ([ :typeof \$ddnsip ] = \"nothing\" ) do={\r\
    \r\
    :log info (\"DDNS: No ip address present on \" . \$ddnsinterface . \", p\
    lease check.\")\r\
    \r\
    } else={\r\
    \r\
      :if (\$ddnsip != \$ddnslastip) do={\r\
    \r\
        :log info \"DDNS: Sending UPDATE!\"\r\
        :log info [ :put [/tool dns-update name=\$ddnshost address=[:pick \$\
    ddnsip 0 [:find \$ddnsip \"/\"] ] key-name=\$ddnsuser key=\$ddnspass ] ]\r\
        :global ddnslastip \$ddnsip\r\
    \r\
      } else={ \r\
    \r\
        :log info \"DDNS: No changes necessary.\"\r\
    \r\
      }\r\
    \r\
    }"

/system scheduler
add comment="" disabled=no interval=5m name=DDNS on-event=\
    HomingBeacon-Simple policy=read,write,policy,test,password start-time=\
    startup


ARCHIVED
The script below is RouterOS 3.0 Compatible!

An updated script here (01/20/08) should allow auto-detection of the default gateways interface name. This script below can be used if you have more than 1 WAN connection, but only 1 is active at a time.

# Define User Variables
:global ddnsuser "CHANGEIPUSERID"
:global ddnspass "CHANGEIPPASSWORD"
:global ddnshost "FREEHOSTNAME.TOUPDATE.TLD"

# Define Global Variables
:global ddnsip
:global ddnslastip
:if ([ :typeof $ddnslastip ] = nil ) do={ :global ddnslastip "0" }

:global ddnsinterface
:global ddnssystem ("mt-" . [/system package get system version] )

# Define Local Variables
:local int

# Loop thru interfaces and look for ones containing
# default gateways without routing-marks
:foreach int in=[/ip route find dst-address=0.0.0.0/0 active=yes ] do={ 
  :if ([:typeof [/ip route get $int routing-mark ]] != str ) do={
     :global ddnsinterface [/ip route get $int interface]
  } 
}

# Grab the current IP address on that interface.
:global ddnsip [ /ip address get [/ip address find interface=$ddnsinterface ] address ]

# Did we get an IP address to compare?
:if ([ :typeof $ddnsip ] = nil ) do={
   :log info ("DDNS: No ip address present on " . $ddnsinterface . ", please check.")
} else={

  :if ($ddnsip != $ddnslastip) do={

    :log info "DDNS: Sending UPDATE!"
    :log info [ :put [/tool dns-update name=$ddnshost address=[:pick $ddnsip 0 [:find $ddnsip "/"] ] key-name=$ddnsuser key=$ddnspass ] ]
    :global ddnslastip $ddnsip

  } else={ 
    :log info "DDNS: No update required."
  }

}

# End of script

If errors or problems occur with the above scripts please check to see if we are even receiving any updates. https://www.changeip.com/Reports/DDNSUpdates.asp will show you current updates on your account. Feel free to contact Support at ChangeIP.com if you are having problems.

2.9 Series: (Please use the above for the newer 3.0 version - this version is left here for archival reasons.)

:log info "DDNS: Begin"

:global ddns-user "YOURUSERID"
:global ddns-pass "YOURPASSWORD"
:global ddns-host "*1"
:global ddns-interface "EXACTINTERFACENAME"

:global ddns-ip [ /ip address get [/ip address find interface=$ddns-interface] address ]

:if ([ :typeof $ddns-lastip ] = nil ) do={ :global ddns-lastip 0.0.0.0/0 }

:if ([ :typeof $ddns-ip ] = nil ) do={

  :log info ("DDNS: No ip address present on " . $ddns-interface . ", please check.")

} else={

  :if ($ddns-ip != $ddns-lastip) do={

    :log info "DDNS: Sending UPDATE!"
    :log info [ /tool dns-update name=$ddns-host address=[:pick $ddns-ip 0 [:find $ddns-ip "/"] ] key-name=$ddns-user key=$ddns-pass ]
    :global ddns-lastip $ddns-ip

  } else={ 

    :log info "DDNS: No change" 

  }

}

:log info "DDNS: End"
For those of you that like to use the CLI, and want to make sure you get a very clean import with no line breaks, etc, you can run this script to create it for you:

/system script
add name=HomingBeaconDynamicDNSUpdater policy=\
    ftp,reboot,read,write,policy,test,winbox,password,sniff \
    source="# Define User Variables\r\
    :global ddnsuser \"CHANGEIPUSERID\"\r\
    :global ddnspass \"CHANGEIPPASSWORD\"\r\
    :global ddnshost \"FREEHOSTNAME.TOUPDATE.TLD\"\r\
    \r\
    # Define Global Variables\r\
    :global ddnsip\r\
    :global ddnslastip\r\
    :if ([ :typeof \$ddnslastip ] = nil ) do={ :global ddnslas\
    tip \"0\" }\r\
    \r\
    :global ddnsinterface\r\
    :global ddnssystem (\"mt-\" . [/system package get system \
    version] )\r\
    \r\
    # Define Local Variables\r\
    :local int\r\
    \r\
    # Loop thru interfaces and look for ones containing\r\
    # default gateways without routing-marks\r\
    :foreach int in=[/ip route find dst-address=0.0.0.0/0 acti\
    ve=yes ] do={ \r\
      :if ([:typeof [/ip route get \$int routing-mark ]] != st\
    r ) do={\r\
         :global ddnsinterface [/ip route get \$int interface]\
    \r\
      } \r\
    }\r\
    \r\
    # Grab the current IP address on that interface.\r\
    :global ddnsip [ /ip address get [/ip address find interfa\
    ce=\$ddnsinterface ] address ]\r\
    \r\
    # Did we get an IP address to compare\?\r\
    :if ([ :typeof \$ddnsip ] = nil ) do={\r\
       :log info (\"DDNS: No ip address present on \" . \$ddns\
    interface . \", please check.\")\r\
    } else={\r\
    \r\
      :if (\$ddnsip != \$ddnslastip) do={\r\
    \r\
        :log info \"DDNS: Sending UPDATE!\"\r\
        :log info [ :put [/tool dns-update name=\$ddnshost add\
    ress=[:pick \$ddnsip 0 [:find \$ddnsip \"/\"] ] key-name=\$d\
    dnsuser key=\$ddnspass ] ]\r\
        :global ddnslastip \$ddnsip\r\
    \r\
      } else={ \r\
        :log info \"DDNS: No update required.\"\r\
      }\r\
    \r\
    }\r\
    \r\
    # End of script"
Credit: https://wiki.mikrotik.com