Page 1 of 1

[Script] Namecheap Digitalocean Dynamic DNS Update Script

Posted: Thu Apr 14, 2016 8:44 pm
by soonwai
Namecheap Dynamic DNS Update Script
http://wiki.mikrotik.com/wiki/Dynamic_DNS_Update_Script_for_Namecheap

This is a ROS 7 script (IIRC, the fetch command is bit different in ROS 6) which checks if the IP for an interface has changed, updates namecheap.com's dynamic DNS and also sends you an email about it. :o

As it turns out, it's also good for letting me know when electricity has been restored after a blackout or when the ISP comes back from an outage. :)

ROS now has /ip cloud with Mikrotik's own ddns. With this script and Namecheap, you can have a much cooler and shorter ddns domain. And also a backup in case /ip cloud is down.

My first script here so please let me know if things can be improved. I'm quite the newbie to Mikrotik. The script was originally taken from the Mikrotik wiki for another ddns provider and then modified for Namecheap.

Email tool needs to be setup beforehand. Just change the variables to yours. There's no error checking if the ddns update fails or sending email encounters an error.

Schedule this script to run every few minutes as you please. For pppoe, you can also run it from ppp profile up and down script.

:local "NC_DDNS_SERVER" "dynamicdns.park-your-domain.com"
:local "NC_DDNS_HOSTNAMES_ARRAY" {"host1";"host2"}
:local "NC_DDNS_HOSTNAMES" [:tostr $"NC_DDNS_HOSTNAMES_ARRAY"]

:local "NC_DDNS_DOMAIN" "example.com"
:local "NC_TOKEN" "0123456789abcdef"
:local "TELEGRAM_SERVER" "api.telegram.org"
:local "TELEGRAM_KEY" "bot0123456789abcdef"
:local "TELEGRAM_CHAT_ID" "012345678"
:local "ISP_NAME" "My_ISP"
:local "WAN_INTERFACE" "pppoe-out1"
:local "LOG_FILE_PREFIX" "/disk1/logs/DDNS_NC."

:global "ddns_previous_ip"
:local "ddns_current_ip" [ /ip address get [/ip address find interface=$"WAN_INTERFACE" ] address ]
:local "current_date" [/system clock get date]
:local "current_time" [/system clock get time]
:local "system_name" [/system identity get name]
:local "system_uptime" [/system resource get uptime]
:local "system_free_memory" [/system resource get free-memory]
:local "system_cpu_load" [/system resource get cpu-load]
:local "system_version" ("ROS " . [/system/package/get [find name=routeros] version] )

# Strip the net mask off the IP address
:set "ddns_current_ip" [:pick $"ddns_current_ip" 0 [:find $"ddns_current_ip" "/"]]

:if ([ :typeof $"ddns_previous_ip" ] = nil ) do={ :global "ddns_previous_ip" "0" }
:if ([ :typeof $"ddns_current_ip" ] = nil ) do={
    :log info ("DDNS: No ip address present on $"WAN_INTERFACE" interface, please check.")
    } else={
        :if ($"ddns_current_ip" != $"ddns_previous_ip") do={
            :foreach hostname in=$"NC_DDNS_HOSTNAMES_ARRAY" do={
                :log info ("DDNS: Updating $hostname.$"NC_DDNS_DOMAIN" $"ddns_previous_ip" -> $"ddns_current_ip"")
                :local str "https://$"NC_DDNS_SERVER"/update?host=$"hostname"&domain=$"NC_DDNS_DOMAIN"&password=$"NC_TOKEN"&ip=$"ddns_current_ip""
                #:log info $str
                /tool fetch url=$str mode=https dst-path=($"LOG_FILE_PREFIX".$hostname)
            }
            #:log info $"NC_DDNS_HOSTNAMES"
            :log info "DDNS: Sending Email"
            /tool e-mail send to=myself@example.com subject="$"ISP_NAME" IP $"current_date" $"current_time" $"system_name"" body="$"system_name" $"current_date" $"current_time" \r$"system_version"\rNamecheap: $"NC_DDNS_HOSTNAMES" \rDomain: $"NC_DDNS_DOMAIN" \r$"ISP_NAME" IP: $"ddns_current_ip" \rPrevious IP: $"ddns_previous_ip" \rUptime: $"system_uptime" \rFree memory: $"system_free_memory" kb \rCPU Load: $"system_cpu_load" % "
            :log info "DDNS: Sending Telegram"
            :local str "https://$"TELEGRAM_SERVER"/$"TELEGRAM_KEY"/sendMessage?chat_id=$"TELEGRAM_CHAT_ID"&parse_mode=Markdown&text=$"ISP_NAME" $"system_name" $"system_version"%0ANamecheap: $"NC_DDNS_HOSTNAMES"%0ADomain: $"NC_DDNS_DOMAIN"%0A$"current_date" $"current_time"%0A$"ISP_NAME" IP: $"ddns_current_ip"%0APrevious IP: $"ddns_previous_ip"%0AUptime: $"system_uptime"%0AFree memory: $"system_free_memory" kb%0ACPU Load: $"system_cpu_load" %"
            #:log info $str
            /tool fetch url=$str mode=https keep-result=no   
            :global "ddns_previous_ip" $"ddns_current_ip"
        } else={
            :log info "DDNS: IP has not changed. DDNS will not be updated."
          }
      }

