How to revert srcnat pre-routing instead of post-routing?

I have set up a simple policy routing that sends all packets with source address 192.0.2.0/24 through interface wan2 (all other traffic goes through wan1).

Now the router has public IP 192.0.2.209/28 and I want to run port forwarding (dstnat) over it: All packets to 192.0.2.209:443 shall be forwarded to internal host 10.227.4.10:443. This works with the classic dstnat. But the issue is that the return packet will have internal source IP 10.227.4.10 and hence will be sent out to wan1 (instead of wan2).

Example: Suppose host 198.51.100.55 on the internet opens a connection:

  • Router receives a packet from 198.51.100.55:xxx to 192.0.2.209:443


  • Router performs DNAT and changes destination to 10.227.4.10:443


  • Now the routing decison is made, packet sent out the internal interface and host 10.227.4.10:443 answers


  • Router receives return packet from address 10.227.4.10:443 to destination 198.51.100.55:xxx


  • Router makes routing decision to send out packet on wan1


  • Router reverts dstnat by replacing source address from 10.227.4.10:443 back to 192.0.2.209:443

Is there a way to swap the last steps? In other words, FIRST replace the source address back to 192.0.2.209 and then perform routing decision based on the replaced value?

I tried to perform an additional srcnat step and now the internal network does not see a public IP at all: Source is always 192.0.2.209 and destination is always 10.227.4.10. However, this still does not work…

You have to mark connections, coming in via WAN2 … then use connection mark to set routing mark … and then use that routing mark to use alternate routing over WAN2 interface.

Yes, it has to be connections marked, so that return packets (belonging to same connection) will get properly marked for alternative routing.

Thank you, this seems to work, indeed!

For future reference (and poking holes, if not correct):

/ip firewall nat
add action=dst-nat chain=dstnat dst-address=192.0.2.209 dst-port=443 protocol=tcp to-addresses=10.227.4.10 to-ports=443

/ip firewall mangle
add action=mark-connection chain=prerouting dst-address=192.0.2.209 dst-port=443 in-interface-list=WAN new-connection-mark=mark_pfw passthrough=yes protocol=tcp
add action=mark-routing chain=prerouting connection-mark=mark_pfw new-routing-mark=rtable_wan2 passthrough=yes protocol=tcp src-address=10.227.4.10 src-port=443

Probably you don’t have to set protocol=tcp src-address=10.227.4.10 src-port=443 in mark-routing configuration … if you properly apply connection mark. You’d probably have to add the route to 10.227.4.0/24 to the alternative routing table though to allow forward packets to reach their destination. But this way you wouldn’t have to add too many mark-routing stanzas (in case you’d want to use WAN2 for any other ingress connectivity apart from https).