Balancing traffic in Mikrotik between two WAN interfaces taking into account incoming traffic
I warn you right away - the system has many shortcomings, for example, access to the same resource from different IPs is possible, which is fraught with an authorization rally. So using it is best for connections that are not sensitive to the source address, for the same torrents for example.
And yet, I will not describe the configuration of Mikrotik from scratch, it is assumed that you already have a router with two VANs, on which IP addresses are already set up, local ports are also configured. And that the user is more or less oriented in Mikrotik, at least at the level of what he knows where, what menu item is located.
For completely newcomers and people who are poorly versed in networks (you can be a master in one and a beginner in another, I don’t see anything unusual in this) I posted a couple of spoilers
So. We will conditionally accept that:
- local addresses in our range are 192.168.0.0/16 and are connected to the Localca bridge
- Provider1 sits on our WAN1 interface, with gateway 10.0.0.1
- Provider2 sits on our WAN2 interface, with gateway 172.16.25.1
So let's get started.
First, create new routes:
/ip route
add disabled=no distance=1 dst-address=192.168.0.0/16 gateway=Localca routing-mark=isp2 scope=30 target-scope=10
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=172.16.25.1 routing-mark=isp2 scope=30 target-scope=10
add disabled=no distance=1 dst-address=192.168.0.0/16 gateway=Localca routing-mark=isp1 scope=30 target-scope=10
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=10.0.0.1 routing-mark=isp1 scope=30 target-scope=10
Do not worry if it duplicates existing dynamic (or the routes you created). All salt in routing brands. All routes with a routing mark are a separate routing table, and packets that go through it cannot use other tables, so you need to register the path to local addresses too. In theory, when there is no address in the desired table, packets can look at the default (unmarked) routing table. But I have had cases when this principle did not work, so it’s better to
play it safe Let's create a mangle that will send all new connections to the desired gateway:
/ip firewall mangle
add action=mark-connection chain=prerouting connection-mark=no-mark disabled=no dst-address=!192.168.0.0/16 new-connection-mark=inet_con passthrough=yes
add action=mark-routing chain=prerouting comment=multiwan connection-mark=inet_con disabled=no new-routing-mark=isp2 passthrough=no
The first rule catches all unmarked (and therefore new) connections that do not go to our LAN, and therefore go through the WAN interface, and marks them with the necessary label. I chose this approach, since we have several VAN interfaces, and for each we would have to create a separate rule with the necessary Out. Interface, and so we limited ourselves to one rule. The second rule to connections with the necessary label assigns a routing mark. Comment serves us so that we can find this rule with a script.
The next item, we go to System-Scripts and create a new script with the following content:
:global rx1 "0"
:global rx2 "0"
/interface monitor WAN1 once do={
:global rx1 $("rx-bits-per-second");
}
/interface monitor WAN2 once do={
:global rx2 $("rx-bits-per-second");
}
:local one 20000000
:local two 8000000
:global wan1 ($one / $rx1)
:global wan2 ($two / $rx2)
if ($wan1>$wan2) do={/ip firewall mangle set [find comment=multiwan] new-routing-mark=isp1} else={/ip firewall mangle set [find comment=multiwan] new-routing-mark=isp2}
First, we reset the variables, then we get the data on the load on the interfaces (specifically, the number of bits received per second, for which the rx-bits-per-second parameter is responsible). Next, we enter the width of each Internet channel in bits into the variables one and two, and we get the opposite (since Mikrotik often does not show fractional, we would get 0 when dividing the number of bits by width) relative load (divide the width by the load in bits). And then we compare them, and if the number of the first VAN is higher, then in our mangle (a comment came in handy here, we turned to the desired mangle on it) we enter the route mark for VAN1, otherwise to VAN2.
Now it's up to you to set the frequency of script execution. We go to the System-Sheduler and add a new task with the desired execution interval, in the on Event field: enter
/system script run erazel_balancing
Where erazel_balancing is the name of the script in which we change the mangle. Do not forget to change the name of your script.
Now we have a fully automatic load balancing system for external interfaces, depending on their relative workload.
Well, there remains the question of accessing the server from various external addresses. So I would advise you to use this approach for torrents and other non-critical applications. Just in the first mangle (which marks the connection), make another condition on the protocol and port, well, and duplicate it for different protocols / ports. For instance:
add action=mark-connection chain=prerouting connection-mark=no-mark disabled=yes dst-address=!192.168.0.0/16 new-connection-mark=inet_con passthrough=yes protocol=tcp src-port=45000