Below is a snippet of code for updating Digitalocean's DNS using its API. You can use this instead of Namecheap in the script above or both simultaneously. Fingers crossed DO's DNS recordids are persistent.
# Only recordid(s) in DO_DDNS_RECORDID_ARRAY are used in Digitalocean's DNS API.
:local "DO_DDNS_RECORDID_ARRAY" {"host1"=123456789;"host2"=987654321}
:local "DO_DDNS_DOMAIN" "example.com"
:local "DO_TTL" 30
:local "DO_TOKEN" "dop_v1_abcdefghijklmn1234567890opqrstuvwxyz"
:local "DO_HEADER" "Content-Type: application/json,Authorization: Bearer $"DO_TOKEN""
:local "DO_LOG_FILE_PREFIX" "/disk1/logs/DDNS_DO."

:local "do_data" "{\"ttl\":$"DO_TTL", \"data\":\"$"ddns_current_ip"\"}"

:foreach hostname,recordid in=$"DO_DDNS_RECORDID_ARRAY" do={
  :local "do_url" "https://api.digitalocean.com/v2/domains/$"DO_DDNS_DOMAIN"/records/$"recordid""
  :log info $"do_url"
  /tool fetch mode=https http-method=put http-header-field=$"DO_HEADER" http-data=$"do_data" url=$"do_url" dst-path=($"DO_LOG_FILE_PREFIX".$hostname)
}

Re: Namecheap Dynamic DNS Update Script

Posted: Mon Feb 20, 2017 9:25 pm
by soonwai

Re: [Script] Namecheap Dynamic DNS Update Script

Posted: Tue Oct 24, 2017 1:38 am
by IMLizKing
I used the above as a starting point for my own namecheap dynamic DNS update script. I tied it into my DHCP client script for my WAN interface instead, so there is no need to run it every 5 minutes or anything like that. I also didn't bother with the e-mail or keeping a pile of variables globally. Anyways, I thought I'd share it here since this is where I ended up when I wanted dynamic DNS with namecheap on my MikroTik router...

Code: Select all

:if ($bound=1) do {

# the name (within the domain) to update -- must already exist!
:local host <dns hostname>

# the domain name
:local domain <dns domainname>

# key for namecheap updates
:local password <namecheap key>

# get wan IP (easy in the DHCP script)
:local wanip $"lease-address"

:log info "DHCP got WAN IP of $wanip"

:local url "https://dynamicdns.park-your-domain.com/update?host=$host&domain=$domain&password=$password&ip=$wanip"

#:log info "URL args: $url"

# this should to the deed! (note: no verification is done here, check namecheap yourself at first!)
/tool fetch url=$url mode=https keep-result=no

} else {
#:log info "DHCP was unbound"
}
You'll want to login to namecheap first, lookup your DNS key for updates, and make an initial entry in your DNS table (of type "A + Dynamic DNS Record".)

The script doesn't do much (any) error checking, but I figure if it works once, it'll probably keep working. And I don't do anything when the DHCP is unbound.. I don't think that hurts much of anything, plus I don't know that we can remove a DNS entry remotely on namecheap.

Hope this helps someone! Cheers!

Re: [Script] Namecheap Dynamic DNS Update Script

Posted: Fri Aug 03, 2018 1:42 pm
by CyberCam
So if you have more than one host name do you need to recreate this script for each sub domain host name? Or is there a way to enter all your sub domain host name in one script!

Re: [Script] Namecheap Dynamic DNS Update Script

Posted: Mon Jan 14, 2019 3:38 pm
by BloodLizard
So if you have more than one host name do you need to recreate this script for each sub domain host name? Or is there a way to enter all your sub domain host name in one script!
Did some simple modifications for myself.

# the name (within the domain) to update -- must already exist!
:local hosts [:toarray value="record1,record2,record3"];
# the domain name
:local domain <domain>
# key for namecheap updates
:local password <pass key>
# get wan IP
:local ddnsip [ /ip address get [/ip address find interface=<wan interface> ] address ]
:log info "WAN IP is $ddnsip"
# Strip the net mask off the IP address
:for i from=( [:len $ddnsip] - 1) to=0 do={
    :if ( [:pick $ddnsip $i] = "/") do={ 
        :set ddnsip [:pick $ddnsip 0 $i]
       } 
   }
:foreach host in $hosts do={
:local url "https://dynamicdns.park-your-domain.com/update?host=$host&domain=$domain&password=$password&ip=$ddnsip"
:log info "URL args: $url"
/tool fetch url=$url mode=https keep-result=no
}

