Page 1 of 1

Update Cloudflare DNS with script

Posted: Wed Jun 26, 2024 1:23 am
by msachse
Hello,
I am trying to write a script that would allow routerOS to update cloudflare through their API any time my ISP changes the WAN IP on my router. I found some starting point in GIT (https://github.com/dudanov/mikrotik-clo ... ns-scripts) but have not been successful in running the script as it is giving me errors. The device is running RouterOS 7.14.3.

Anybody can point out how the script needs to be reworked? I tried adding line by line and found the first error is coming where the current IP address for WAN is being retrieved.
# Update Cloudflare DNS IPv4 address script
# RouterOS version >= 6.44 is required

# ** CONFIGURE SECTION **

# WAN IPv4 interface
:local wanif    "wan1"

# Cloudflare section
:local email    "e-mail"
:local key      "token"
:local zoneId   "zoneId"
:local hostId   "hostId"

# Domain hostname
:local hostName "host.yourdomain.com"

# ** END OF CONFIGURE SECTION **

# Get WAN interface IPv4 address
:global ip4wan
:local ip4new [/ip address get [/ip address find interface=$wanif] address]
:set ip4new [:pick [:tostr $ip4new] 0 [:find [:tostr $ip4new] "/"]]

:if ([:len $ip4new] = 0) do={
  :log error "[Cloudflare DDNS] Could not get IPv4 for interface $wanif"
  :error "[Cloudflare DDNS] Could not get IPv4 for interface $wanif"
}

:if ($ip4new != $ip4wan) do={

  :log info "[Cloudflare DDNS] WAN IPv4 address for interface $wanif has been changed to $ip4new."

  :local url    "https://api.cloudflare.com/client/v4/zones/$zoneId/dns_records/$hostId"
  :local header "X-Auth-Email: $email, X-Auth-Key: $key, content-type: application/json"
  :local data   "{\"type\":\"A\",\"name\":\"$hostName\",\"content\":\"$ip4new\",\"ttl\":120}"

#  :log info "[Cloudflare DDNS] URL: $url"
#  :log info "[Cloudflare DDNS] HEADER: $header"
#  :log info "[Cloudflare DDNS] DATA: $data"
#  :log info "[Cloudflare DDNS] Updating host $hostName address."

  :local jsonAnswer [/tool fetch mode=https http-method=put http-header-field=$header http-data=$data url=$url as-value output=user]

  :if ([:len $jsonAnswer] > 0) do={

    /system script run "JParseFunctions"; global JSONLoads; global JSONUnload
    :local result ([$JSONLoads ($jsonAnswer->"data")]->"success")
    $JSONUnload

    :if ($result = true) do={
      :log info "[Cloudflare DDNS] Successfully updated IPv4 address to $ip4new."
      :set ip4wan $ip4new
    } else={
      :log error "[Cloudflare DDNS] Error while updating IPv4 address."
    }
  } else={
    :log error "[Cloudflare DDNS] No answer from Cloudflare API."
  }
}


Re: Update Cloudflare DNS with script

Posted: Sat Jun 29, 2024 9:59 am
by tangent
Do you have an interface called “wan1”? If not, the script will of course fail. Either change the name to that of your actual WAN interface or rename it to wan1 to placate the script.

Re: Update Cloudflare DNS with script

Posted: Sat Jun 29, 2024 10:07 am
by rextended
Or much more simply, the script is made with the feet, and if the interface wan1 has more than one IP the script fails...

When making a script, all the steps must be validated step by step...

Incomplete example:
Does the interface exist?
It has exactly one IP (neither 0, nor more than 1)???
[or] if it has more than one IP, ignore the local ones (for example 192.168. 100.2/24) etc...

Re: Update Cloudflare DNS with script

Posted: Thu Jul 25, 2024 3:41 am
by msachse
@rextended: Interesting enough, the script works but with a flaw that doesn't come from itself. The interface gets a second IP assigned through IPSec. Now I'm not sure why my VPN Tunnels do that since I am running two and only one is being created by the policies. But if I delete that second address, the script works.

Now to the million dollar question: How do I modify the script so it not only looks for the address on my wan1 interface but also the right one of the two? I tried to combine the statement using AND but get a syntax error in the terminal. Any ideas? I suppose the following line has to be modified:
:local ip4new [/ip address get [/ip address find interface=$wanif] address]
and this doesn't do the trick:
:local ip4new [/ip address get [/ip address find interface=$wanif and address!=10.6.*] address][/code

Re: Update Cloudflare DNS with script

Posted: Fri Jul 26, 2024 1:46 am
by rextended
:local ip4new [/ip address get [/ip address find interface=$wanif] address]

+ "the first assigned only"

=

:local ip4new [/ip address get ([/ip address find interface=$wanif]->0) address]

But what I write before is still valid.

Re: Update Cloudflare DNS with script

Posted: Tue Sep 17, 2024 11:37 pm
by andreacar
Hi,
if it can be useful to anyone, I created a step by step guide to create a DDNS with Cloudflare:
Mikrotik with Cloudflare DDNS

Bye