DynDNS update script

I know there were several DynDNS update scripts out there, and they do work, but they don’t work as needed to really stay within the TOS at DynDNS. [Like causing a nochg update after a reboot, since they don’t keep IP states across reboots, or querying the IP more often than allowed.]

They use a “old” version of the update process - while it still works, it’s not current. This has been updated.

They also didn’t actually check the return status codes from an update and if they got a bad status code, wouldn’t handle the error properly. I think those issues should be resolved in this code.

Also, writes to flash could be greater than needed. [Though the sizes were so small, it’s unlikely to be a problem.] We only write to flash when the IP is updated successfully at DynDNS.

The code style isn’t totally uniform (sorry), and there are TONS of comments in the script itself, so there’s no “documentation” outside the script itself.

I’m glad for feedback, if you have it.

It only handles DynDNS updates for a single interface, and would require some re-working to handle more than one.

[This shouldn’t be a common request, but if someone wants it, I’m glad to do it for a fee. I’m giving this out “free” simply because I needed the functionality and wasn’t happy with the alternatives out there. However, if I’m going to code something I don’t actually need, then it’s going to be when I get around to it - which will be a snowballs chance in, well you know where…or I’m going to have to charge for it.]

Glad to take comments, bug-fixes etc.
Please take a minute if you use the code to let me know if worked and what hardware/ROS version you used.

-Greg


I’ve updated the code - I believe I just removed some comments that don’t apply any more. [They got left by accident.]
I don’t believe there’s any code change.

\

Updated 2012/03/26
New version 1.0.5
Change to script - will check if “lastip” file exists and create if not. This saves the user from having to manually create the file by hand.

[I don’t recall any other changes…]


Updated 2012/04/01
New version 1.0.6.

Fix to the problem where we’d create the “lastip.txt” file and then promptly read garbage data. Also, changes to the notes/comments for file naming got-cha’s.

If you have an older version, you don’t need this one, but for new installs the newer one is probably better - less chance of the user borking themselves.
dyndns-published-1.0.6.rsc (8.43 KB)

Just a follow-up

If you use this script, could you please

  1. Let me know if it worked or not.
  2. What hardware it was on
  3. What ROS version
  4. Comments or suggestions.

Finally, if you adapt the code, would you be so kind as to relate that back to me:
What revisions did you make and why?
I’d like to try to add your code to the script, so if you could send me the code, it would be helpful.
[No promise that I will, but it’s most likely if I get the code.]

Oh, and Karma would be nice! :slight_smile:

-Greg

Hi Greg,

  1. It works! Praise the Omnissiah :slight_smile:
  2. RB750G
  3. RouterOS 5.14
  4. No comment, please move along.

No, really, there is one thing that may make it even better: to have it wait for a couple of seconds before checking external IP. I have PPPoE over LAN, and it takes about 5 seconds from router boot to connect. Unfortunately the script runs before that, so startup schedule returns nothing.

Otherwise it runs without problems every 5 minutes by scheduler, and after I have PPPoE connected, it updates fine.

Thank you for the script. This is actually the second that works on my router (the other being Jürgens’ from 2009), but now that it’s installed, I’ll keep this one.

