Mikrotik Policy-Based Routing

One of the more interesting features within the RouterOS mangle (packet marking) facility is the ability to mark packets in the pre-routing chain. With this option, we can perform what is called policy-based routing. Suppose we have two WAN (Internet) connections that our LAN clients could potentially use, and that we wish to split the usage such that one range of IP addresses use WAN1 and another range use WAN2. As an example in our library environments, we may have situations where we want staff machines to use one ISP and patron machines use another. Here is a simple diagram we can reference:

What we want to have happen is for all machines in the IP range 192.168.88.100 through 192.168.88.150 to use ISP1 (192.168.25.1), and all machines in the IP range 192.168.88.151 through 192.168.88.200 to use ISP2 (192.168.50.1).

So, our interface IP assignments could be something like this:
[sourcecode language=”plain”]
/ip address
add address=192.168.88.1/24 disabled=no interface=LAN network=192.168.88.0
add address=192.168.25.1/24 disabled=no interface=WAN1 network=192.168.25.0
add address=192.168.50.1/24 disabled=no interface=WAN2 network=192.168.50.0
[/sourcecode]

First, let’s get some address lists going in IP > Firewall > Address Lists
[sourcecode language=”plain”]
/ip firewall address-list
add address=192.168.88.100-192.168.88.150 comment="Use ISP 1" disabled=no list=patron
add address=192.168.88.151-192.168.88.200 comment="Use ISP 2" disabled=no list=staff
[/sourcecode]

Now, let’s set up routing marks based on the address lists above:
[sourcecode language=”plain”]
/ip firewall mangle
add action=mark-routing chain=prerouting comment=ISP1 disabled=no new-routing-mark=ISP1 passthrough=yes src-address-list=patron
add action=mark-routing chain=prerouting comment=ISP2 disabled=no new-routing-mark=ISP2 passthrough=yes src-address-list=staff
[/sourcecode]

Finally, we add default routes based on the routing mark of the packets:
[sourcecode language=”plain”]
/ip route
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=192.168.25.1 routing-mark=ISP1 scope=30 target-scope=10
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=192.168.50.1 routing-mark=ISP2 scope=30 target-scope=10
[/sourcecode]

Another way we could use policy-based routing would be for routing packets through a filtering proxy. Suppose we have a transparent Squid proxy set up for content filtering in our network. We have would need to set up four interfaces including WAN, LAN, and two more to loop the packets out to the Squid box and back into the router. Our diagram is something like this:

Our interface list:
[sourcecode language=”plain”]
/ip address
add address=192.168.88.1/24 disabled=no interface=LAN network=192.168.88.0 comment="LAN"
add address=192.168.25.1/24 disabled=no interface=WAN network=192.168.25.0 comment="WAN"
add address=192.168.101.1/24 disabled=no interface=F-Out network=192.168.101.0 comment="Filter Out"
add address=192.168.102.1/24 disabled=no interface-F-In network=192.168.102.0 comment="Filter In"
[/sourcecode]

What we would do is cable the filter-out (F-Out) interface of the router to the LAN port of the Squid box (assigned IP 192.168.101.2). Then, cable the Squid box WAN port (assigned IP 192.168.102.2) back to the filter-in (F-In) interface of the router. This creates a detour path to route our packets through if we wish to filter them. Then, set up an address-list for filtered machines, as well as routing marks in mangle:
[sourcecode language=”plain”]
/ip firewall address-list
add address=192.168.88.100-192.168.88.150 comment="Filtered" disabled=no list=patron
/ip firewall mangle
add action=mark-routing chain=prerouting comment=Filtered disabled=no new-routing-mark=Filtered passthrough=yes src-address-list=patron
[/sourcecode]

Notice in this example that we need only create address-lists and mangle rules for machines we wish to detour through the Squid box as all other packets will exit the router directly through the WAN port and out to the Internet like normal.

Now, we set one routing rule for the detour, using the Squid box LAN IP as our gateway:
[sourcecode language=”plain”]
/ip route
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=192.168.101.2 routing-mark=Filtered scope=30 target-scope=10
[/sourcecode]