PBR - Ensure traffic leaves the same interface it arrives on

Hi *,

I’m attaching a sketch of a problem that I believe is related to policy based routing.

Whenever the mobile client tries to access the web server located in the DMZ behind the CPE using the port forwarding (DNAT) through the vpn appliance, traffic goes through.

However, since the mobile client’s is connecting using a publicly routed ip address, the CPE (RB2011) forwards reply traffic using its default gateway instead of the vpn interface.

How can ensure that reply traffic leaves through interface ovpnc1 which is the one it initially arrived on?

Thanks in advance
lab_pbr_vpn.png

I had a similar issue using a VPN. It took a routing mark to get the routing correct.
http://forum.mikrotik.com/t/please-help-simple-pptp-vpn-client-setup/74793/1

Well, yes, it would help with this but from my understanding placing a routing mark as with your post will basically match all traffic that’s coming from the DMZ subnet. But the hosts in the DMZ should still be able to communicate to the outside w/o having all outbound traffic routed via the VPN by default. In fact the VPN only carries inbound but no outbound traffic.

I also wonder if it wouldn’t make sense to implement this using >ip route rules instead which would classify traffic based on the IP layer only. Guess it would be much faster compared to placing a routing mark using iptables (netfilter) running mangle. However, it gives you more fine-grained control when pushing traffic into a separate routing table based on certain constraints like the transport protocol or the used communication port.

This should be quite easy using two mangle rules.

Create a first rule that marks connections coming from the VPN tunnel and not having a mark already.
Create a second rule that applies a new routing mark to packets marked with the connection mark and coming from the DMZ.
Add a new routing table with the routing mark and route via VPN.

This works because when marking a connection the router will automatically give that mark to response packets too.

Here is an (slightly different) example were the router itself is a VPN endpoint reachable via two internet connections:
0 ;;; Mark packets received from LTE
chain=input action=mark-connection new-connection-mark=from-lte
passthrough=yes in-interface=ether2-lan
src-mac-address=24:65:11:xx:xx:xx connection-mark=no-mark

1 ;;; Mark response packets to be sent via LTE
chain=output action=mark-routing new-routing-mark=lte-route
passthrough=yes connection-mark=from-lte

Well, in my lab I came up with the following but somehow it still doesn’t work.

When both mangle rules are enabled inbound traffic via vpn does no longer reach the host located in the DMZ.
[admin@R2-PBR-LAB] > ip firewall mangle export

mar/11/2014 08:32:57 by RouterOS 6.10

software id = RNN2-JRDD

/ip firewall mangle
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=vpn-ext new-connection-mark=from-vpn
add action=mark-routing chain=prerouting connection-mark=from-vpn new-routing-mark=route-vpnThe following shows the additional RIT with name “route-vpn” that’s being referenced for the return path:
[admin@R2-PBR-LAB] > ip route export

mar/11/2014 08:32:50 by RouterOS 6.10

software id = RNN2-JRDD

/ip route
add distance=1 gateway=vpn-ext routing-mark=route-vpn

Well, take a look again at what I said:

Create a second rule that applies a new routing mark to packets marked with the connection mark > and coming from the DMZ.

Right now you are switching inbound traffic to a routing table that no longer has the destination it is supposed to reach.

Got you, it’s working perfectly fine now, thanks!
[admin@R2-PBR-LAB] > ip firewall mangle export

mar/11/2014 09:19:55 by RouterOS 6.10

software id = RNN2-JRDD

/ip firewall mangle
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=vpn-ext new-connection-mark=from-vpn
add action=mark-routing chain=prerouting connection-mark=from-vpn new-routing-mark=route-vpn src-address=10.12.0.0/24
/ip route
add distance=1 gateway=vpn-ext routing-mark=route-vpn
/ip settings
set rp-filter=noIt just took me a while to wrap my head around this :wink:

Just wanted to thank both dog (for the solution) and jayd2k for providing his working rules. This helped me sort out a similar problem where my LTE connection was my default route, but I wanted to be able to come in via my ADSL interface.

I had to add an extra mangle rule on the output chain to allow me to log into the Mikrotik itself via the ADSL. Won’t claim to understand it, but it works. I can now get to the router via Winbox from outside, and I can also get to devices behind NAT.

My three rules then:

/ip firewall mangle
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ADSL1 new-connection-mark=ADSL
add action=mark-routing chain=prerouting connection-mark=ADSL new-routing-mark=ADSL src-address=192.168.0.0/24
add action=mark-routing chain=output connection-mark=ADSL new-routing-mark=ADSL

If you’re interested, the packet flow diagram will show you why:
http://wiki.mikrotik.com/wiki/Manual:Packet_Flow_v6

Mangle Prerouting is only called when packets arrive at the router from outside the system.

When the Mikrotik’s internal process generates a packet to send to your Winbox client, the packet starts at the far right of the main diagram “router processes” - then goes downward through local_out, then the question “IPv4 or IPv6” is yes, so it follows link K into the routing block.

In the routing block, the path will be: Routing Decision, [Output], [Postrouting], IPSec Decision (no), (L)

So then looking at the [Output] and [Postrouting] groups below, you’ll see that Mangle Prerouting is never called, but that Mangle Output is called.

HTH.

Thank you for the explanation. I’ve taken a look and tried to make sense of it, but this could be above my pay-grade.

I’m not sure how you ended up at “J” in your example I’ve quoted. I would have thought it would end up at “L” if it followed your decision path.

Oops - you’re right - I was flipping back and forth between browser tabs and my brain changed the L to a J by the time I was typing again. :confused:

I’m going to edit my previous post just so that people reading along later don’t get confused.