Community discussions

MikroTik App
 
kw12157
just joined
Topic Author
Posts: 6
Joined: Sun Dec 24, 2017 10:05 pm

Force DDNS update out WAN1

Sun Dec 24, 2017 10:23 pm

I have been using the code below for years successfully. I recently added another WAN interface (WAN2) which is now the default route since it is much faster. I need the DDNS request to go out interface WAN1. How do I modify this script to use ONLY WAN1?

# Dynamic DNS for ChangeIP.com behind NAT
# Modified by Jorge Amaral, officelan.pt
# For support send mail to support at offficelan dot pt
#
# The original script was written by "webasdf" on the Mikrotik foruns, i just modified it to work with ChangeIP.com
#
# Here is where you need to set your definitions
:local user "user_name"
:local pass "password"
:local host "host.dynamic-dns.net"
##############
##############
:global lastwanip;
:if ([ :typeof $lastwanip ] = "nothing" ) do={ :global lastwanip 0.0.0.0 };
:local wanip [:resolve $host];
:if ( $wanip != $lastwanip ) do={
/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
:local result [/file get dyndns.checkip.html contents]
: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]
:set lastwanip $currentIP;
:put [/tool dns-update name=$host address=$currentIP key-name=$user key=$pass ]
}

Thanks in advance,
Kevin
 
User avatar
sebastia
Forum Guru
Forum Guru
Posts: 1782
Joined: Tue Oct 12, 2010 3:23 am
Location: Antwerp, BE

Re: Force DDNS update out WAN1

Sat Dec 30, 2017 4:50 pm

Since you specify the new address in the call, it shouldn't matter from which ip the update is coming:

/tool dns-update name=$host address=$currentIP key-name=$user key=$pass

I've tried that recently with changeip, and it happily updated to the passed ip, independent of the connecting ip.
 
kw12157
just joined
Topic Author
Posts: 6
Joined: Sun Dec 24, 2017 10:05 pm

Re: Force DDNS update out WAN1

Sat Jan 13, 2018 6:03 pm

Sebastia,
Thanks for the reply, but it does matter which IP the update is coming from.
If I go out WAN1 I get the public IP for that GW. If I go out WAN2 I get the public IP for that GW. I want to leave the default route to WAN2 since it is much faster, but I want the ability to connect in via WAN1 in case WAN2 goes down. WAN2 actually goes to another MikroTik and runs the script successfully giving me remote access via the Internet access at that site.
I was able to get a work around working by figuring out the IP address of checkip.dyndns.org and adding a route for that IP with the GW for WAN1.
For a long term solution I think I need either:
1. A change in the script to have if use only WAN1.
2. A script to check the IP of checkip.dyndns.org and update the route if it changes.

Thanks in advance,
Kevin
 
pe1chl
Forum Guru
Forum Guru
Posts: 10223
Joined: Mon Jun 08, 2015 12:09 pm

Re: Force DDNS update out WAN1

Sat Jan 13, 2018 6:59 pm

It is not very useful to post the WAN1 address on a dynamic DNS server when you don't have
the route marking and multiple route tables in place to handle incoming traffic on WAN1 while your
default route is via WAN2.
So, first make that working.
Once that is OK, use /tool fetch with the proper src-address to make the traffic go out via the desired WAN.
 
mbaute
newbie
Posts: 30
Joined: Fri May 22, 2015 3:54 pm

Re: Force DDNS update out WAN1

Fri Jan 26, 2018 4:31 pm

Find netblocks of dyndns.org and add those to routes. You wouldn't need to resolve anything else from from dyndns.org on wan2 right?

We had the same situation but with mikrotik's own ddns. Works everytime
 
pe1chl
Forum Guru
Forum Guru
Posts: 10223
Joined: Mon Jun 08, 2015 12:09 pm

Re: Force DDNS update out WAN1

Fri Jan 26, 2018 4:35 pm

That is not the same thing! For the built-in cloud DNS updates you cannot specify the src-address, but for /tool fetch you can.
(you can specify the exernal address but it is not certain this is used as preferred src-address, probably not)
So it is not needed to use a workaround, you can implement the real and correct solution.
 
kw12157
just joined
Topic Author
Posts: 6
Joined: Sun Dec 24, 2017 10:05 pm

Re: Force DDNS update out WAN1

