⬆️ ⬇️

MikroTik. Correct dst nat when using 2 or more providers

Getting to the task, I was counting on an easy walk in the shade of an oak park, contemplating nature and indulging in thoughts ... However, later it became clear that this would be a thorny and difficult trek through mountain rivers with underwater rocks, icy rocks and deep caves.

Through meditation, the struggle with the elements and my own dullness of overcoming myself, I nevertheless achieved the desired nirvana.



In this article I will not only provide a ready-made set of rules, but I will try to explain as much as possible why and how they work.





Specifically, in my case, it was necessary to configure the router so that the web server in the local network behind it was available over the IP of any of the 3 providers.



Part 1.



For a start, let's go over all the settings so that the most impatient can copy-paste without reading.

')

Version RouterOS:

# oct/11/2016 22:02:32 by RouterOS 6.37.1 # software id = X62B-STGZ 


Interfaces:

 /interface list add name=WAN /interface list member add interface=ISP1 list=WAN add interface=ISP2 list=WAN add interface=ISP3 list=WAN 


I do not remember from which version of RouterOS this feature appeared. It allows you to group interfaces, which is very convenient (for example, in the rules / ip firewall). I have a group of 3 WAN interfaces.

AcidVenom suggested that in 6.36



IP addresses (addresses, for obvious reasons, “left”):

 /ip address add address=192.168.0.1/24 comment=defconf interface=bridge network=192.168.0.0 add address=95.11.29.240/24 interface=ISP1 network=95.11.29.0 add address=5.35.59.162/27 interface=ISP2 network=5.35.59.160 add address=5.98.112.30/30 interface=ISP3 network=5.98.112.28 


Routing:

 /ip route add distance=1 gateway=95.11.29.254 routing-mark=ISP1-route add distance=1 gateway=5.35.59.161 routing-mark=ISP2-route add distance=1 gateway=5.98.112.29 routing-mark=ISP3-route add check-gateway=ping distance=1 gateway=8.8.8.8 add check-gateway=ping distance=2 gateway=8.8.4.4 add check-gateway=ping distance=3 gateway=1.1.36.3 add distance=1 dst-address=8.8.4.4/32 gateway=5.35.59.161 scope=10 add distance=1 dst-address=8.8.8.8/32 gateway=95.11.29.254 scope=10 add distance=1 dst-address=1.1.36.3/32 gateway=5.98.112.29 scope=10 


For the organization of Failover, I configured recursive routing, I will tell you in more detail in the second part.



Firewall (for this publication, I deliberately provide rules that allow everything.

Do not do this!):

 /ip firewall filter add action=accept chain=forward add action=accept chain=input add action=accept chain=output 


dst and src nat:

 /ip firewall nat add action=masquerade chain=srcnat out-interface-list=WAN add action=dst-nat chain=dstnat comment="HTTP" dst-port=80 \ in-interface-list=WAN protocol=tcp to-addresses=192.168.0.83 to-ports=80 add action=dst-nat chain=dstnat comment="HTTPs" dst-port=443 \ in-interface-list=WAN protocol=tcp to-addresses=192.168.0.83 to-ports=443 


mangle

 /ip firewall mangle add action=mark-connection chain=input in-interface=ISP1 \ new-connection-mark=ISP1-conn passthrough=yes add action=mark-routing chain=output connection-mark=ISP1-conn \ new-routing-mark=ISP1-route passthrough=no add action=mark-connection chain=input in-interface=ISP2 new-connection-mark=\ ISP2-conn passthrough=yes add action=mark-routing chain=output connection-mark=ISP2-conn \ new-routing-mark=ISP2-route passthrough=no add action=mark-connection chain=input in-interface=ISP3 \ new-connection-mark=ISP3-conn passthrough=yes add action=mark-routing chain=output connection-mark=ISP3-conn \ new-routing-mark=ISP3-route passthrough=no add action=mark-connection chain=forward in-interface=ISP1 \ new-connection-mark=ISP1-conn-f passthrough=no add action=mark-routing chain=prerouting connection-mark=ISP1-conn-f \ in-interface=bridge new-routing-mark=ISP1-route add action=mark-connection chain=forward in-interface=ISP2 \ new-connection-mark=ISP2-conn-f passthrough=no add action=mark-routing chain=prerouting connection-mark=ISP2-conn-f \ in-interface=bridge new-routing-mark=ISP2-route add action=mark-connection chain=forward in-interface=ISP3 \ new-connection-mark=ISP3-conn-f passthrough=no add action=mark-routing chain=prerouting connection-mark=ISP3-conn-f \ in-interface=bridge new-routing-mark=ISP3-route 