Hi, and thanks for the great work!

  1. It works, but with error!
  2. RB750G
  3. 5.14
  4. Script slightly modified to work with Loopa.se,
    :set vlocalurl (“http://” . “$username” . “:” . “$password” . “@” . “dns.loopia.se/XDynDNSServer/XDynDNS.php” . “?” . “hostname=” . “$hostname” . “&myip=” . “$currentIP”)

Log shows
23:37:38 script,info UpdateDynDNS: Dyndns update needed
23:37:38 script,info DynDNS Update FAILED
23:37:38 script,info UpdateDynDNS: Dyndns Update Result: nochg

The update works, but the log indicates something went wrong.

a “nochg” means it tried to post an update, but the IP hadn’t changed. [At least that’s what it means for DynDNS…]

If setup as per the documentation in the “header” of the script, it shouldn’t generate nochg updates - at least not generally.
[Perhaps it could generate one the very first run, if the lastip file didn’t contain the real last ip address.]

However it shouldn’t do updates unless the address changes - so you shouldn’t ever get nochg updates after that.

Thanks for the feedback anyway!

-Greg

Update to the code.

See the first post in the thread for details and for the download link.

-Greg

Hi,

(RouterOS - 5.14 on a RB751U-2HnD)

I just attempted to copy/paste the script into winbox after editing the username/password/hostname/interface variables. However, the script gets stuck, and I’ve noticed the following…

  • Seems that line 90 captures the output of the file listing as the content for dyndns-lastip.txt. I even put the IP address directly in the file, and I get the following for the conent
# mar/28/2012 21:51: 9 by RouterOS 5.14
# software id = XXXX-XXXX
#
 # NAME           TYPE                                SIZE CREATION-TIME       
 0 skins          directory                                dec/31/1969 20:00:50
 1 base-co... script                            24 450 jan/01/1970 20:03:03
 2 sys-note.txt   .txt file                              0 jan/01/1970 20:03:32
 3 pub            directory                                mar/28/2012 15:13:07
 4 export-2012... script                            13 271 mar/28/2012 15:21:39
 5 dyndns-resp... .txt file                              0 mar/28/2012 21:50:58
 6 dyndns-last... .txt file                              0 mar/28/2012 21:50:58
 7 backup-28.b... backup                            54 847 mar/28/2012 15:21:39
  • I bypassed the above file check altogether, but script appears to be stuck at set command in line 97.

Also, because this script will be used behind a proxy server, is there a way to ensure that the interface IP is the one used, rather than the proxy IP from the upstream proxy server?

I’m sure it’ s something simple.

Thanks,

Carlos.

The code in lines 87-94 check to see if the file specified in lin 69 [vLastIPFileName] exists, and if it doesn’t it creates it.
The creation is simply a print of the root directory of your RB. [Which is what you’re seeing in that file…]

…Ah, the light turns on for me!

I’d guess what is happening is that the first run, the file doesn’t exist, so it creates it, then immediately tries to read it, which won’t produce anything useful.

We need to add a couple of lines to populate it with a temporarily bogus IP.
[I must not have tested for this condition…I thought I had, but alas, I must not have…]

Lets try this.
Replace line 93 with this

/file set [/file find name=$vLastIPFileName] contents="1.2.3.4"

Then, delete the file specified in Line 69 off the the RB. [This will force it to re-create the file, and test our new code…]

Then run it again and let me know what happens.

-Greg

Seems nothing has changed. I started to do a bit of debug, and it seems that the check for the file always generates a new dyndns-lastip.txt file. I tried a new search for file, that always created a new file:

:local found "0";
:foreach i in=[/file find] do={
	:local filename [/file get $i name];
	if ( $filename = $vLastIPFileName) do={
      :set found "1"
	  :log info ("found file")
	}
}
if ( $found = "1" ) do={
   :log info ("DynDNS: LastIP File Found")
}
if ( $found = "0" ) do={
   :log info ("DynDNS: LastIP File Not Found")
    /file print file=$vLastIPFileName
	:delay 2
	/file set [/file find name=$vLastIPFileName] contents="1.2.3.4"
}

And that was still not working. So I removed the “/” from the file names in the variables and it started to work just fine.

Update to code, to add to comments, and fix a read from an “un-initialized” file for the last-ip store.

Thanks to @carlosmp for running the issue down and providing a clear explanation of his findings!

-Greg

Working code if any of you use no-ip.com as your DDNS provider.

:set vlocalurl (“http://” . “$username” . “:” . “$password” . “@” . “dynupdate.no-ip.com” . “/nic/update?hostname=” . “$hostname” . “&myip=” . “$currentIP”)

@mitzone

Thanks!

I’ll add that in the code, and this script can be used for either NoIP or DynDNS.

-Greg

Hi, and thanks for the great work!

  1. It works great..
  2. RB750
  3. 5.10 & 5.4
  4. Will it be possible for the script to look at any wan ip instead of specifying a specific wan interface. Reason: I have a few different ISP account’s, I only run one at a time, if I need to use another ISP Account, I just disable 1 (pppoe-client) and enable the other…
    Because of this I’ll have to edit the script each time to specify the correct interface example pppoe-out1 or pppoe-out2 etc

With the old script it used to update whichever pppoe connection was enabled.

Thanks for all the work you put into the script :slight_smile:

So, let me ask, since I simply don’t use PPPoE etc - how do you know what WAN interface to check.

[If you can, can you give me a code snippet that would help me along.]

Part of the reason I’ve written it the way I have is that for virtually all of my installs, we have regular eth interfaces that get IP’s via DHCP and I may have more than one. So I want the script to be dedicated to updating a DNS record for that one specific interface. If I have two, they can both run and both update their respective interfaces. [Thus the serialization of the response file-names etc, so they don’t tangle with each other.]

So, I may be able to put something like this in, but it does change the nature of the code substantially. But I’m not at all sure how to determine which interface is “active” - so if you’d point that out for me, I’d be glad to spend a little time trying to code it. [Or perhaps point me at another utility which does do it and I’ll look at how they accomplished it and code up an appropriate analog for this script.]

Finally - would you be willing to test for me?

-Greg

Hi,

  1. It worked.
  2. RB1100AH with multi wan
  3. ROS 5.18
  4. possible to add multi wan update in one script instead of one script for each wan interface? and option to enable force update every 24h with dyndns?

Thanks for the feedback.

and option to enable force update every 24h with dyndns?

I could add this, but it’s very much against the TOS. I’m not sure what the limits are set at for DynDNS, so I’m not sure if a forced 24h set would get you on the wrong side… I just think it’s a bad idea.

Also, writing the code to handle state seems a bit daunting. [You’d have to keep last update date/time & state across a reboot.]
NAND file read/write support is really pretty sketchy - so I don’t fancy writing this code very much.

(And I’ve not used any date/time comparisons in RoS, but I can’t imagine them working very well when so much else really doesn’t. )

I guess I just see pretty significant time involvement to rework (& debug) the script to to something that’s very explicitly and directly against the TOS at DynDNS. Since following the TOS is one of the prime reasons I re-wrote the script in the first place, I’m not eager to add options to violate it.

Unless someone comes up with some sweetener, I’m not likely to tackle it. :slight_smile:

If you decide to do it, and write some good documented code, I might add/merge it though.

  1. possible to add multi wan update in one script instead of one script for each wan interface?

This is much more do-able…

I could do this, but I am not sure I see the need. On multi-wan installations, DHCP isn’t very common anyway. To have multiple DHCP clients on a multi-wan setup is even more uncommon. [I have multi-WAN connects that have a single DHCP, but none that have more than one.]

The additional work to support multiple DHCP WAN legs is non-trivial. And to do that work to save the very occasional end-user the work of a more-than-one script setup seems like pretty diminishing returns. So, while it is more feasible, I don’t think it warrants the investment of time - at least on my part.

Sorry I am not giving the answers you probably want, but that’s how it seems to me.

-Greg

Hello,

I’m using the script with file creation and it works great, however, I’m a bit concerned of the internal flash, since it will die in time (long time - but still)… at this time I see this: Bad Blocks - 0.2%…
I connected a 2GB USB flash to my RB751G-2HnD and formatted it - it sees it but I can’t change the script to use the USB1 for creation and query of the dyndns-resp.txt and dyndns-lastip.txt on the flash.

If possible, could you please help me with that?

Thank you,
Alex

I only have just a second.

See this thread:
http://forum.mikrotik.com/t/sector-writes-how-big-is-a-sector/55752/1

Now, I’m not sure how much to trust that estimate of 100K writes per block, but even if we assume half the writes they claim in spec, we’re still talking a LOT of writes before your flash will die. [Even one-tenth will be a lot.]

I’ll see if I can dig up code where I’ve done this, but you should be able to do so do. Essentially you’ll just prefix the file name with a path+file name - where the path points to the flash drive.

One of the scripts I’ve written I started to include paths to the SD drive - so look in the comments - it may be in this script. If not, then look at my other posts. It may be in the netwatch script I’ve written, if not the dyndns one.

If I have time, I’ll try to dig it up - but again, you should be able to figure it out from the code/comments I have left.

[But lastly, none of my scripts write to flash unless something changes. Since your IP isn’t likely to change often, then the script will only be writing to flash when that happens. The stress of those changes is going to be exceedingly small. (Like, I’d guess, with a change every single day, the sun will likely be nearly running out of hydrogen to fuse by then.)

If you’re writing to flash too much, look elsewhere for a cause - it’s not my dyndns script unless there’s some really horrible bug I’ve missed and no-one else has noticed either…it could possibly be, but I don’t think so.]

-Greg

Hello,

I tried to adjust the script to write on usb flash, but for some reasons it creates the files with the directory tree listing in it, instead of the required output…

Did anyone had a success with this?

Thank you,
Alex

I have tested it writing and reading from flash.

As the docs/comments say - use something like this.
:local vLastIPFileName “micro-sd/dyndns-lastip.txt”
and/or
:local vDynDNSResponseFile “micro-sd/cc-dyndns-resp.txt”

[I assume you would want both on flash, or both not on flash…]

I don’t have a unit handy to test with, but my sd volume was named as above, and it worked fine.
[I haven’t created an SD volume for a while so I don’t recall exactly how they are named, but perhaps yours isn’t called “micro-sd” - and it should be something else. Check system|store in WinBox.]

As for writing a directory - that’s “normal” If the file doesn’t exist, it has to create it, and the only way to create it is to pipe a RoS file listing to the specified file. [You can avoid having the system create the files by creating them yourself and leaving them empty. Then the script will see they exist and not try to create them with the “garbage” initial data. But in either case, it shouldn’t impact the operation of the script, at least that I’m aware of.]

Once it does that, it should then use the file with the file listing contents and put the results of the either the last-ip or the dyndns fetch results there.


Are you sure the script is running properly? Check the log, [just “Log” in winbox]. For example, if the “fetch” fails, the script will bomb in the middle and the two files won’t get any proper data written to them. [You can post back what the logs show…and I’ll see if I can help.]

Let me know - someone else recently had a problem with the fetch failing, but they never figured out what was wrong, and it works fine here - so if there’s some odd bug, tracking it down would be helpful.

-Greg