MikroTik Script: DuckDNS.org DDNS Update

This script is to be used in conjuction with DuckDNS.org’s Dynamic DNS Service. It is to be scheduled/ran on a Mikrotik router. Unlike the original version (click the MikroTik button after the page loads), this script does not use any global variables, instead it compares the current IP of the WAN interface with the resolved (DNS) IP of the users DuckDNS.org’s FQDN (e.g. mysudbdomain.duckdns.org). Simply create your DuckDNS.org subdomain if you haven’t already and ensure that values are updated for the following variables: duckdnsFullDomain, duckdnsSubDomain, duckdnsToken, wanInterface, and logDestination.

Marthur's DuckDNS.org Dynamic DNS Update Script v1.0

#---------------------------------------------------SCRIPT INFORMATION----------------------------------------------------
#
# Script:  Marthur's DuckDNS.org Dynamic DNS Update Script
# Version: 1.0
# Updated: 10/30/2017
# Created: 10/30/2017
# Author:  Marthur Jones
# Website: https://www.marthur.com
#
#-----------------------------------------------TESTED USING THE FOLLOWING------------------------------------------------
#
# Hardware: CCR1009-7G-1C-1S+
# Firmware: v3.41
# RouterOS: v6.40.4
#
# This script is to be used in conjuction with DuckDNS.org's Dynamic DNS Service. It is to be scheduled/ran on a Mikrotik 
# router. Unlike the original version, this script does not use any global variables, instead it compares the current IP
# of the WAN interface with the resolved (DNS) IP of the users DuckDNS.org's FQDN (e.g. mysudbdomain.duckdns.org).
#
#----------------------------------------------MODIFY THIS SECTION AS NEEDED----------------------------------------------

# DuckDNS Full Domain (FQDN)
:local duckdnsFullDomain "mysubdomain.duckdns.org"

# DuckDNS Sub Domain
:local duckdnsSubDomain "mysubdomain"

# DuckDNS Token
:local duckdnsToken "7311de01-1830-454d-be05-9e8f2f99f4ce"

# The interface name with the assigned dynamic IP address (usually the WAN interface).
:local wanInterface "Ether0-Gateway"

# Log destination
:local logDestination "/disk1/logs/"

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

:log warning message="START: DuckDNS.org DDNS Update"

:if ([/interface get $wanInterface value-name=running] = true) do={

#   Get the previous IP via DNS resolution.
    :local previousIP [:resolve "$duckdnsFullDomain"]

#   Get the current IP on the WAN interface.
    :local currentIP [/ip address get [find interface="$wanInterface" disabled=no] address]

#   Strip net mask from IP address.
    :for i from=([:len $currentIP] - 1) to=0 do={
        :if ([:pick $currentIP $i] = "/") do={
            :set currentIP [:pick $currentIP 0 $i]
        }
    }

    :log info "DuckDNS: DNS IP ($previousIP), interface IP ($currentIP)"
    
    :if ($currentIP != $previousIP) do={
        :log info "DuckDNS: Current IP $currentIP is not equal to previous IP, update needed"
        :log info "DuckDNS: Sending update for $hostname"
        /tool fetch mode=https keep-result=yes dst-path=($logDestination . "duckdns-ddns-update.txt") address=[:resolve www.duckdns.org] port=443 host=www.duckdns.org src-path=("/update?domains=" . $duckdnsSubDomain . "&token=" . $duckdnsToken . "&ip=" . $currentIP);
        :log info "DuckDNS: Host $hostname updated on DuckDNS with IP $currentIP"
    }   else={
        :log info "DuckDNS: Previous IP $previousIP is equal to current IP, no update needed"
        }

}   else={
    :log info "DuckDNS: $wanInterface is not currently running, unable to verify and/or update IP."
    }
    
:log warning message="END: DuckDNS.org DDNS Update"

Leave a Comment

Your email address will not be published. Required fields are marked *