NAT to two different servers on the same port via hostname with Mikrotik RB2011

10,027

Thanks for the export.

It turns out that either this configuration is not supported by MikroTik or there is a bug.

According to the Packet Flow Diagram, if I understand it correctly, dst-nat should be able to detect the packet/connection marks since mangle prerouting is before dst-nat. But after some tests of my own I got stuck the same as you did. MikroTik Packet Flow Diagram

While mangle/filter can match the marked packets (or even without marking, but by directly using the L7 filter on the rules) on nat it simply does not match any packets.

There are also various relevant threads on the MikroTik forums, which none seem to have found a solution.

http://forum.mikrotik.com/viewtopic.php?f=2&t=83129

http://forum.mikrotik.com/viewtopic.php?f=2&t=73856

http://forum.mikrotik.com/viewtopic.php?f=13&t=62152

One guy mentions a solution by using the WebProxy of MikroTik, which I personally wouldn't use since it will change the source IP address to the IP of MikroTik and thus the webservers will log all requests with the same IP instead of the real visitors' IPs.

I can think of two other solutions but are not that straightforward.

Solution 1: If you are using version 5.x of MikroTik there is an ISO image that will patch MikroTik and add a minimal debian distro on top (or bellow) it. Which then you can use to install HAproxy or any other reverse proxy you like to accomplish what you need properly (HAproxy or any other reverse proxy is the correct way to do this as others have already mentioned)

Solution 2: Another approach is to create a metarouter (if you run MikroTik on a routerboard, you have enough free RAM and you don't use nstreme) and load an openwrt image on it. On which you can then install a reverse proxy of your liking to accomplish the task.

Most likely not a solution: Of course you could also send a support ticket to MikroTik to confirm or (most likely) deny that there is a bug on NAT with L7 packet marking. But I wouldn't expect much from their support. Most of the time will not help you at all. Their default strategy is that everyone is stupid and the problem is always on the users' configuration and not on MikroTik itself...

It would be nice to be able to handle this task on the router itself. It's suitable for constrained environments where putting yet another machine to do the reverse proxy is not an option. Though I wouldn't use this method (even if it worked) on a production environment. Layer 7 filter is quite slow and heavy for the router.

Update: I just saw that you are using RB2011, so the ISO/debian solution won't work for you (it's only for x86). If you are not using nstreme (I guess not) then your only bet is by using a metarouter with openwrt to do the reverse proxy stuff for you.

Share:
10,027

Related videos on Youtube

pataroulis
Author by

pataroulis

Updated on September 18, 2022

Comments

  • pataroulis
    pataroulis almost 2 years

    I have a Mikrotik RB2011 router, running RouterOS which connects to the internet via a static IP. In my lan I have two different servers, one that is on IP 192.168.89.11 and another on 192.168.89.12

    My DNS (on cloudflare) resolves both myfirstserver.com and mysecondserver.com to my router's static IP.

    Now, what I want to do is to somehow separate the traffic so all traffic for myfirstserver.com goes to 192.168.89.11 and traffic for mysecondserver.com goes to 192.168.89.12 (and both on port 80. I know I could just change ports but if these are servers publicly available, no user would set a different port than 80)

    What I have tried so far, is to somehow mark the packets through mangle and then use that mark on NAT to do the proper dst-nat forward.

    I try marking packets through either content or Layer 7 protocol regex (they work properly if the action is log. I can see them being logged correctly).

    The thing is that after I mark them, it seems that NAT just ignores them and forwards the connection to the server that accepts the non-marked packets.

    I think I have mixed up the order of filtering and the chains somehow.

    Would someone be able to provide some pointers/assistance on how to accomplish this?

    Thanks!

    EDIT: My question is very specific, about marking packets in RouterOS on a Mikrotik router and checking the mark in NAT. it is not about whether i need a reverse proxy or whatever. Thanks

    EDIT 2: @Cha0s asked my /ip firewall export so here it is:

    /ip firewall layer7-protocol
    add name=haf1a regexp=haf1a
    
    /ip firewall address-list
    add address=192.168.89.0/24 list=local
    add address=192.168.88.0/24 list=local
    add address=www.xxx.yyy.zzz list=local
    add address=192.168.87.0/24 list=local
    
    /ip firewall filter
    add chain=input comment="default configuration" protocol=icmp
    add chain=input comment="default configuration" connection-state=established
    add chain=input comment="default configuration" connection-state=related
    add action=drop chain=virus comment="Drop 80 DoS attack" src-address-list=spammer
    add action=add-src-to-address-list address-list=spammer address-list-timeout=1d chain=input connection-limit=10,32 dst-address-list=!local dst-port=53 protocol=udp
    add action=drop chain=input dst-port=53 protocol=udp src-address-list=!local
    add action=add-src-to-address-list address-list=spammer address-list-timeout=1d chain=input connection-limit=30,32 protocol=tcp
    /ip firewall mangle
    add action=change-mss chain=forward new-mss=1422 out-interface=all-ppp protocol=tcp tcp-flags=syn tcp-mss=1423-65535
    
    /ip firewall nat
    add action=masquerade chain=srcnat comment="default configuration" out-interface=ether1-gateway
    add action=masquerade chain=srcnat out-interface=pppoe-out1
    add action=dst-nat chain=dstnat comment="No HAF mark" dst-address=www.xxx.yyy.zzz dst-port=80 packet-mark=!haf1 port="" protocol=tcp src-port="" to-addresses=192.168.89.41 to-ports=80
    add action=dst-nat chain=dstnat comment="HAF mark" dst-address=www.xxx.yyy.zzz dst-port=80 packet-mark=haf1 port="" protocol=tcp src-port="" to-addresses=192.168.89.31 to-ports=80
    

    where www.xxx.yyy.zzz is my external ip (static) and 192.168.89.31 and 192.168.89.41 my two servers inside my local network

    My goal is to redirect any connections with haf1a in them (eg haf1a.lala.com) to the relevant server (192.168.89.31)

    • FooBee
      FooBee over 9 years
      Setup a HTTP reverse proxy on the router or forward the traffic to one that one delivers the traffic to the real servers (this could even be one of the real servers).
    • pataroulis
      pataroulis over 9 years
      thank you but this is not what I need as I want all ports to be seamlessly NATed to the respective servers. Not just http traffic
    • FooBee
      FooBee over 9 years
      It's not going to work then. HTTP has a method to differentiate traffic meant for different servers, but many protocols have not and there is no way to trick around that.
    • pataroulis
      pataroulis over 9 years
      I edited the question to make it Mikrotik-specific. I just need an answer on how I can mark packets when they enter the router so I can be able to check them on NAT
    • Cha0s
      Cha0s over 9 years
      Please post the results of /ip firewall export here so we can understand your setup. Your described method (L7 regex + NAT rules) sounds right. But if the NAT rules don't match the packets properly there probably is an error in your configuration.
    • Cha0s
      Cha0s over 9 years
      Also you don't need to mark any packets. You simply create the L7 regex rules and then the NAT rules that will dst-nat the matched packets to the configured IPs/Ports.
  • pataroulis
    pataroulis over 9 years
    I edited the question to make it Mikrotik-specific. I just need an answer on how I can mark packets when they enter the router so I can be able to check them on NAT
  • pataroulis
    pataroulis over 9 years
    Oh my! thanks for going to such depth for an answer. Really appreciate you didn't go the "Can't work, now mark my answer correct" approach. Will try one step at a time with the metarouter. Didn't even know I can do such a thing. Thanks again!
  • Cha0s
    Cha0s over 9 years
    Glad I could help :)