Part 2.



Consider all the details.



Routing:

look under the spoiler so as not to thumb
 /ip route add distance=1 gateway=95.11.29.254 routing-mark=ISP1-route add distance=1 gateway=5.35.59.161 routing-mark=ISP2-route add distance=1 gateway=5.98.112.29 routing-mark=ISP3-route add check-gateway=ping distance=1 gateway=8.8.8.8 add check-gateway=ping distance=2 gateway=8.8.4.4 add check-gateway=ping distance=3 gateway=1.1.36.3 add distance=1 dst-address=8.8.4.4/32 gateway=5.35.59.161 scope=10 add distance=1 dst-address=8.8.8.8/32 gateway=95.11.29.254 scope=10 add distance=1 dst-address=1.1.36.3/32 gateway=5.98.112.29 scope=10 




/ ip route

In the first three lines we specify the default gateway of each of our 3 providers.

Routes have the same weight ( distance ), but work in different routing tables.



In other words, these routes work for packets marked with the appropriate tag ( routing-mark ). We will hang tags to packages in / ip firewall mangle (which I will like to describe below).



The next 3 lines indicate the default routes in the main routing table.



Here you should pay attention to:



  1. Parameter distance . For each route is different and, accordingly, the "weight" of the routes is also different.



    ISP1 is the main one, ISP2 and ISP3 close it, i.e. if the ISP1 provider fails, we will work through ISP2, and if ISP2 is in Bose, ISP3 will take over.



  2. Somewhat incomprehensible may be the value of the gateway parameter. How did this google DNS and some kind of left IP address suddenly become the default route? The magic lies in the scope parameter of the last three lines, as well as in the Nexthop lookup mechanism itself.



    In fact, the traffic will go to the active provider, and then he will send it to the Internet through his uplinks.



  3. About the check-gateway = ping parameter. The bottom line is that in the simplest scheme of building failover, specifying check-gateway = ping in the default routes, we only check the connection to the provider’s router. If the Internet is not available behind the ISP’s router, we will not understand this. And with the help of feint with the scope parameter, we check the connection no longer with the provider, but look for it, on the Internet.


Under the spoiler my detailed translation / adaptation of the Wiki MikroTik on this topic.



MikroTik. Nexthop_lookup
English articles http://wiki.mikrotik.com/wiki/Manual:IP/Route , in my opinion, slightly upturned. This is not Cisco CCNA Exploration, which is read in one breath, but I will try to translate its passage as clear as possible. If you see the same uproarty somewhere, correct me, please.



First, let's define some terms.

Nexthop - the next jump, if literally. The next gateway / router / router on the way of the packet from point A (from my router, for example) to point B (say to google DNS 8.8.8.8), i.e. the next hop where the packet will be processed. The translation will use the phrase “next hop” (sorry for anglicism).



Immediate nexthop is the next gateway / router / router on the route of the packet from point A to point B, accessible directly. For my home MikroTik, with the default route:



 dst-address=0.0.0.0/0 gateway=89.189.163.1 gateway-status=89.189.163.1 reachable via ether1-gateway 


89.189.163.1 - this is immediate nexthop, since It is available through ether1-gateway. The translation will use the phrase “immediately accessible next hop”.