Sat Jan 27, 2018 7:31 pm

pe1chl,
Thanks for your reply. I only use the DDNS url for management, so I have not put a lot of time into truly making incoming traffic work on WAN1. I am able to connect to the MikroTik there and manage it. I have tried to make getting to other devices that I manage, mainly 7 WiFi APs, connected to 3 different MikroTik routers, but have not been able to get out of the first MikroTik router. So I need to put in more time on that. Some of the fiber is not terminated so the current link to the MikroTik with the 2nd Internet access is via a temp wireless link from a 3rd MikroTik until the fiber gets terminated. Once the fiber is terminated and the permanent configuration is in place I will put more time into that.
I was hoping to resolve the DDNS issue from WAN1 in the meantime...
mbaute adding the IP for dyndns.org is my work around. I am looking for a permanent solution what won't break if the IP of dyndns.org changes.
 
pe1chl
Forum Guru
Forum Guru
Posts: 10223
Joined: Mon Jun 08, 2015 12:09 pm

Re: Force DDNS update out WAN1

Sun Jan 28, 2018 12:20 pm

pe1chl,
Thanks for your reply. I only use the DDNS url for management, so I have not put a lot of time into truly making incoming traffic work on WAN1. I am able to connect to the MikroTik there and manage it.
I'm confused how that could work. Please show your routing configuration.
 
kw12157
just joined
Topic Author
Posts: 6
Joined: Sun Dec 24, 2017 10:05 pm

Re: Force DDNS update out WAN1

Tue Feb 06, 2018 12:34 am

pe1chl,
Thanks for your reply. Here is my firewall mangle and route information.

/ip firewall mangle
add action=mark-connection chain=prerouting disabled=yes in-interface=\
ether9-WAN-DSL new-connection-mark=DSL_Conn_Mark passthrough=no
add action=mark-routing chain=output connection-mark=DSL_Conn_Mark disabled=yes \
new-routing-mark=Out_DSL_Mark passthrough=yes

/ip route
add disabled=yes distance=1 gateway=192.168.10.1 routing-mark=Out_DSL_Mark
add distance=1 gateway=10.20.2.253
add distance=2 gateway=192.168.10.1
add comment="192.168.3.x routed to BB" disabled=yes distance=1 dst-address=\
192.168.3.0/24 gateway=192.168.25.177
add comment="192.168.24.x-192.168.24.x routed to Andy" distance=1 dst-address=\
192.168.24.0/22 gateway=10.20.2.253
add distance=1 dst-address=216.146.43.70/31 gateway=192.168.10.1

Like I said, I can get into the MikroTik to manage it, but can't reach any other devices via WAN1.

I am still looking for a way to get an IP address from a DNS lookup and add that IP to a route. Can you help with that?
 
pe1chl
Forum Guru
Forum Guru
Posts: 10223
Joined: Mon Jun 08, 2015 12:09 pm

Re: Force DDNS update out WAN1

Tue Feb 06, 2018 11:43 am

You need to add an extra mangle rule or ip route rule that matches the traffic with the DSL local address and marks it with the proper route mark.
Maybe there are other issues, it is difficult to do remote debugging with so little info.
 
zivtal
Frequent Visitor
Frequent Visitor
Posts: 57
Joined: Sun Feb 05, 2017 6:22 pm

Re: Force DDNS update out WAN1

Fri Feb 09, 2018 10:47 pm

This is script that I made, Hope it will help you... You can update DDNS via main wan or via specific PPPoE/L2TP/Ethernet/Lte etc,,,..
# Script name (must be same as you called the script)
:local ScriptName "dDNS"

# Define dynamic hosts [example 'INTERFACE|PROVAIDER@DYNAMICHOST' (via interface), example 'PROVAIDER@DYNAMICHOST' (via default gateway/interface)]
:local Hosts "dyndns@yourdomain.dyndns.net,dynu@yourdomain.dynu.net,lte1|dynu@yourdomain2.dynu.net"

# Define accounts [example 'provaider|username@password']
:local Accounts "dyndns|USERNAME@PASSWORD,dynu|USERNAME@PASSWORD"

:if ([:len [/system script job find script=$ScriptName]]>1) do={:error "Another copy of $ScriptName is running.";}

