My old scripts and schedulers used to have a lot of hard coded values, were limited to only two gateways, did not utilize functions and were fairly inconsistent.
After nearly two years of putting it off and the acquisition of my new toys, I finally found the time to sit and rewrite the entirety of the scripts that I use on a daily basis.
Don’t know if I should be posting here since there are no other replies, but it says to do so in the Github, so here I am.
I keep getting errors saying my variables are empty or contain invalid values in every module. I even tested it with the same values you put in the example, only changing the IP address on WANGateways, but can’t make it work. I mainly wanna test your failover script in place of another I have, but also liked the DNS one and would like to set it up as well.
Please, if you can help me on this issue. I’m running the 6.44.3 version, if that’s relevant. Thank you in advance.
Apologies for the late reply, due to my fairly busy daily schedule this one managed to slip under my radar.
This behavior occurs when the configuration file is saved with the UNIX (\n) instead of Windows (\r\n) EOL scheme.
I have rolled out an update (to the parser function) where it properly detects and adjusts the EOL sequence, which fixes the issue.
Thank you for reporting this to me and for your patience.
Hi, please assist.
Irrespective of the values used I am getting the message:
"Provision][Error]: Gateways configuration for XXXXXXXXX does not have a corresponding default route.
[Provision][Error]: Gateways configuration for XXXXXXXX does not have a corresponding default route.
[Provision][Error]: The gateways configuration is invalid, please check the config file and try again.
****** Script output ********
[admin@MikroTik] > /import RouterSCRIPTS_Installer.rsc
[RouterSCRIPTS][Info]: Install finished. Assuming you have read through the supplied readme file, you may now remove any modules that you have no use for, then run:
$provision auto
Script file loaded and executed successfully
[admin@MikroTik] > $provision auto
[Provision][Info]: Provisioning all available modules.
[Provision][Info]: Provisioning gateways.
[Provision][Error]: Gateways configuration for Vodafone does not have a corresponding default route.
[Provision][Error]: Gateways configuration for Verizon does not have a corresponding default route.
[Provision][Error]: The gateways configuration is invalid, please check the config file and try again.
[Provision][Info]: Provisioning failover.
[Provision][Error]: The failover module depends on the gateway selector module, please provision it and try again.
[Provision][Info]: Provisioning dyndns.
[Provision][Info]: Provisioning resolver.
[Provision][Info]: Provisioning livestream.
[Provision][Error]: Completed with errors.
[admin@MikroTik] >
The provisioning script is complaining because you haven’t designated corresponding routes to the connections you have defined in your cfg file.
From the readme file:
WANGatewayPrefix: > The comment prefix to use for identifying default gateway routes in the routing table
The value which follows this configuration variable, must be present as a comment (I personally prefer to prefix it but it doesn’t matter), on the 0.0.0.0 routes of each gateway defined in the cfg file.
The corresponding routes are being matched/designated via their comment and gateway fields. Without the comment being in place, the script cannot guess which ones to utilize for it’s functions.
An example (using values from the readme) cfg file of:
Regarding the distance: The allowed range is from 1 to 2. Because you have declared two gateways in the cfg file.
If you had declared three gateways in the cfg file, then it would’ve been from 1 to 3 and so on..
Hi Frostbyte,
thank you for the script! is very interesting. I’m doing some experiments but I have a problem, I cannot make it work. How can the Failover script check the WAN reachability of the WAN target through the various secondary gateways if the current default route of the Mikrotik router is on the active gateway? I mean, if I try to ping the WAN target (e.g. 8.8.8. from the 2nd gateway interface the response is ICMP timeout even if the 2nd gateway has full Internet connectivity. The ICMP request does not go out on the 2nd gatewa interface, so the entire script assumes that the 2nd gw has not WAN connectivity. I have to do something with NAT? Actually I’m only masquerating with src nat to the two gateway interfaces
I have a routerboard with two ISP Internet connections.
ping count=<# of Attempts> interface=
The bold part in red is what forces the ping to actually go out from the proper WAN Interface, regardless of what the currently active gateway is.
In order to better understand where the problem lies, some additional information is required:
The contents of the *.cfg file you’re trying to provision the device with.
The output of the following commands (in terminal) from the device:
Dear Frostbyte, thank you for the reply. I’m not completely sure about function of the “interface=” option of the ping command. According to me this command option is used to recursively learn the IP address associated to the specified interface and than create a ping packet with source IP address the IP address of that interface. However this not means that the ping will exit from that interface, because if the destination address of the ping is not in a local network the router still looks at the actual default gateway to decide to which dest address send the packet and accordingly on which interface. But I’m not an expert about Mikrotik world, so I can mistake.
All of this to say that in my small lab your script seems not able to ping the target host from the 2nd path to verify the connectivity, so it can’t switch to the 2nd ISP when the first fails. Could you please help me?
Thanks a lot!
I attach the output of your commands, also the ping command.
[admin@MikroTik] > /ip address print detail
Flags: X - disabled, I - invalid, D - dynamic
0 ;;; defconf
address=192.168.80.1/24 network=192.168.80.0 interface=bridge actual-interface=bridge
[admin@MikroTik] > /ip route print detail
Flags: X - disabled, A - active, D - dynamic, C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme, B - blackhole, U - unreachable, P - prohibit
0 A S ;;; Default route
dst-address=0.0.0.0/0 gateway=192.168.10.1 gateway-status=192.168.10.1 reachable via ether1 distance=1 scope=30 target-scope=10
1 S ;;; Default route
dst-address=0.0.0.0/0 gateway=192.168.88.1 gateway-status=192.168.88.1 reachable via ether5 check-gateway=ping distance=4 scope=30 target-scope=10
[admin@MikroTik] > $provision auto
[Provision][Info]: Provisioning all available modules.
[Provision][Info]: Provisioning gateways.
[Provision][Info]: Provisioning failover.
According to the documentation, the “interface” parameter applies a “Which interface to use” restriction to the command, so the ping is forced to exit from that interface. Since there is a route (0.0.0.0/0) to your target address (8.8.8.8 ) where it’s gateway (192.168.88.1) belongs in the same subnet (192.168.88.0/24) that your interface (ether5) participates in, the ping should go through, otherwise it should fail. Once we get your setup working, you will be able to verify this yourself as well (by actually bringing down connections).
This is a bit weird. On the surface there doesn’t seem to be anything wrong with what the scripts are expecting to find. (That means that, concerning the scripts at least, the configuration should be valid).
However, I find two things which are alarming:
The provision command did not end with a success/failure message. (If you didn’t crop it on purpose, something may have went wrong, which we will need to investigate)
Assuming your interface, address, route and firewall (since you mentioned you’re NATing) configurations are proper; you should be able to ping with that last command. Something is definitely going on with the configuration of the device in general.
As a small experiment, could you try disabling the route #0 (dst-address=0.0.0.0/0 gateway=192.168.10.1) and try a ping to 8.8.8.8 without the interface parameter? Does it succeed?
Thanks for putting this together!
I’m trying to make it work, however my problem is that I have just one physical interface where your script seems to rely on two interfaces to work, by using ping with source interface, am I right?
Is there a way I could make this work only with one interface?
If you have only one internet gateway/connection, then no.
Unless you’re planning to perform a “proof of concept” test, which can be achieved by utilizing/configuring multiple MikroTik devices/VMs.
Technically you need at least two different internet gateways/connections so you can have a proper failover. There is no point to it otherwise, I’m sure you can understand why.
Furthermore the provision algorithm explicitly disallows for duplicate values in WANNames and WANGateways, so you can’t bypass it by inputting the same information twice in the configuration file.
Answer #2:
In case you have two or more different internet gateways/connections, but accessible through the same interface or on the same subnet, it will still be required of you to split them into different subnets and interfaces (bridges and vlans are allowed too). This limitation exists because there’s no other clean way (without confusing the scripts, that is) to differentiate between the available gateways when checking for each one’s internet availability.
As per the documentation available on github:
You can only have one gateway per subnet. Multiple gateways over the same bridge/master-interface are > not supported
Disclaimer: If you’re after the Balancing functionality of the gateway module, it is assumed (besides having two different internet gateways/connections) that you know your way around configuring PCC Load Balancing, to achieve a desirable result. Since all that option provides for, is an on/off toggle (sensitive to internet outages) for mangle rules with a matching comment prefix (as defined in the configuration file).
Thanks for the reply.
Sorry I forgot to mention, yes I have 2 different gateways in two different subnets on the same interface.
I have tried to fiddle a litte with VLAN’s but it’s been a while, I couldn’t make it work as I’m doing
GW1
--------------untagged,no vlan-------------RouterBoardETH1
GW2
On that scenario I have to get the RB to tag the ingress packets and untag back to a couple of bridges inside that same eth1… or something like that. I’m a bit rusty with VLANs and I’m thinking it might be overkill for my situation so I’m considering just implementing recursive without script instead, although I really like the toggle functionalities of your script.
In that situation and if utilizing the scripts is the desirable goal, there are two options to consider:
Connect GW1 and GW2 onto two different physical ports of the RouterBoard device.
Pass GW1 and GW2 as tagged VLANs through a single physical port of the RouterBoard device.
At this point I’m completely unaware of your exact physical setup and as to why you’re not just connecting CPE1 to one physical port of the RouterBoard device and CPE2 to another.
That would appear to be the simplest method both physical-wise and configuration-wise (just remember: different subnets, different interfaces).
Now, in case there is some complication or particularity that I am missing (and I probably might be), let’s assume the diagram you drew above.
I would not consider option 2 to be an overkill (since you would have one cable reach the RouterBoard device and one of it’s physical ports occupied, instead of two). Though you will have to ensure that the combined bandwidth of GW1 and GW2 does not exceed the speed specification of the RouterBoard device port that you’re plugging into (to avoid a potential bottleneck).
If you choose to bring in GW1 and GW2 as tagged VLANs over the same physical port of your RouterBoard device, things are really simple from there and onward:
You create two VLANs, each with it’s respective VLAN ID (that you tagged it with on the other side) and with the physical port that you’re passing them through as the Interface (RouterBoardETH1 in your case). Then you go into IP > Address and you assign a corresponding address and subnet mask to each one of the VLANs you created (remember, different subnets). Lastly, you go into IP > Route and you create your two routes (make sure to peruse the github documentation as the distances and comment contents on this step are important).
At this point I’m completely unaware of your exact physical setup and as to why you’re not just connecting CPE1 to one physical port of the RouterBoard device and CPE2 to another.
That would appear to be the simplest method both physical-wise and configuration-wise (just remember: different subnets, different interfaces).
These are two wan gateways that are physically on the other side of the city. The link where both are accessible via Layer3 arrives through P2P on a single cable to eth1. It doesn’t make sense to re-split into two cables. This is a bit of a temporary scenario for until I have the ability to have 2 physical links coming to the RB.
You create two VLANs, each with it’s respective VLAN ID (that you tagged it with on the other side) and with the physical port that you’re passing them through as the Interface (RouterBoardETH1 in your case). Then you go into IP > Address and you assign a corresponding address and subnet mask to each one of the VLANs you created (remember, different subnets). Lastly, you go into IP > Route and you create your two routes (make sure to peruse the github documentation as the distances and comment contents on this step are important).
I don’t have means to tag on the other side at the moment but will soon. Since it’s a 3011UIAS it should be ok to cope with traffic. I will try that again, for the time being the recursive failover is working.
Thanks!
Two WAN interfaces, the $failover check command times out when attempting to ping the external IP:
[admin@xxxxx] > $failover status
[Failover][Info]: Failover status: Active.
[Failover][Info]: ether1: Online (up for at least 00:01:15)
[Failover][Info]: ether2: Offline (down for at least 00:01:15)
[admin@xxxxx] > $failover status
[Failover][Info]: Failover status: Active.
[Failover][Info]: ether1: Online (up for at least 00:01:15)
[Failover][Info]: ether2: Offline (down for at least 00:01:15)
[admin@xxxxx] > $failover check
SEQ HOST SIZE TTL TIME STATUS
0 9.9.9.9 56 56 22ms
sent=1 received=1 packet-loss=0% min-rtt=22ms avg-rtt=22ms max-rtt=22ms
SEQ HOST SIZE TTL TIME STATUS
0 9.9.9.9 timeout
sent=1 received=0 packet-loss=100%
I have two default routes, distance of 1 & 2 respectively. NAT both out to the internet. Provision completed fine with no errors (I removed DynDNS, ResolveFQDN & Livestream modules).