Connected route - a connected route. A route whose gateway is directly accessible.



Gateway - network gateway / router / router.

I will use all three translation options.



scope - Used in the search engine for the next hop, i.e. what kind of hop decisions will be next. The desired route can be selected only among routes whose scope values ​​are less than or equal to the target-scope value. The default values ​​depend on the protocol:



  • related routes: 10 (if the interface is running (running))
  • OSPF, RIP, MME routes: 20
  • static routes: 30
  • BGP Routes: 40
  • associated routes: 200 (if the interface is not running)


target-scope - Used in the search engine for the next hop, i.e. what kind of hop decisions will be next. This is the maximum value of the scope parameter for the route by which the next hop can be found. For iBGP, the value is set to 30 by default.



Label the values ​​of both parameters.







Search for the next hop.

Finding the next hop is part of the route selection process.



Routes in the FIB need an interface corresponding to each of the gateway addresses. The address of the next hop gateway must be directly accessible through this interface. The interface that should be used to send an outgoing packet to each of the gateways is found by searching for the next hop.



Some routes (for example, iBGP), as the gateway address, may have an address belonging to the router, located through several hop-gateways from our MikroTik. To install such routes in the FIB, you must find the gateway address that is accessible directly (an immediate nexthop), i.e. directly from us, which will be used to reach the gateway address on this route. The immediate address of the next hop can also be found using the next hop search mechanism.



The next hop is searched for only in the main main routing table, even for routes that have an excellent value for the routing-mark parameter. This is necessary to limit the installation of routes that can be used to search for immediately accessible nexthops. In routes for RIP or OSPF protocols, it is assumed that the next router is directly accessible and should be found using only connected routes.



Routes with the interface name as a gateway are not used in the search for the next hop. If there is a route with the name of the interface, as well as a route with an active IP address, then the route with the interface is ignored.



Routes that have a scope greater than the maximum allowed value are not used in the search for the next hop. Each route specifies the maximum allowable value for the scope parameter, for its next hop, in the target-scope parameter. The default value for this parameter allows you to search for the next hop only through connected routes, except for iBGP routes that have a larger default value and can also search for the next hop via IGP and static routes.







The interface and the address of the next directly accessible router are selected based on the search results for the next hop:



  • If the most accurate active route that was found during the search for the next hop address is a linked route, then the interface of this linked route is used as the next hop interface and the gateway is marked as reachable. After the router becomes directly accessible through this interface (this is what should be understood as a “connected route” or “connected route”), its address is used as the address of the immediately next router (immediate next) address.



  • If the most accurate active route that was found during the search for the next hop address has the gateway address that was already detected, the immediately available hop and interface are copied from this route, and the gateway is marked as recursive.



  • If the most accurate active route that was found during the search for the next hop address is the ECMP route, then the first available router of that route is used.



  • If the search engine for the address of the next hop did not find a single route, then the gateway is marked as unreachable.


And now, as they say in KVN, why did I show this number. Please note that we set scope = 10 for static routes in the last three lines, thereby “forcing” MikroTik to take these routes into account when searching for the next hop.



It accepts, and thus routes by default through:



  • 8.8.8.8
  • 8.8.4.4
  • 1.1.36.3


become recursive, i.e. directly available hop will be the gateways of the providers and the traffic we will send through them, but check-gateway = ping will check the availability of the addresses for the provider networks.



I hope my translation and explanation will be useful to you.



While the most eager to learn to read under the spoiler, tell a little shorter and simpler.

When we specify scope = 10 in the last three lines, we let MikroTik understand that:





it is not accessed directly, but recursively through these static routes. One IP per brother provider.



/ ip firewall mangle