Re: [Script] Namecheap Dynamic DNS Update Script

Posted: Mon Apr 29, 2019 7:54 pm
by Kronyx
Hi !

I have searched but did not find how to create the script and where ton install the script ? Sorry i'm new with Mikrotik.

Re: [Script] Namecheap Dynamic DNS Update Script

Posted: Sun Nov 17, 2019 1:56 pm
by sealtech
So in your example is the domain cctv1.soonwai.com? I cannot get the script to update my subdomain
:global ddnshostname "cctv1"
:global ddnsdomain "soonwai.com"

Re: [Script] Namecheap Dynamic DNS Update Script

Posted: Thu Jan 28, 2021 6:29 am
by Lilarcor
I have been using it for last one year and it works so well. Recently, I have got ipv6 address from my isp. Is there a way to let the script support updating AAAA record ?

Re: [Script] Namecheap Dynamic DNS Update Script

Posted: Fri Jan 29, 2021 4:37 am
by Van9018
With this script and Namecheap, you can have a much cooler and shorter ddns domain.
You can also create a CNAME record that resolves to your mikrotik ddns url. Saves you the cost of ddns hosting.

Re: [Script] Namecheap Dynamic DNS Update Script

Posted: Fri Oct 21, 2022 9:38 am
by priv
Hi,
I found that the original script does not work anymore and removed from wiki.
(I don't know how long it is broken, because my ips are not changed.)

I did some debugging on command line, found that tool fetch with "address" will cause https problems.

Now namecheap only accept "url" mode.
/tool fetch url=$str mode=https keep-result=no

Additionally, original script export a lot of global variables, but only lastip is needed, others can be local.

Here's the fixed script
:local ddnsserv "dynamicdns.park-your-domain.com"
:local ddnshostname "home"
:local ddnsdomain "yourdomain.com"
:local ddnspass "masked"
:local ddnsip [ /ip address get [/ip address find interface=pppoe-out1 ] address ]
:global ddnslastip

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

:if ([ :typeof $ddnslastip ] = nil ) do={ :global ddnslastip "0" }
:if ([ :typeof $ddnsip ] = nil ) do={
   :log info ("DDNS: No ip address present on pppoe interface.")
} else={
  :if ($ddnsip != $ddnslastip) do={
    :log info "DDNS: IP changed, previous IP=$ddnslastip, new IP=$ddnsip"
    :log info ("DDNS: Updating Namecheap Dynamic DNS")
    :local str "https://$ddnsserv/update?host=$ddnshostname&domain=$ddnsdomain&password=$ddnspass&ip=$ddnsip"
    /tool fetch url=$str mode=https keep-result=no
    :global ddnslastip $ddnsip
  } else={
    #:log info "DDNS: IP unchanged. No update required."
  }
}
Regards,
Alvin

Re: [Script] Namecheap Dynamic DNS Update Script

Posted: Sun Feb 19, 2023 4:37 pm
by capac
Hi folks,
have been trying to use the latest version of this script, however, can't seem to get it working... copy/pasted the script, adjusted with my domain/subdomain/pw/interface, but nada.
Can anyone post a recent script that works ?
Many thanks.

Re: [Script] Namecheap Dynamic DNS Update Script

Posted: Fri Apr 14, 2023 5:45 pm
by lorenzopicoli
I can confirm that the latest script does work. Make sure that you adjust line number 5 where it sets the ddnsip so it checks the correct interface

Re: [Script] Namecheap Dynamic DNS Update Script

Posted: Fri Apr 14, 2023 6:14 pm
by rextended
L'ha già scritto che ha cambiato interfaccia. Lo script è pieno di errori, quindi a seconda della versione di RouterOS, che ovviamente nessuno scrive, hai risultati diversi.

Re: [Script] Namecheap Digitalocean Dynamic DNS Update Script

Posted: Thu May 30, 2024 10:42 pm
by aka13
I just wanted to chime in, that the script from 2017 when using DHCP-Client indeed works with the same logic.
I use it for my domain with minor cosmetic modifications:
:local host "*"
:local domain "my_domain"
:local password "my_api_key"

:if ($bound=1) do={
    :local ipaddress $"lease-address"
    :log info "IP lease received, updating DDNS"
    /tool fetch url="https://dynamicdns.park-your-domain.com/update?host=$host&domain=$domain&password=$password&ip=$ipaddress" mode=https keep-result=no
} else={
    :log info "No IP lease, nothing to be done with DDNS"
}
:log info "DHCP Client script ran successfully"
The last line is a sanity check, that the script really worked. Sadly the behaviour of scripts is to silently error out, and unless you do a log output at the very end, you can't be sure that it really ran in full.

Re: [Script] Namecheap Digitalocean Dynamic DNS Update Script

Posted: Sat Aug 17, 2024 12:22 am
by cpunk
I just wanted to chime in, that the script from 2017 when using DHCP-Client indeed works with the same logic.
This worked great for me. I replaced a scheduled script with this. Thanks!