Guys, as a self-proclaimed harpin NAT expert (but not in any kind of smug way
), I can tell you right away that you’re overthinking it.
If it’s about servers where there are already mappings between private and public addresses, and they need to either connect to internet or back to own subnet using dstnat (and nowhere else, see below), then it’s the easiest thing.
If you already have this as srcnat for connections to internet:
/ip firewall nat
chain=srcnat action=src-nat to-addresses=1.1.1.3 src-address=192.168.0.3 out-interface=ether1_WAN
chain=srcnat action=src-nat to-addresses=1.1.1.2 src-address=192.168.0.2 out-interface=ether1_WAN
then just remove out-interface options. Get rid of them, they are not needed. And bam, you have universal rules with hairpin NAT support built-in. Connections from 192.168.0.3 to public address bounced back to 192.168.0.x will show as from 1.1.1.3, and from 192.168.0.2 as 1.1.1.2.
If there’s requirement that servers must be able to directly connect to other local subnet(s), they can be simply exluded using dst-address(-list)=! or out-interface(-list)=!. That’s if you want to keep it as one rule and not split each it in two semi-duplicate ones, but that’ s a way too.
More generally, there’s nothing wrong with broad:
/ip firewall nat
add chain=srcnat src-address=192.168.0.0/24 dst-address=192.168.0.0/24 action=masquerade
If you’re bothered by the fact that it also matches connections initiated from router itself, just add src-address-type=!local. If you don’t like that connections still have router’s address as source, simply replace masquerade with action=src-nat to-addresses=. And I mean almost any address, except 192.168.0.x, those wouldn’t work, because server wouldn’t send responses to them back to router. But other than that, there are no restrictions. Use public address of your router as shown above, choose some random private address, or even any random public address. Last one doesn’t make much sense, because it wouldn’t make things more clear, but it would still work. Use to-addresses=8.8.8.8, literally this addreses that belongs to Google, and it will work too. But it’s just example, don’t do it for real.
But it’s still one address for whole subnet, right? And you really really must know if connection came from Bob’s computer 192.168.0.10 or Jane’s 192.168.0.20. I’d suggest to adopt use of usernames, as it’s more reliable, but no problem, it’s still doable:
/ip firewall nat
add chain=srcnat src-address=192.168.0.0/24 dst-address=192.168.0.0/24 action=netmap to-address=192.168.100.0/24
Bob will show as 192.168.100.10 and Jane as 192.168.100.20, so it’s not great, because 0 is not 100, but you will be able to tell them apart, it’s the best you can get.