OVH.com Dynamic DNS Service update script

If anyone is interested, I made (read modified DynDNS script) an update script for the OVH.com Dynamic DNS Service. Feel free to use, copy, modify, re-publish.

https://github.com/acidsploit/mikrotik-routeros-scripts

:global ovhddnsuser "<OVH DynDNS USER>"
:global ovhddnspass "<OVH DynDNS PASS>"
:global theinterface "<INTERFACE THAT HAS YOUR PUBLIC IP>"
:global ovhddnshost "<OVHDynDNS HOSTNAME>"
:global ipddns [:resolve $ovhddnshost]
:global ipfresh [ /ip address get [/ip address find interface=$theinterface ] address ]
:if ([ :typeof $ipfresh ] = nil ) do={
   :log info ("OVHDynDNS: NO IP address on $theinterface")
} else={
   :for i from=( [:len $ipfresh] - 1) to=0 do={ 
      :if ( [:pick $ipfresh $i] = "/") do={ 
    :set ipfresh [:pick $ipfresh 0 $i]
      } 
}
 
:if ($ipddns != $ipfresh) do={
   :log info ("OVHDynDNS: $ovhddnshost DNS RECORD IP = $ipddns")
   :log info ("OVHDynDNS: $theinterface CURRENT IP = $ipfresh")
   :log info ("OVHDynDNS: UPDATING $ovhddnshost -> $ipfresh")
   :global str "nic/update?system=dyndns&hostname=$ovhddnshost&myip=$ipfresh&wildcard=OFF&backmx=NO&mx=NOCHG"

   # DEBUG fetch command
   #:log info ("OVHDynDNS: /tool fetch address=www.ovh.com host=www.ovh.com src-path=$str mode=https user=$ovhddnsuser password=$ovhddnspass dst-path=(\"/OVHDynDNS.$ovhddnshost\")")
   /tool fetch address=www.ovh.com host=www.ovh.com src-path=$str mode=https user=$ovhddnsuser password=$ovhddnspass dst-path=("/OVHDynDNS.".$ovhddnshost)
   :delay 1

   :global ovhresult [/file get "OVHDynDNS.$ovhddnshost" contents]
   :log info "OVHDynDNS: OVH response: $ovhresult"

   :global str [/file find name="OVHDynDNS.$ovhddnshost"]
   /file remove $str
   
   :if ($ovhresult = "good $ipfresh\n" ) do={
      :log info "OVHDynDNS: SUCCESS"
   } else={
       :log info "OVHDynDNS: FAILED"
   }

   :global ipddns $ipfresh
   :log info "OVHDynDNS: $ovhddnshost DNS RECORD = $ipfresh!"
    } else={
     :log info "OVHDynDNS: We good!"
    }
}

Maybe publish this on the wiki, it could be useful for future reference.

Cheers!

Thanks sploit for the script!
I just found out that OVH has this dynhost option and i thought it would be perfect to use with a mikrotik script.
I’ll give it a try later.
Thanks again!

Some constructive criticism: all these :global could be changed to :local. There is no need to store “state” between runs.

So i can just replace the :global with :local ?
I’m not very good at scripting and very new to mikrotik :wink:

Correct, and you could clean up your environment (/system/scripts/environment) of these variables.

Thanks!
This works very well.
I think in a further step i’m going to remove the “OVHDynDNS: We good!” message if the update was successful.
This is spamming my log/syslog server very much :wink:

Hi,

I’m new here.
Can you tell me what to do if the router is behind een modem ?
So my router has no external ip adres.

Thanks

I had a custom domain at Dyn (DynDNS) which has now been taken over by Oracle. And I’m very disappointed they are ending custom dynamic domains as of next year in March.
I’m keeping a Dyn account for legacy old clients, but I’m moving all my other more recent customers that need Dynamic DNS to OVH DynHost.

Can someone modify this script so it fetches the external IP (not from the eth1 / wan interface), since the MikroTik eth1/wan interface doesn’t always have an external IP…
I saw another ‘DynDNS’ script here first getting the external IP from an OpenDNS website. https://diagnostic.opendns.com/myip
But I could also make my own website instead of OpenDNS for example…

Found another ipv4 checker from Google. https://domains.google.com/checkip

Here is a nifty trick for nginx to make a simple checkip service:

location = / {                                         
        add_header Content-Type text/plain; return 200 $remote_addr;                                                   
    }

Then doing:

curl myip.mydomain.com

Will give you your public ip. I don’t think it can be done any more simple.

Hi,

the script works great as long as the IP address on the WAN really is a public IP. In my case for instance, I have a remote site router behind CG-NAT (LTE connection thanks to a MT LDF LTE6 kit), so the IP I grab is a NAT-ed 100.64.0.0/10, which is to be expected since this is the IP that the ISP allocates to my external WAN interface. Sadly this doesn’t help me much if my dns name resolves to this NAT-ed address of course…