rules here
 /ip firewall mangle add action=mark-connection chain=input in-interface=ISP1 \ new-connection-mark=ISP1-conn passthrough=yes add action=mark-routing chain=output connection-mark=ISP1-conn \ new-routing-mark=ISP1-route passthrough=no add action=mark-connection chain=input in-interface=ISP2 new-connection-mark=\ ISP2-conn passthrough=yes add action=mark-routing chain=output connection-mark=ISP2-conn \ new-routing-mark=ISP2-route passthrough=no add action=mark-connection chain=input in-interface=ISP3 \ new-connection-mark=ISP3-conn passthrough=yes add action=mark-routing chain=output connection-mark=ISP3-conn \ new-routing-mark=ISP3-route passthrough=no add action=mark-connection chain=forward in-interface=ISP1 \ new-connection-mark=ISP1-conn-f passthrough=no add action=mark-routing chain=prerouting connection-mark=ISP1-conn-f \ in-interface=bridge new-routing-mark=ISP1-route add action=mark-connection chain=forward in-interface=ISP2 \ new-connection-mark=ISP2-conn-f passthrough=no add action=mark-routing chain=prerouting connection-mark=ISP2-conn-f \ in-interface=bridge new-routing-mark=ISP2-route add action=mark-connection chain=forward in-interface=ISP3 \ new-connection-mark=ISP3-conn-f passthrough=no add action=mark-routing chain=prerouting connection-mark=ISP3-conn-f \ in-interface=bridge new-routing-mark=ISP3-route 




To clarify the rules of this section, we will invite several assistants.



  1. MANGLE - this table is intended for operations on the classification and labeling of packets and connections, as well as modification of packet headers (TTL and TOS fields) (wikibooks).



    The mangle table contains the following chains:

    1. PREROUTING - allows you to modify a packet before making a routing decision.
    2. INPUT - allows you to modify the package intended for the host itself.
    3. FORWARD is a chain that allows modifying transit packets.
    4. OUTPUT - allows you to modify packets originating from the host itself.
    5. POSTROUTING - allows you to modify all outgoing packets, both generated by the host itself, and transit.
  2. CONNECTION TRACKING is a special subsystem that monitors the state of connections and allows you to use this information when making decisions about the fate of individual packets.
  3. MikroTik Packet flow


I broke the rules into groups, to facilitate their understanding. In the first group of 6 rules that are responsible for traffic to / from the router itself, and in the second group of 6, for transit traffic.



Nachem from the first two.

In the first, we tell the router that all incoming chain = input connections on the ISP1 interface need to be labeled action = mark-connection new-connection-mark = ISP1-conn , and also we specify passthrough = yes so that the packet, after passing this rule, does not left the table and continued following the rules.



In the second we tell MikroTik to catch the outgoing connections chain = output marked as ISP1-conn and assign them a routing label (to be placed in the corresponding routing table, do you remember the first three routes?), And also tell passthrough = no how saying, there’s nothing to do here for the package after this rule, i.e. the package will leave the table.



All of the above is true for both ISP2 and ISP3. Thus, we have ensured that the router answers exactly from the interface to which the request comes to it.



Go to the final six rules.

It is already clear, they are also divided into subgroups of 2, for each of our ISPs.

The first one instructs the router to monitor the FORWARD chain, and if a connection occurs through the ISP1 interface, it is marked action = mark-connection with a new tag new-connection-mark = ISP1-conn-f (note! Different from the traffic tag of the router itself, In this case, we mark transit traffic). passthrough = n o, since we do not want the packet, after getting into this rule, to be processed in the table somehow else.



The second hangs the desired routing label new-routing-mark = ISP1-route in the PREROUTING chain , i.e. Before making a decision on routing, and monitors the traffic that came to us from the local network in-interface = bridge .

Here we are rescued by the CONNECTION TRACKING mechanism, which allows us to catch connections from the local network (from the WEB server) marked by the rule above and hang up the necessary routing tag.



This allows transit traffic (here to / from the web server) to go exactly the way it came, i.e. came through ISP1 - go through it.



Conclusion



I am very happy if my explanations are clear, but this work will be useful.

Gone to meditate, good luck to all!



Thank you for attention!

Source: https://habr.com/ru/post/313342/



All Articles