[admin@MikroTik] > { :local t "1.2.3.4/32"; :put [ :pick $t 0 [ :find $t "/" ] ] }
1.2.3.4
Hello guys...and thanks for the script!
# Define User Variables
:global ddnsuser "my_username"
:global ddnspass "my_password"
:global ddnshost "my_dyndns_domain"
# Define Global Variables
:global ddnsip
:global ddnslastip
:if ([:typeof $ddnslastip] = nil) do={ :global ddnslastip "0.0.0.0/0" }
# Grab the current IP address on that interface.
:global ddnsip [/ip address get [/ip address find interface=my_pppoe_interface] address]
:global ip [ :pick $ddnsip 0 [ :find $ddnsip "/" ] ]
# Did we get an IP address to compare
:if ([:typeof $ip] = nil) do={
:log info ("DynDNS: No ip address present on " . $ddnsinterface . ", please check.")
} else={
:if ($ip != $ddnslastip) do={
:log info "DynDNS: Sending IP:$ip UPDATE!"
/tool fetch keep-result=no url="http://$ddnsuser:$ddnspass@204.13.248.112/nic/update\?hostname=$ddnshost"
:global ddnslastip $ip
# } else={
# :log info "DDNS: No update required."
}
}
}
# End of script
:global ddnsip [/ip address get [/ip address find interface=my_pppoe_interface] address]
:global ip [ :pick $ddnsip 0 [ :find $ddnsip "/" ] ]
:log info $ip
Thank you, Your version of Mikrotik 3.30 earned (without problems).The Script "dyndns-update". Set the local variables username, password and hostname:
Script "dyndns-force". Intended to update dyndns only once every 24 hrs. If you run this too much, you may get locked out of dyndns.
Setup the schedulers. Run dyndns-update every 15 minutes and dyndns-force once every 24 hours:
Same problem with RouterOS Version 4.7.
# Set needed variables
:local username "YourUsername"
:local password "YourPassword"
:local hostname "nohostset"
:global systemname [/system identity get name]
:if ($systemname = "Site1" ) do= {
:set hostname "yourdomain1.dyndns.org"
}
:if ($systemname = "Site2" ) do= {
:set hostname "yourdomain2.dyndns.org"
}
:if ($systemname = "Site3" ) do= {
:set hostname "yourdomain3.dyndns.org"
}
:global dyndnsForce
:global previousIP
# print some debug info
:log info ("UpdateDynDNS: username = $username")
:log info ("UpdateDynDNS: password = $password")
:log info ("UpdateDynDNS: hostname = $hostname")
:log info ("UpdateDynDNS: previousIP = $previousIP")
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "</body>" -1]
:local currentIP [:pick $result $startLoc $endLoc]
:log info "UpdateDynDNS: currentIP = $currentIP"
# Remove the # on next line to force an update every single time - useful for debugging, but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details available at http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $previousIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
:set previousIP $currentIP
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" src-path="/nic/update?hostname=$hostname&myip=$currentIP" dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}
hope so, that my answar will help to someone. i had exactly same problem, and a problem was in default routes in Mikrotik. All my default routes had some routing marks, and i made one without routing mark, and then everything was fine. in this case, Mikrotik was without internet access (i couldn't ping any address or host on internet)Must I leave " " in variable?
I have error in terminal:
invalid value for argument address
WAN is pppoe to ADSL modem
MikroTik RouterOS 3.22
sorry for my English
# Set needed variables
:local username "Login_dyndns.com"
:local password "Password_dyndns.com"
:local hostname "nohostset"
:global systemname [/system identity get name]
:if ($systemname = "MikroTik" ) do= {
:set hostname "site1.dyndns.org,site2.homeip.net,site3.dyndns.org,etc.dyndns.org"
}
:global dyndnsForce
:global previousIP
# print some debug info
:log info ("UpdateDynDNS: username = $username")
:log info ("UpdateDynDNS: password = $password")
:log info ("UpdateDynDNS: hostname = $hostname")
:log info ("UpdateDynDNS: previousIP = $previousIP")
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "</body>" -1]
:local currentIP [:pick $result $startLoc $endLoc]
:log info "UpdateDynDNS: currentIP = $currentIP"
# Remove the # on next line to force an update every single time - useful for debugging,
# but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details available at http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $previousIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
:set previousIP $currentIP
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" \
src-path="/nic/update?hostname=$hostname&myip=$currentIP" dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}
# Set needed variables
:local username "Login_dyndns.com"
:local password "Password_dyndns.com"
:local hostname "siteX.dyndns.org"
:global dyndnsForce
:global previousIP
:set dyndnsForce true
# print some debug info
:log info ("UpdateDynDNS: username = $username")
:log info ("UpdateDynDNS: password = $password")
:log info ("UpdateDynDNS: hostname = $hostname")
:log info ("UpdateDynDNS: previousIP = $previousIP")
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "</body>" -1]
:local currentIP [:pick $result $startLoc $endLoc]
:log info "UpdateDynDNS: currentIP = $currentIP"
# Determine if dyndns update is needed
# more dyndns updater request details available at http://www.dyndns.com/developers/specs/syntax.html
:set dyndnsForce false
:set previousIP $currentIP
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" \
src-path="/nic/update?hostname=$hostname&myip=$currentIP" dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update forced")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
# Set needed variables
:local username "YourUsername"
:local password "YourPassword"
:local hostname "nohostset"
:global systemname [/system identity get name]
:if ($systemname = "Site1" ) do= {
:set hostname "yourdomain1.dyndns.org"
}
:if ($systemname = "Site2" ) do= {
:set hostname "yourdomain2.dyndns.org"
}
:if ($systemname = "Site3" ) do= {
:set hostname "yourdomain3.dyndns.org"
}
:global dyndnsForce
:global previousIP
# print some debug info
:log info ("UpdateDynDNS: username = $username")
:log info ("UpdateDynDNS: password = $password")
:log info ("UpdateDynDNS: hostname = $hostname")
:log info ("UpdateDynDNS: previousIP = $previousIP")
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "</body>" -1]
:local currentIP [:pick $result $startLoc $endLoc]
:log info "UpdateDynDNS: currentIP = $currentIP"
# Remove the # on next line to force an update every single time - useful for debugging,
# but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details available at http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $previousIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
:set previousIP $currentIP
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" \
src-path="/nic/update?hostname=$hostname&myip=$currentIP" dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}
:local hostname "nohostset"
:if ($systemname = "Site1" ) do= {
:set hostname "yourdomain1.dyndns.org"
}
:if ($systemname = "Site2" ) do= {
:set hostname "yourdomain2.dyndns.org"
}
:if ($systemname = "Site3" ) do= {
:set hostname "yourdomain3.dyndns.org"
}
:local hostname [/system identity get name]
# Set needed variables
:global username [/file get user.txt contents]
:global password [/file get password.txt contents]
:global hostname [/file get host.txt contents]
:global dyndnsForce
:global previousIP
:set previousIP [:resolve domain-name=$hostname]
# print some debug info
:log info ("dyndns-update: username = $username")
:log info ("dyndns-update: password = $password")
:log info ("dyndns-update: hostname = $hostname")
:log info ("dyndns-update: previousIP = $previousIP")
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:global result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "</body>" -1]
:local currentIP [:pick $result $startLoc $endLoc]
:log info "dyndns-update: currentIP = $currentIP"
# Determine if dyndns update is needed
# more dyndns updater request details available at http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $previousIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
:set previousIP $currentIP
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" src-path="/nic/update?hostname=$hostname&myip=$currentIP" dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("dyndns-update: Dyndns update needed")
:log info ("dyndns-update: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
} else={
:log info ("dyndns-update: No dyndns update needed")
}
/ip dns
set allow-remote-requests=no cache-max-ttl=1w cache-size=2048KiB \
max-udp-packet-size=512 servers=62.81.0.35,80.58.0.33
hello,
your minirouter has DNS configured?
Code: Select all/ip dns set allow-remote-requests=no cache-max-ttl=1w cache-size=2048KiB \ max-udp-packet-size=512 servers=62.81.0.35,80.58.0.33
# Loop thru interfaces and look for ones containing
# default gateways without routing-marks
:foreach int in=[/ip route find dst-address=0.0.0.0/0 active=yes ] do={
:if ([:typeof [/ip route get $int routing-mark ]] != str ) do={
:global ddnsinterface [/ip route get $int interface]
}
}
what router OS version do you use?Hi
b]/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"[/b]
bad-argument name src-path (line 1 column 52)
What can be the problem?
You should type into On Event: "/system script run "script_name"Hi,
I am using the Dyndns script and this works fine, but I have a problem. I have added this script to the schedule, but It doesn't work.
I don't know why it does not work. If you can give and answer.
Thanks in advance.
I have the same situation like you.How to make the script update 2 pppoe interface?
Same user. 2 host name, 2 pppoe.
:global ddnsinterface "pppoe-out1"
if ([:typeof $ddnsinterface] = nil) do={
# Loop thru interfaces and look for ones containing
# default gateways without routing-marks
:foreach int in=[/ip route find dst-address=0.0.0.0/0 active=yes] do={
:if ([:typeof [/ip route get $int routing-mark]] != str) do={
:global ddnsinterface [/ip route get $int interface]
}
}
}
# Set needed variables
:local username "USERNAME"
:local password "PASSWORD"
:local hostname "HOSTNAME"
:global dyndnsForce
:global previousIP
# print some debug info
:log info ("UpdateDynDNS: username = $username")
:log info ("UpdateDynDNS: password = $password")
:log info ("UpdateDynDNS: hostname = $hostname")
:log info ("UpdateDynDNS: previousIP = $previousIP")
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "</body>" -1]
:local currentIP [:pick $result $startLoc $endLoc]
:log info "UpdateDynDNS: currentIP = $currentIP"
# Remove the # on next line to force an update every single time - useful for debugging,
# but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $previousIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
:set previousIP $currentIP
:log info "$currentIP or $previousIP"
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" src-path="nic/update?system=dyndns&hostname=$hostname&myip=$currentIP&wildcard=no" dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}
# Set needed variables
:local username "xxxxxx"
:local password "xxxxxx"
:local hostname "xxxx.xxx.com"
:global systemname [/system identity get name]
:if ($systemname = "Site1" ) do= {
:set hostname "yourdomain1.dyndns.org"
}
:if ($systemname = "Site2" ) do= {
:set hostname "yourdomain2.dyndns.org"
}
:if ($systemname = "Site3" ) do= {
:set hostname "yourdomain3.dyndns.org"
}
:global dyndnsForce
:global previousIP
# print some debug info
:log info ("UpdateDynDNS: username = $username")
:log info ("UpdateDynDNS: password = $password")
:log info ("UpdateDynDNS: hostname = $hostname")
:log info ("UpdateDynDNS: previousIP = $previousIP")
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "</body>" -1]
:local currentIP [:pick $result $startLoc $endLoc]
:log info "UpdateDynDNS: currentIP = $currentIP"
# Remove the # on next line to force an update every single time - useful for debugging,
# but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $previousIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
:set previousIP $currentIP
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" \
src-path="/nic/update?hostname=$hostname&myip=$currentIP" dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}
thanks a lot,/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:local result [/file get dyndns.checkip.html contents]
:foreach int in=[/ip route find dst-address=0.0.0.0/0 active=yes ] do={
:if ([:typeof [/ip route get $int routing-mark ]] != str ) do={
:global ddnsinterface [/ip route get $int interface]
}
}
:log info "UpdateDynDNS TEST TEST TEST: currentIP = TEST A"
# Set needed variables
:local username "YOUR_USERNAME"
:local password "YOUR_PASSWORD"
:local hostname "YOUR_HOSTNAME"
:global systemname [/system identity get name]
:if ($systemname = "Site1" ) do= {
:set hostname "yourdomain1.dyndns.org"
}
:if ($systemname = "Site2" ) do= {
:set hostname "yourdomain2.dyndns.org"
}
:if ($systemname = "Site3" ) do= {
:set hostname "yourdomain3.dyndns.org"
}
:global dyndnsForce
:global previousIP
# print some debug info
#:log info ("UpdateDynDNS: username = $username")
#:log info ("UpdateDynDNS: password = $password")
#:log info ("UpdateDynDNS: hostname = $hostname")
:log info ("UpdateDynDNS: previousIP = $previousIP")
# CAUTION: YOU NEED TO SELECT THE INTERFACE WHICH HAS YOUR PUBLIC IP. Here this is interface number=1
:local network [/ip address get number=1 address]
#:log info (" network is $network")
:local length [:len $network]
#:log info ("length is $length")
:local currentIP [:pick $network 0 ($length-3)]
:log info ("UpdateDynDNS: fetched IP address is $currentIP")
# Remove the # on next line to force an update every single time - useful for debugging,
# but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $previousIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
:set previousIP $currentIP
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" \
src-path="/nic/update?hostname=$hostname&myip=$currentIP" dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}
# Set needed variables
:local username "username"
:local password "password"
:local hostname "blahblahblah.dyndns.org"
:global dyndnsForce
:global previousIP
# print some debug info
:log info ("UpdateDynDNS: username = $username")
:log info ("UpdateDynDNS: password = $password")
:log info ("UpdateDynDNS: hostname = $hostname")
:log info ("UpdateDynDNS: previousIP = $previousIP")
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "</body>" -1]
:local currentIP [:pick $result $startLoc $endLoc]
:log info "UpdateDynDNS: currentIP = $currentIP"
# Remove the # on next line to force an update every single time - useful for debugging,
# but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $previousIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
:set previousIP $currentIP
:log info "$currentIP or $previousIP"
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" \
src-path="nic/update?system=dyndns&hostname=$hostname&myip=$currentIP&wildcard=no" \
dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" \
src-path="nic/update?system=dyndns&hostname=$hostname&myip=$currentIP&wildcard=no" \
dst-path="/dyndns.txt"
# parse the results of update
:local resultLen [:len $result]
:local startLoc [:find $result "Go" -1]
:local endLoc [:find $result "od" -1]
:local resultParse [:pick $result $startLoc $endLoc]
:log info ("Update was successful: ".$resultParse)
:if (($resultParse = "Good") do ={
:log info ("Update was successful: ".$resultParse)
:set previousIP $currentIP
} else={
:log info ("UpdateDynDNS: Update failed!")
}
it will be external tool, not inside the RouterOS.routed MNDP (CDP)?.. O_o
# Set needed variables
:local username "YourUserName"
:local password "YourPassword"
:local hostname "YourHostName"
:global dyndnsForce
# print some debug info
#:log info ("UpdateDynDNS: username = $username")
#:log info ("UpdateDynDNS: password = $password")
#:log info ("UpdateDynDNS: hostname = $hostname")
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "</body>" -1]
:local currentIP [:pick $result $startLoc $endLoc]
:log info "UpdateDynDNS: currentIP = $currentIP"
#get IP from DynDNS for our hostname
:local resolvedIP [:resolve $hostname]
:log info ("UpdateDynDNS: resolved IP =$resolvedIP")
# Remove the # on next line to force an update every single time - useful for debugging, but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details available at http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $resolvedIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" src-path="/nic/update?hostname=$hostname&myip=$currentIP" dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}
# Set needed variables
:local username "YourUserName"
:local password "YourPassword"
:local hostname "YourHostName"
:global ddnsinterface "YourInternetInterfaceWithDynamicIP"
:global ddnsip ""
:global dyndnsForce
# Remove the # on next line to force an update every single time - useful for debugging, but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Grab the current IP address on that interface.
:global ddnsip2 [/ip address get [/ip address find interface=$ddnsinterface ] address];
:set ddnsip [:pick $ddnsip2 0 [:find $ddnsip2 "/"]];
:log info ("UpdateDynDNS: currentIP = $ddnsip")
#get IP from DynDNS for my hostname
:local resolvedIP [:resolve $hostname]
:log info ("UpdateDynDNS: resolved IP =$resolvedIP")
# Determine if dyndns update is needed
# more dyndns updater request details available at http://www.dyndns.com/developers/specs/syntax.html
:if (($ddnsip != $resolvedIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" src-path="/nic/update?hostname=$hostname&myip=$ddnsip" dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}
where will it run?.. on dedicated server, not on the router itself?..it will be external tool, not inside the RouterOS.routed MNDP (CDP)?.. O_o
better to use one of the dyndns nameservers to resolve the nameelgo: fair comment!
So, here is my version without the continual disk operations
Code: Select all#get IP from DynDNS for my hostname :local resolvedIP [:resolve $hostname] :log info ("UpdateDynDNS: resolved IP =$resolvedIP") ...
:local resolvedIP [:resolve domain-name=$hostname server=204.13.248.75]
Emphasis mine. Doing that may result in all RouterOS devices being blocked from submitting updates (Dyn do that for badly behaved user agents) and possibly even they'll stop reporting a valid value at checkip.dyndns.org.Unacceptable Client Behavior
* Send requests to or access anything other than /nic/update at the host members.dyndns.org.
* Reverse engineer web requests to our website to create or delete hostnames.
* Hardcode the IP address of any of the Dyn servers.
* Attempt to update after receiving the notfqdn, abuse, nohost, badagent, badauth, badsys return codes or repeated nochg return codes without user intervention.
* Perform DNS updates to determine whether the client IP needs to be updated.
* Access our web-based IP detection script (http://checkip.dyndns.com/) more than once every 10 minutes
Note that performing a DNS query to see if the hostname needs updated is in breach of Dyn's policies, as is using checkip.dyndns.org every minute:
Emphasis mine. Doing that may result in all RouterOS devices being blocked from submitting updates (Dyn do that for badly behaved user agents) and possibly even they'll stop reporting a valid value at checkip.dyndns.org.Unacceptable Client Behavior
* Send requests to or access anything other than /nic/update at the host members.dyndns.org.
* Reverse engineer web requests to our website to create or delete hostnames.
* Hardcode the IP address of any of the Dyn servers.
* Attempt to update after receiving the notfqdn, abuse, nohost, badagent, badauth, badsys return codes or repeated nochg return codes without user intervention.
* Perform DNS updates to determine whether the client IP needs to be updated.
* Access our web-based IP detection script (http://checkip.dyndns.com/) more than once every 10 minutes
#To RUN script USE ----->> /system script run dynDns
#
:local ddnsuser "username"
#
# CHANGE PASSWORD, hostname, username and interface to match yours!
#
:local ddnspass "pass"
:local theinterface "eth1"
:local ddnshost "yourhost"
:local ipddns [:resolve $ddnshost];
:local ipfresh [ /ip address get [/ip address find interface=$theinterface ] address ]
:if ([ :typeof $ipfresh ] = nil ) do={
:log info ("DynDNS: 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 ("DynDNS: IP-DynDNS = $ipddns")
:log info ("DynDNS: IP-Fresh = $ipfresh")
:log info "DynDNS: Update IP needed, Sending UPDATE...!"
:local str "/nic/update?hostname=$ddnshost&myip=$ipfresh&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG"
/tool fetch address=members.dyndns.org src-path=$str mode=http user=$ddnsuser \
password=$ddnspass dst-path=("/DynDNS.".$ddnshost)
:delay 1
:local str [/file find name="DynDNS.$ddnshost"];
/file remove $str
:global ipddns $ipfresh
:log info "DynDNS: IP updated to $ipfresh!"
} else={
:log info "DynDNS: dont need changes";
}
}
}
} need changes";
}
}members.dyndns.org src-path=$str mode=http user=$ddnsuser \
password=$ddnspass dst-path=("/DynDNS.".$ddnshost)
:delay 1
:local str [/file find name="DynDNS.$ddnshost"];
/file remove $str
:global ddnslastip $ddnsip
}
}
add name="Tunnel 0" policy=\
ftp,reboot,read,write,policy,test,winbox,password,sniff,sensitive,api \
source=":global LocalSite [:resolve x1.dyndns.org]\r\
\n:global RemoteSite0 [:resolve y1.dyndns.org]\r\
\n/ip ipsec policy set 0 sa-dst-address=\$RemoteSite0 sa-src-address=\$Loc\
alSite \r\
\n/ip ipsec peer set 0 address=\$RemoteSite0"
add name="Tunnel 1" policy=\
ftp,reboot,read,write,policy,test,winbox,password,sniff,sensitive,api \
source=":global LocalSite1 [:resolve x1.dyndns.org]\r\
\n:global RemoteSite1 [:resolve y2.dyndns.org]\r\
\n/ip ipsec policy set 1 sa-dst-address=\$RemoteSite1 sa-src-address=\$Loc\
alSite1 \r\
\n/ip ipsec peer set 1 address=\$RemoteSite1\r\
\n"
add name="Tunnel 2" policy=\
ftp,reboot,read,write,policy,test,winbox,password,sniff,sensitive,api \
source=":global LocalSite2 [:resolve x1.dyndns.org]\r\
\n:global RemoteSite2 [:resolve y3.dyndns.org]\r\
\n/ip ipsec policy set 2 sa-dst-address=\$RemoteSite2 sa-src-address=\$Loc\
alSite2\r\
\n/ip ipsec peer set 2 address=\$RemoteSite2\r\
\n"
Hi, I can confirm that following script works on rb751G-2HnD with RouterOS v5.24. However, remember to check that this script has proper line endings: \r\n. If you are unix or mac user and copied the script from webpage directly to winbox then it probably won't work. Before pasting use external text editor to convert line endings to \r\n.hi. i am trying to setup dyndns to rb750 without success.
the user details are correct since i am checking them on different routers.
these are the steps i followed.
-in winbox i created a new script called dynDNS. there i have added the script from the creator of this thread, but i chenged to my username/passwd/hostname
-then i clicked on the script to run now, to check if it is working. nothing happens. it does not make the correct resolution of the ip to hostname, since dyndns did not get the update.
-in terminal i added the script to run every 1 min.
-reboot
unfortunately dyndns it does not get the info of my new ip to resolve it, everytime i reboot.
how can i fix this issue?
# Set needed variables
:local username "xxxxxxxxxx"
:local password "yyyyyyyy"
:local hostname "yyyyyyyyyyyyy"
:global ddnsinterface "xxxxxxxxx e.g. pppoe-out1 xxxxxxx"
:global ddnsip ""
:global dyndnsForce
# Remove the # on next line to force an update every single time - useful for debugging, but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Grab the current IP address on that interface.
:global ddnsip2 [/ip address get [/ip address find interface=$ddnsinterface ] address];
:set ddnsip [:pick $ddnsip2 0 [:find $ddnsip2 "/"]];
:log info ("UpdateDynDNS: currentIP = $ddnsip")
#get IP from DynDNS for my hostname
:local resolvedIP [:resolve $hostname]
:log info ("UpdateDynDNS: resolved IP =$resolvedIP")
# Determine if dyndns update is needed
# more dyndns updater request details available at http://www.dyndns.com/developers/specs/syntax.html
:if (($ddnsip != $resolvedIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" src-path="/nic/update?hostname=$hostname&myip=$ddnsip" dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}
Try this.... it is slightly modified, but tested yesterday on V.6.rc11Hello,
I have an RB750 with OS 6.0RC12 i try the scripts that found in this topic but no success.
Can some one confirm if the scripts work with OS 6.0RC12?
#SuperScript V.3.0 [20130330]
#Variables definition
:global adslip
:global adsllastip
:global datum [/system clock get date]
:global vrijeme [/system clock get time]
:global ime [/system identity get name]
#IF lastip is non existant - set it to "0"
:if ([ :typeof $adsllastip ] = nil ) do={ :global adsllastip "0" }
#Set variable with actual ADSL address
:global adslip [ /ip address get [/ip address find interface=ADSL ] address ]
#If not existant - log it
:if ([ :typeof $adslip ] = nil ) do={
:log error "=== No IP on ADSL Interface"
} else={
#...if existsi
:if ($adslip != $adsllastip) do={
:local dynuser "+++dynuser+++"
:local dynpass "+++dynpass+++"
:local dynhost "+++dynhost+++"
:log info "=== Updating dns record at DynDNS"
:local str "/nic/update?hostname=$dynhost&myip=$adslip&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG"
/tool fetch address=members.dyndns.org src-path=$str mode=http user=$dynuser password=$dynpass dst-path=("/DynDNS.".$dynhost)
:local mailsender "$ime@something.com";
:local mailrec +++mailrec@something.com+++;
:local mailsubject "IP adresa from /$ime/ $datum $vrijeme";
:local mailbody "$adslip";
:local mailserver [:resolve +++mymailserver+++];
:local mailuser +++mymailuser+++;
:local mailpass +++mailpass+++;
:log info "=== Sending mail"
/tool e-mail send from=$mailsender to=$mailrec subject=$mailsubject body=$mailbody server=$mailserver user=$mailuser password=$mailpass;
#Moving new IP to lastip variable
:global adsllastip "$adslip"
} else={
:log info "=== No IP update needed"
}
}
# Set variables
:local username "username";
:local password "password";
:local hostname "hostname";
:local inetinterface "ether1-gateway";
:local sysdate [/system clock get date];
:local systime [/system clock get time];
:local sysname [/system identity get name];
:local dyndnsForce;
#:set dyndnsForce true;
# Print debug info
#:log info ("DynDNS: username = $username");
#:log info ("DynDNS: password = $password");
#:log info ("DynDNS: hostname = $hostname");
# Check if WAN interface is running
:if ([/interface get $inetinterface value-name=running]) do={
# Get the current IP on the WAN interface
:local currentIP [/ip address get [find interface="$inetinterface" disabled=no] address];
# Strip the net mask off the IP address
:set currentIP [:pick $currentIP 0 [:find $currentIP "/"]];
:log info ("DynDNS: current WAN IP = $currentIP");
# Get resolved IP
:local resolvedIP [:resolve domain-name=$hostname server=8.8.8.8];
:log info ("DynDNS: resolved IP = $resolvedIP");
# Determine if dyndns update is needed
# Dyndns updater request details http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $resolvedIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false;
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" \
src-path="nic/update?system=dyndns&hostname=$hostname&myip=$currentIP&wildcard=no" \
dst-path="/dyndns.txt";
:delay 1;
:local result [/file get dyndns.txt contents]
:log info ("DynDNS: Update needed")
:log info ("DynDNS: Update Result: ".$result)
# Send mail
:local mailsender "routerboard@domain";
:local mailrec "mailbox@domain";
:local mailsubject "IP address from /$sysname/ $sysdate $systime";
:local mailbody "$currentIP";
:local smtpserver "mailserver.domain";
:local mailserver [:resolve domain-name=$smtpserver server=8.8.8.8];
:log info ("DynDNS: Sending mail");
/tool e-mail send from=$mailsender to=$mailrec subject=$mailsubject body=$mailbody server=$mailserver;
} else={
:log info ("DynDNS: No update needed");
}
} else={
:log info ("DynDNS: $inetinterface is not currently running");
}
:local username "user";
:local password "pw";
:local hostname "subnet.domain.be";
:local inetinterface "ether1-gateway";
:local sysdate [/system clock get date];
:local systime [/system clock get time];
:local sysname [/system identity get name];
:local dyndnsForce;
#:set dyndnsForce true;
# Print debug info
#:log info ("EuroDNS: username = $username");
#:log info ("EuroDNS: password = $password");
#:log info ("EuroDNS: hostname = $hostname");
# Check if WAN interface is running
:if ([/interface get $inetinterface value-name=running]) do={
# Get the current IP on the WAN interface
:local currentIP [/ip address get [find interface="$inetinterface" disabled=no] address];
# Strip the net mask off the IP address
:set currentIP [:pick $currentIP 0 [:find $currentIP "/"]];
:log info ("EuroDNS: current WAN IP = $currentIP");
# Get resolved IP
:local resolvedIP [:resolve domain-name=$hostname server=8.8.8.8];
:log info ("EuroDNS: resolved IP = $resolvedIP");
# Determine if dyndns update is needed
# Dyndns updater request details https://www.eurodns.com/products/plugins/documentation/ and http://sourceforge.net/apps/trac/ddclient/wiki/Usage
:if (($currentIP != $resolvedIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false;
/tool fetch user=$username password=$password url="http://eurodyndns.org/update/?hostname=$hostname&myip=$currentIP" dst-path="/eurodns.txt";
:delay 1;
:local result [/file get dyndns.txt contents]
:log info ("EuroDNS: Update needed")
:log info ("EuroDNS: Update Result: ".$result)
# Send mail
:local mailsender "routerboarb@lli.be";
:local mailrec "xx@xx.be";
:local mailsubject "IP address from /$sysname/ $sysdate $systime";
:local mailbody "$currentIP";
:local smtpserver "smtp.voo.be";
:local mailserver [:resolve domain-name=$smtpserver server=8.8.8.8];
:log info ("EuroDNS: Sending mail");
/tool e-mail send from=$mailsender to=$mailrec subject=$mailsubject body=$mailbody ; #configure Email Setting /tool e-mail
} else={
:log info ("EuroDNS: No update needed");
}
} else={
:log info ("DynDNS: $inetinterface is not currently running");
}
}
# Define User Variables
:global ddnsuser "SECONDNAME"
:global ddnspass "PASSWORDtoDYN.COM"
:global ddnshost "NAME.homeip.net"
# Define Global Variables
:global ddnsip
:global ddnslastip
:if ([ :typeof $ddnslastip ] = nil ) do={ :global ddnslastip "0" }
:global ddnsinterface
:global ddnssystem ("mt-" . [/system package get system version] )
# Define Local Variables
:local int
# Loop thru interfaces and look for ones containing
# default gateways without routing-marks
:foreach int in=[/ip route find dst-address=0.0.0.0/0 active=yes ] do={
:if ([:typeof [/ip route get $int routing-mark ]] != str ) do={
:global ddnsinterface [/ip route get $int interface]
}
}
# Grab the current IP address on that interface.
:global ddnsip [ /ip address get [/ip address find interface=$ddnsinterface ] address ]
# Did we get an IP address to compare?
:if ([ :typeof $ddnsip ] = nil ) do={
:log info ("DynDNS: No ip address present on " . $ddnsinterface . ", please check.")
} else={
:if ($ddnsip != $ddnslastip) do={
:log info "DynDNS: Sending UPDATE!"
:local str "/nic/update?hostname=$ddnshost&myip=$ddnsip&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG"
/tool fetch address=members.dyndns.org src-path=$str mode=http user=$ddnsuser \
password=$ddnspass dst-path=("/DynDNS.".$ddnshost)
:delay 1
:local str [/file find name="DynDNS.$ddnshost"];
/file remove $str
:global ddnslastip $ddnsip
}
}
:local username "login"
:local password "pass"
:global hostname "my.com"
:global dyndnsForce
:global previousIP
:local resolvedIP [:resolve $hostname]
#print some debug
#:log info ("UpdateDynDNS: username = $username")
#:log info ("UpdateDynDNS: password = $password")
:log info ("UpdateDynDNS: hostname = $hostname")
:log info ("UpdateDynDNS: previousIP = $previousIP")
:log info ("UpdateDynDNS: resolvedIP = $resolvedIP")
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "" -1]
:local currentIP [:pick $result $startLoc $endLoc]
:log info "UpdateDynDNS: currentIP = $currentIP"
# Remove the # on next line to force an update every single time - useful for debugging,
# but you could end up getting blacklisted by DynDNS!
# Edit: Not really needed anymore... the result is not equal... Update will happen.
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details http://www.dyndns.com/developers/specs/syntax.html
#This is where we check the DNS record against actual result. Thanks to jimstolz76
:if (($currentIP != $resolvedIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
:set previousIP $currentIP
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" \
src-path="/nic/update?hostname=$hostname&myip=$currentIP" dst-path="/dyndns.txt"
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("Update Result: " . $result)
:put ("Dyndns Update Result: " . $result)
} else= {
:log info ("UpdateDynDNS: No dyndns update needed")
}
# Define User Variables
:global ddnsuser "user"
:global ddnspass "passwd"
:global ddnshost "domain.com"
:global ddnsinterface "beeline-l2tp"
:global ddnsip
:global ddnslastip
:if ([:typeof $ddnslastip] = nil) do={ :global ddnslastip "0.0.0.0/0" }
# Grab the current IP address on that interface.
:global ddnsip [/ip address get [/ip address find interface=$ddnsinterface] address]
:if ([:typeof $ddnsip] = nil) do={
:log info ("DynDNS: No ip address present on " . $ddnsinterface . ", please check.")
} else={
:if ($ddnsip != $ddnslastip) do={
:log info "DynDNS: Previous IP was: $ddnslastip"
:log info "DynDNS: Sending new IP:$ddnsip UPDATE!"
/tool fetch keep-result=no url="http://$ddnsuser:$ddnspass@204.13.248.112/nic/update\?hostname=$ddnshost"
:global ddnslastip $ddnsip
} else={
:log info "DDNS: No update required."
}
}
:global ddnsuser "user"
:global ddnspass "passwd"
:global theinterface "beeline-l2tp"
:global ddnshost devabap.com
:global ipddns [:resolve $ddnshost];
:global ipfresh [ /ip address get [/ip address find interface=$theinterface ] address ]
:if ([ :typeof $ipfresh ] = nil ) do={
:log info ("DynDNS: 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 ("DynDNS: IP-DynDNS = $ipddns")
:log info ("DynDNS: IP-Fresh = $ipfresh")
:log info "DynDNS: Update IP needed, Sending UPDATE...!"
:global str "/nic/update\?hostname=$ddnshost&myip=$ipfresh&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG"
/tool fetch address=members.dyndns.org src-path=$str mode=http user=$ddnsuser \
password=$ddnspass dst-path=("/DynDNS.".$ddnshost)
:delay 1
:global str [/file find name="DynDNS.$ddnshost"];
/file remove $str
:global ipddns $ipfresh
:log info "DynDNS: IP updated to $ipfresh!"
} else={
:log info "DynDNS: dont need changes";
}
}
# Define User Variables
:global ddnsuser "user"
:global ddnspass "passwd"
:global ddnshost "devabap.com"
:global ddnsinterface "beeline-l2tp"
:global ddnsip
:global ddnslastip
:if ([:typeof $ddnslastip] = nil) do={ :global ddnslastip "0.0.0.0/0" }
# Grab the current IP address on that interface.
:global ddnsip [/ip address get [/ip address find interface=$ddnsinterface] address]
:if ([:typeof $ddnsip] = nil) do={
:log info ("DynDNS: No ip address present on " . $ddnsinterface . ", please check.")
} else={
:if ($ddnsip != $ddnslastip) do={
:log info "DynDNS: Previous IP was: $ddnslastip"
:log info "DynDNS: Sending new IP:$ddnsip UPDATE!"
/tool fetch keep-result=no url="http://$ddnsuser:$ddnspass@204.13.248.112/nic/update\?hostname=$ddnshost"
:global ddnslastip $ddnsip
} else={
:log info "DDNS: No update required."
}
}
# Set needed variables
:local username yyyy
:local password zzzzzz
:local hostname xxx.dyndns.tv
:global dyndnsForce
:global previousIP
# print some debug info
:log info ("UpdateDynDNS: username = $username")
:log info ("UpdateDynDNS: password = $password")
:log info ("UpdateDynDNS: hostname = $hostname")
:log info ("UpdateDynDNS: previousIP = $previousIP")
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:delay 1
:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "</body>" -1]
:local currentIP [:pick $result $startLoc $endLoc]
:log info "UpdateDynDNS: currentIP = $currentIP"
# Remove the # on next line to force an update every single time - useful for debugging,
# but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $previousIP) || ($dyndnsForce = true)) do={
:set dyndnsForce false
:set previousIP $currentIP
:log info "$currentIP or $previousIP"
/tool fetch user=$username password=$password mode=http address="members.dyndns.org" \
src-path="nic/update?system=dyndns&hostname=$hostname&myip=$currentIP&wildcard=no" \
dst-path="/dyndns.txt"
:delay 1
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
:put ("Dyndns Update Result: ".$result)
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}
I don't know what happened, but I noticed the same problem and hit it with a hammer of suitable size.I have the same problem, my dyndns hostname stopped updating. I 've tried about 8 different scripts and none of them worked. I have a dual wan setup on my rb750gl but a while ago dyndns worked fine. Does anybody know what happened?
Edit: remove spurious blank lines introduced by cut'n'paste.@gbr
did you get it working - can you share?
# Based on a script found on the Internet.Will add attribution if I find it.
# Changed 20150719 by Graeme Ruthven (graeme@kula.co.nz)
# Modified to:
# - update using authentication in URL as original method appeared to stop working.
# This was about the time of the RouterOS 6.30 release, but may be unrelated.
# - Get the previous IP from the contents of the dyndns.txt file, as the global variable
# doesn't appear to persist.
#
# Reference: https://help.dyn.com/remote-access-api/perform-update/
:local username "<dyn.com user name>"
:local password "<dyn.com password or, better, Updater Client Key>"
:local hostname "<dyn.com host name>"
:local emailAddress "<where to send notifications>"
:local url "dummy"
:local previousIP
:global dyndnsForce
:set dyndnsForce false
:log info ("UpdateDynDNS starts.")
# print some debug info
#:log info ("UpdateDynDNS: username = $username")
#:log info ("UpdateDynDNS: password = $password")
#:log info ("UpdateDynDNS: hostname = $hostname")
#:log info ("UpdateDynDNS: previousIP = $previousIP")
# I have some doubt over the persistence of the global previousIP.
# This value should be stored in /dyndns.txt after the last update attempt,
# preceded by the status and a space.
# For status values see: https://help.dyn.com/remote-access-api/return-codes/
:if ([:len [/file find name=dyndns.txt]] > 0) do={
:local ipfile [/file get dyndns.txt contents]
:local ipstart ([find $ipfile " " -1] + 1)
:local ipend [:len $ipfile]
:set previousIP [:pick $ipfile $ipstart $ipend]
} else={
:set previousIP "0.0.0.0"
}
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyn.com" src-path="/" dst-path="/dyndns.checkip.html"
:delay 1
:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "</body>" -1]
:local currentIP [:pick $result $startLoc $endLoc]
# Remove the # on next line to force an update every single time - useful for debugging,
# but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $previousIP) || ($dyndnsForce = true)) do={
:log info ("Changing IP from $previousIP to $currentIP.")
:set dyndnsForce false
:set url "http://$username:$password@members.dyndns.org/nic/update?hostname=$hostname&myip=$currentIP&wildcard=no"
/tool fetch url=$url mode=http dst-path="/dyndns.txt"
# Original code:
# /tool fetch user=$username password=$password mode=http address="members.dyndns.org" \
# src-path="nic/update?system=dyndns&hostname=$hostname&myip=$currentIP&wildcard=no" \
# dst-path="/dyndns.txt"
:delay 1
# :set previousIP $currentIP
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
# email result:
:local output "DynDNS Update Result: $result"
/tool e-mail send to="$emailAddress" subject="DynDNS update $currentTime" body="$output"
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyn.com" src-path="/" dst-path="/dyndns.checkip.html"
:delay 1
:local result [/file get dyndns.checkip.html contents]
No. Go to http://checkip.dyn.com in a browser and you'll see that it returns the current IP address of your Internet connection.@gbr - thank you very much for posting this. I kind of works for me.... have a couple of questions. Note: I am a novice at scripting and still learning.
So I have poured over this sever times - it has been a great learning opportunity. As I understand it this -
goes out to dyndns, grabs the ip address from the hostname and then creates a file named "dyndns.checkip.html". I assumed this should be what shows up on your dyndns hosts page. Mine does not...Code: Select all# get the current IP address from the internet (in case of double-nat) /tool fetch mode=http address="checkip.dyn.com" src-path="/" dst-path="/dyndns.checkip.html" :delay 1 :local result [/file get dyndns.checkip.html contents]
Declares a local variable named "result".Also - what does the :local result command do?
See above. You are misinterpreting the purpose of checkip.dyn.com.When I manually change (break) the IP address on the dyndns page to say 1.1.1.1 - it pulls the old IP address still. When I do an nslookup on the hostname it is correct @ 1.1.1.1.
So when the compare if statement runs - it makes no changes because currentIP and previousIP are the same.
Look at the contents of both dyndns.txt and dyndns.checkip.html after a script run.If I delete the dyndns.txt file and the dyndns.checkip.html file the script works - but only the first time I run it.
Sounds as if resolve is acting as expected - doing a DNS lookup on your host name. I doubt that it's a dyn.com error.Further - If I issue global resolvedIP [:resolve $hostname] - it will pull the correct dyndns address of 1.1.1.1
Is that why mine does not work - is this a dyndns issue? Any help appreciated.
Thanks very much GBR for the help and clarification.@gbr - thank you very much for posting this. I kind of works for me.... have a couple of questions. Note: I am a novice at scripting and still learning.
I have the script I provided working successfully on three routers.
# Based on a script found on the Internet.Will add attribution if I find it.
# Changed 20150719 by Graeme Ruthven (graeme@kula.co.nz)
# Modified to:
# - update using authentication in URL as original method appeared to stop working.
# This was about the time of the RouterOS 6.30 release, but may be unrelated.
# - Get the previous IP from the contents of the dyndns.txt file, as the global variable
# doesn't appear to persist.
#
# Reference: https://help.dyn.com/remote-access-api/perform-update/
:local username "<dyn.com user name>"
:local password "<dyn.com password or, better, Updater Client Key>"
:local hostname "<dyn.com host name>"
:local emailAddress "<where to send notifications>"
:local url "dummy"
:local previousIP
:global dyndnsForce
:set dyndnsForce false
:log info ("UpdateDynDNS starts.")
# print some debug info
#:log info ("UpdateDynDNS: username = $username")
#:log info ("UpdateDynDNS: password = $password")
#:log info ("UpdateDynDNS: hostname = $hostname")
#:log info ("UpdateDynDNS: previousIP = $previousIP")
# I have some doubt over the persistence of the global previousIP.
# This value should be stored in /dyndns.txt after the last update attempt,
# preceded by the status and a space.
# For status values see: https://help.dyn.com/remote-access-api/return-codes/
:if ([:len [/file find name=dyndns.txt]] > 0) do={
:local ipfile [/file get dyndns.txt contents]
:local ipstart ([find $ipfile " " -1] + 1)
:local ipend [:len $ipfile]
:set previousIP [:pick $ipfile $ipstart $ipend]
} else={
:set previousIP "0.0.0.0"
}
# get the current IP address from the internet (in case of double-nat)
/tool fetch mode=http address="checkip.dyn.com" src-path="/" dst-path="/dyndns.checkip.html"
:delay 1
:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
:local resultLen [:len $result]
:local startLoc [:find $result ": " -1]
:set startLoc ($startLoc + 2)
:local endLoc [:find $result "</body>" -1]
:local currentIP [:pick $result $startLoc $endLoc]
# Remove the # on next line to force an update every single time - useful for debugging,
# but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details http://www.dyndns.com/developers/specs/syntax.html
:if (($currentIP != $previousIP) || ($dyndnsForce = true)) do={
:log info ("Changing IP from $previousIP to $currentIP.")
:set dyndnsForce false
:set url "http://$username:$password@members.dyndns.org/nic/update?hostname=$hostname&myip=$currentIP&wildcard=no"
/tool fetch url=$url mode=http dst-path="/dyndns.txt"
# Original code:
# /tool fetch user=$username password=$password mode=http address="members.dyndns.org" \
# src-path="nic/update?system=dyndns&hostname=$hostname&myip=$currentIP&wildcard=no" \
# dst-path="/dyndns.txt"
:delay 1
# :set previousIP $currentIP
:local result [/file get dyndns.txt contents]
:log info ("UpdateDynDNS: Dyndns update needed")
:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
# email result:
:local output "DynDNS Update Result: $result"
/tool e-mail send to="$emailAddress" subject="DynDNS update $currentTime" body="$output"
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}
What does it mean dyndns ttl set to 4 hours?I figured my own issue out. I realized I had the dyndns ttl set to 4 hours, so the router was holding on to the cached DNS value for 4 hours. I set it back done to 60 seconds, now it only does it for a max of 60 seconds.
Sent from my iPhone using Tapatalk
:local ddns do={
:local dynhost
:local dynurlv
:if (([:len $provider]=0) or ([:len $host]=0) or ([:len $username]=0) or ([:len $password]=0)) do={
:error "missing parameters"
}
:if ($provider="dynu") do={
:set dynhost "api.dynu.com"
:set dynurlv "/nic/update?hostname=$host"
}
:if ($provider="dyndns") do={
:set dynhost "members.dyndns.org"
:set dynurlv "/nic/update?hostname=$host&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG"
}
:set dynhost [:resolve $dynhost];
:local wanGateway do={
:if ([:len [/ip dhcp-client find where interface=[:tostr $1]]]>0) do={
:return [/ip dhcp-client get [find interface=[:tostr $1]] gateway]
} else={
:return [$1]
}
}
# All return codes
:global resultcodes {
good="Update successful";
nochg="Update not needed, WARNING: repeated attempts may cause you to be blocked.";
badauth="The username and password pair do not match a real user.";
notfqdn="The hostname specified is not a fully-qualified domain name.";
nohost="The hostname specified does not exist in this user account.";
numhost="Too many hosts (more than 20) specified in an update.";
abuse="The hostname specified is blocked for update abuse.";
badagent="The user agent was not sent or HTTP method is not permitted.";
dnserr="DNS error encountered.";
911="There is a problem or scheduled maintenance on our side."
}
:log info ("updating dynamic dns '$host' from '$provider' ...");
:if (([:len [/interface find name=$interface]]>0) and ([/interface get value-name=disabled $interface]=no)) do={
/ip route add distance=1 gateway=[$wanGateway $interface] dst-address=$dynhost comment="updating '$host' via '$interface'"
:delay 800ms;
}
/tool fetch address=$dynhost src-path=$dynurlv mode=http user=$username password=$password dst-path=("$provider.$host")
:delay 2s
:if ([:len [/file find name=("$provider.$host")]]>0) do={
:local result [/file get value-name=contents [/file find name=("$provider.$host")]]
# Separate return code from IP address
:for i from=0 to=( [:len $result] - 1) do={
:if ( [:pick $result $i] = " ") do={
:set result [:pick $result 0 $i]
}
}
:foreach resultcode,desc in=$resultcodes do={
:if ($result=$resultcode) do={
:log warning ("$provider ($host): $desc")
}
}
} else={
:log error ("Update dynamic dns '".$host."' failed...");
}
/file remove [/file find name=("$provider.$host")]
/ip route remove [/ip route find where comment="updating '$host' via '$interface'"]
}
:do {
## Configuration file
:local fconfig [:parse [/system script get "ddns.cfg" source]]
:local cfg [$fconfig]
:local HOSTS ($cfg->"hosts")
:local ACCOUNTS ($cfg->"accounts")
## Foreach HOSTS
:foreach Host in=[:toarray $HOSTS] do={
:local wan
:local dynprov
:local dynhost
:local dynuser
:local dynpass
:if ([:len [:pick $Host (-1) ([:find $Host "|"])]]>0) do={
:set wan [:pick $Host 0 ([:find $Host "|"])]
:set dynprov [:pick $Host ([:find $Host "|"]+1) [:find $Host "@"]]
:set dynhost [:pick $Host ([:find $Host "@"]+1) [:len $Host]]
} else={
:set dynprov [:pick $Host 0 [:find $Host "@"]]
:set dynhost [:pick $Host ([:find $Host "@"]+1) [:len $Host]]
}
:if ([:len [:pick $ACCOUNTS (-1) ([:find $ACCOUNTS "|"])]]>0) do={
:foreach account in=[:toarray $ACCOUNTS] do={
:if ([:pick $account 0 [:find $account "|"]]=$dynprov) do={
:set dynuser [:pick $account ([:find $account "|"]+1) [:find $account "@"]]
:set dynpass [:pick $account ([:find $account "@"]+1) [:len $account]]
}
}
} else={
:set dynuser [:pick $ACCOUNTS 0 [:find $ACCOUNTS "@"]]
:set dynpass [:pick $ACCOUNTS ([:find $ACCOUNTS "@"]+1) [:len $ACCOUNTS]]
}
:if ((([:len $interface]=0) and ([:len $wan]=0)) or ($wan=$interface)) do={
$ddns provider=$dynprov host=$dynhost username=$dynuser password=$dynpass interface=$wan
}
}
}
:local config {
"hosts"="dynu@YOURDOMAIN,dyndns@YOURDOMAIN,INTERFACE|dynu@YOURDOMAIN";
"accounts"="dyndns|USERNAME@PASSWORD,dynu|USERNAME@PASSWORD";
"storage"="";
}
return $config
/interface pppoe-client monitor INTERFACE once do={
:local uptime ([:tonum [:pick [:tostr $uptime] 0 2]]*60*60+[:tonum [:pick [:tostr $uptime] 3 5]]*60+[:tonum [:pick [:tostr $uptime] 6 8]])
}
:if ($uptime<3) do={
/system script run ddns
}