:global UpdateDNS do={
	:local wan $5;
	:local dynprov $1;
	:local dynaddr $2;
	:local dynuser $3;
	:local dynpass $4;
	:local dynhost;
	:local dynurlv;

	:if ($dynprov="dynu") do={
		:set dynhost "api.dynu.com";
		:set dynurlv "/nic/update?hostname=$dynaddr";
	}
	:if ($dynprov="dyndns") do={
		:set dynhost "members.dyndns.org";
		:set dynurlv "/nic/update?hostname=$dynaddr&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG";
	}

	:if (([:len $dynprov]=0) && ([:len $dynaddr]=0) && ([:len $dynuser]=0) && ([:len $dynpass]=0)) do={
		:error "example: \$UpdateDNS <provaider> <domain> <username> <password> <interface>\r\n<provaider>	dyndns dynu\r\n<domain>	mydomain.dyndns.org\r\n<username>	your username\r\n<password>	your password\r\n<interface>	send update by another interface such lte1\r\n";
	} else={
		:if (([:len $dynprov]=0) || ([:len $dynhost]=0)) do={:error "Provaider wan't set or not supported\r\n"}
		:if ([:len $dynaddr]=0) do={:error "Dynamic domain was not set\r\n"}
		:if ([:len $dynuser]=0) do={:error "Username was not set\r\n"}
		:if ([:len $dynpass]=0) do={:error "Password was not set\r\n"}
	}

 	:local ReadFile do={
		:local dynfile $1;
		:local dynaddr [:pick $dynfile ([:find $dynfile "."]+1) [:len $dynfile]];
		:local dynprov [:pick $dynfile 0 [:find $dynfile "."]];
		:local ipaddr;
		:if ([:len [/file find name=$dynfile]]>0) do={
			:local dyndata [file get $dynfile contents];
			:if ($dynprov="dyndns") do={
				:set $ipaddr [:pick $dyndata ([:find $dyndata " "]+1) [:len $dyndata]];
			}
			:if ($dynprov="dynu") do={
				:set $ipaddr [:resolve $dynaddr];
			}
			:if ([:pick $dyndata [:find $dyndata "nochg"] 5]="nochg") do={
				:log info ("<$dynprov> '".$dynaddr."' already updated ($ipaddr) ...");
			} else={
				:log warning ("<$dynprov> '".$dynaddr."' updated ($ipaddr) ...");
			}
		} else={
			:set $ipaddr [:resolve $dynaddr];
			:log warning ("<$dynprov> '".$dynaddr."' has been set ($ipaddr) ...");
		}
		:return $ipaddr;
	}

	:set dynhost [:resolve $dynhost];

   :local WanToIp 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];
    	}
    }

	:local RunOnHostDown do={
		:if ($1!=false) do={
			:local ipaddr [:tostr $1];
			:local ondown [:tostr $2];
			:local wan [:tostr $3];
			:local desc [:tostr $4];
			# If host already not response set delay 10 minutes before run script
			:if ([/ping $ipaddr count=3]=0) do={
				:if ([:len $wan]>0) do={
					:if ([/interface get value-name=type $wan]="lte") do={
						/system routerboard usb power-reset duration=10s
					}
					:if ([:pick [/interface get value-name=type $wan] ([:find [/interface get value-name=type $wan] "-"]+1) [:len [/interface get value-name=type $wan]]]="out") do={
						/interface disable $wan;
						:delay 200ms;
						/interface enable $wan;
					}
				}
				:set $ondown ("/log error \"retry update dynamic dns in 10 minutes.\"\r\n/delay 10m\r\n".$ondown);
			}
			# Create netwatch per hosts, if not exists
			:if ([:len [/tool netwatch find where host=$ipaddr]]=0) do={
				/tool netwatch add host=$ipaddr down-script=$ondown
				/tool netwatch set down-script=("/tool netwatch remove ".[/tool netwatch find where host=$ipaddr]."\r\n\r\n".[/tool netwatch get value-name=down-script [/tool netwatch find where host=$ipaddr]]) [/tool netwatch find where host=$ipaddr]
				:log info ("'$ipaddr' netwatch has been created by script.");
			} else={
				# Set netwatch self remove, if not exists
				:if ([:typeof [:find [/tool netwatch get value-name="down-script" [/tool netwatch find host=$ipaddr]] ("/tool netwatch remove ".[/tool netwatch find where host=$ipaddr])]]="nil") do={
					/tool netwatch set down-script=("/tool netwatch remove ".[/tool netwatch find where host=$ipaddr]."\r\n".[/tool netwatch get value-name=down-script [/tool netwatch find where host=$ipaddr]]) [/tool netwatch find where host=$ipaddr]
				}
				# Set append on-down event (run script)
				:if ([:typeof [:find [/tool netwatch get value-name="down-script" [/tool netwatch find host=$ipaddr]] $ondown]]="nil") do={
					/tool netwatch set down-script=([/tool netwatch get value-name="down-script" [/tool netwatch find host=$ipaddr]].$ondown) [/tool netwatch find host=$ipaddr];
				}
			}
			# Set log 'error' when host is down
			:if ([:typeof [:find [/tool netwatch get value-name="down-script" [/tool netwatch find host=$ipaddr]] $desc]]="nil") do={
				/tool netwatch set down-script=(("/log error \"'$desc' was down.\"\r\n").[/tool netwatch get value-name="down-script" [/tool netwatch find host=$ipaddr]]) [/tool netwatch find host=$ipaddr];
			}
			:if ([:typeof [:find [/tool netwatch get value-name="comment" [/tool netwatch find host=$ipaddr]] $desc]]="nil") do={
				:if ([:len [/tool netwatch get value-name="comment" [/tool netwatch find host=$ipaddr]]]>0) do={
					/tool netwatch set comment=([/tool netwatch get value-name="comment" [/tool netwatch find host=$ipaddr]].", '$desc'") [/tool netwatch find host=$ipaddr]
				} else={
					/tool netwatch set comment=("watching for dynamic hosts '$desc'") [/tool netwatch find host=$ipaddr]
				}
			}
		}
	}

	:local AddSchedulerPerHost do={
		:local schname [:tostr $1];
		:local schcode [:tostr $2];
		:local schtime 3600;
		:if ([:len [/system scheduler find name=$schname]]=0) do={
			/system scheduler add interval=$schtime on-event=$schcode comment=("check dynamic dns proviaders for updates every ".($schtime/60)." minutes.") name=$schname
		} else={
			:if ([:typeof [:find [/system scheduler get value-name="on-event" [/system scheduler find where name=$schname]] $schcode]]="nil") do={
				/system scheduler set interval=$schtime on-event=([/system scheduler get value-name=on-event $schname].$schcode) [/system scheduler find where name=$schname]
			}
		}
	}

	:log info ("<$dynprov> Update '".$dynaddr."' ...");
	:if (([:len [/interface find name=$wan]]>0) && ([/interface get value-name=disabled $wan]=no)) do={
		/ip route add distance=1 gateway=[$WanToIp $wan] dst-address=$dynhost comment="updating '$dynaddr' via '$wan'"
		:delay 800ms;
	}
	/tool fetch address=$dynhost src-path=$dynurlv mode=http user=$dynuser password=$dynpass dst-path=("$dynprov.".$dynaddr)
	/ip route remove [/ip route find where comment="updating '$dynaddr' via '$wan'"]
	$RunOnHostDown [$ReadFile ("$dynprov.".$dynaddr)] ("/log error (\"<$dynprov> '$dynaddr' is offline (netwatch) ...\");\r\n\$UpdateDNS $dynprov $dynaddr $dynuser $dynpass $wan\r\n\r\n") $wan $dynaddr;
	$AddSchedulerPerHost "UpdateDNS" ("/log info (\"<$dynprov> Update '$dynaddr' by scheduler ...\");\r\n\$UpdateDNS $dynprov $dynaddr $dynuser $dynpass $wan\r\n\r\n");
}

:foreach Host in=[:toarray $Hosts] do={
	:local wan;
	:local dynprov;
	:local dynaddr;
	: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 dynaddr [:pick $Host ([:find $Host "@"]+1) [:len $Host]];
	} else={
		:set dynprov [:pick $Host 0 [:find $Host "@"]];
		:set dynaddr [: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]];
	}
	:put ("\$UpdateDNS $dynprov $dynaddr $dynuser $dynpass $wan");
	$UpdateDNS $dynprov $dynaddr $dynuser $dynpass $wan;
}

Who is online

Users browsing this forum: No registered users and 49 guests