Back to Home

Balancing traffic in Mikrotik between two WAN interfaces taking into account incoming traffic

mikrotik · load ballancing · home lan

Balancing traffic in Mikrotik between two WAN interfaces taking into account incoming traffic

Recently I decided to try to implement simple traffic balancing between several WANs. Why is it simple? I know too much about large amounts of information, and I suspect not just me. Therefore, I decided to try to develop a scheme in which even a beginner will understand, since it is not enough to use other people's achievements, you need to know what and what you are doing.

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

What are routes, they are routes
Routes are an indication to the router on which port or for which IP address to search for the desired subnet. Without this, the router will not know where to send packets. That's why we have indicated not only Internet gateways but also the port on which our local addresses are located

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.
mark-routing what is it for
The routing mark is used to indicate the routing table for the selected packets / connections. They will only use routes that carry the corresponding Routing Mark. In this way, we can send different traffic to different gateways / ports according to the conditions we need. Everything to the left of the Action tab in the mangles (and in the filter and NAT) is a filter. So the less criteria we specify, the wider the coverage of traffic falling under this rule. Accordingly, combining different conditions, we can very accurately separate the traffic we need.


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

Read Next