I tried modifying the script to grab the “read” public IP from public IP resolvers for instance v4.ident.me, so I replaced the line
:global ipfresh [ /ip address get [/ip address find interface=$theinterface ] address ]
by
:global ipfresh [ /ip address get [curl v4.ident.me] address ]

but I doesn’t work without any specific fail in the logs…

Could you guys give me a hint of what I’m doing obviousely wrong?
You may have noticed that I’m very bad at scripting, so this may be a good exercice for practicing…

cheers
Denis

This script has stopped working for me. I’m lockerd on “UPDATING” status.

If I uncomment the debug log, that’s all I got :

failure: closing connection: <301 Moved Permanently location="https://www.ovhcloud.com/fr/"> 198.27.92.1:443 (5)

I read on script
www.ovh.com
not
www.ovhcloud.com/fr/

try to change ovh to ovhcloud on script, without put /fr/

Well, this edit won't work. The OVH DynHost need to reach this address in fact

https://www.ovh.com/nic/update?system=dyndns&hostname=$HOSTNAME&myip=$IP

But if this: <301 Moved Permanently location=“https://www.ovhcloud.com/fr/”>
something say to rb that the site is moved, and fetch do not follow redirect…

Well, only the root is redirected actually. I dont understand why fetch is stopped. I might I've done a mistake with this DEBUG command, but I don't know why it did stop working. Does it still work for the others?

I can’t test the service I hope someone that use it try and reply

Well, I installed ddns-updater docker container on my server and succeded to update my A record… So it doesn’t seems that OVH service’s down.

Might it be a firewall filter that might interfer with it?

Not, with that reply: <301 Moved Permanently location=“https://www.ovhcloud.com/fr/”>
can be only an error on script when recomposing the URL…

sorry guys, I didnt see there were replies.

Here is an updated version of the script that updates the real Public IP, even if your router is behind CGNAT, I tested it and it works. Comments are more than welcome if anyone sees anything that could be improved.

:local ovhddnsuser "<OVH_USERNAME>"
:local ovhddnspass "<OVH_PWD>"
:local theinterface "<INTERFACE_NAME>"
:local ovhddnshost "<OVH_DYNDNS_NAME>"
:local ipddns [:resolve $ovhddnshost]
:local ipfresh [:resolve myip.opendns.com server=208.67.222.222]
:if ([ :typeof $ipfresh ] = nil ) do={
   :log info ("OVHDynDNS: NO public IP address linked to $theinterface")
} else={
   :for i from=( [:len $ipfresh] - 1) to=0 do={ 
      :if ( [:pick $ipfresh $i] = "/") do={ 
    :set ipfresh [:pick $ipfresh 0 $i]
      } 
}
 
:if ($ipddns != $ipfresh) do={
   :log info ("OVHDynDNS: $ovhddnshost DNS RECORD IP = $ipddns")
   :log info ("OVHDynDNS: $theinterface CURRENT IP = $ipfresh")
   :log info ("OVHDynDNS: UPDATING $ovhddnshost -> $ipfresh")
   :local str "nic/update?system=dyndns&hostname=$ovhddnshost&myip=$ipfresh&wildcard=OFF&backmx=NO&mx=NOCHG"

   # DEBUG fetch command
   #:log info ("OVHDynDNS: /tool fetch address=www.ovh.com host=www.ovh.com src-path=$str mode=https user=$ovhddnsuser password=$ovhddnspass dst-path=(\"/OVHDynDNS.$ovhddnshost\")")
   /tool fetch address=www.ovh.com host=www.ovh.com src-path=$str mode=https user=$ovhddnsuser password=$ovhddnspass dst-path=("/OVHDynDNS.".$ovhddnshost)
   :delay 1

   :local ovhresult [/file get "OVHDynDNS.$ovhddnshost" contents]
   :log info "OVHDynDNS: OVH response: $ovhresult"

   :local str [/file find name="OVHDynDNS.$ovhddnshost"]
   /file remove $str
   
   :if ($ovhresult = "good $ipfresh\n" ) do={
      :log info "OVHDynDNS: SUCCESS"
   } else={
       :log info "OVHDynDNS: FAILED"
   }

   :local ipddns $ipfresh
   :log info "OVHDynDNS: $ovhddnshost DNS RECORD = $ipfresh!"
    } else={
     :log info "OVHDynDNS: We good!"
    }
}

Didn’t work for me. But I don’t think your modified script is the problem.

One question probably simple, but is there some forbidden caracter inside a string or “” ? Don’t see anyone in the doc, but, just in case..