Dstnat in output chain?

I thought I knew RouterOS pretty well, but this got me. With Linux iptables, I can change destination for locally originated connections like this:

iptables -t nat -A OUTPUT --dst 192.168.80.1 -j DNAT --to-destination 192.168.84.2

But this does not seem possible in RouterOS. Did I just miss something, or is it known limitation?

It doesn’t appear RouterOS will accept a rule like that. Looks like Output rules can’t jump to dstnat rules.

Closest you’ll get is using just a dstnat rule with src ip of the router to make RouterOS apply it to packets originating locally.
Chain=dst-nat, src-ip=, dst-ip= 192.168.80.1, to-destination=192.168.84.2

It’s not important where it is, but what it should do. Trying to use current dstnat chain does not work, it applies only to packets coming to router from elsewhere, not locally originated.

Existing mapping between iptables and RouterOS chains is like this:

“iptables -t nat -A PREROUTING” is “/ip firewall nat chain=dstnat”
“iptables -t nat -A POSTROUTING” is “/ip firewall nat chain=srcnat”

But it looks like “iptables -t nat -A OUTPUT” was skipped by MikroTik. I get it, it’s not like it would be an essential functionality for many people. But sometimes it could be useful, e.g. for this guy.

I’d also vote for this option. It could be useful for:

  • scoped DNS forwarders; by moving the L7 rules from dstnat chain to forward chain the local DNS server and cache can be used
  • local traffic (e.g. netwatch) to netmapped subnet

If this was added, I’d also use it for per-domain DNS forwarding in few places, because it would help with at least some shortcomings of current L7 hack (bypassing cache and not working for router itself). But I really hope to live to see proper support for that in RouterOS DNS resolver.

interesting feature +1

+1


Отправлено с моего iPhone используя Tapatalk

I’d +1 this feature as well, need it for conditional DNS forwarding too.

hey there. happy new year with my first post!
i need this feature badly, isn’t there any way to do this yet?
i can do it by using another RB to work as my first RB’s firewall, but this isn’t pleasant

+1!

After reading sindy’s Multiple Road Warrior L2TP/IPsec clients behind NAT - solved thread, and after my brain stopped hurting, I thought “hey, this loop trick could also work for other stuff”. The idea is to let traffic from router go out, then let it come back to router and then it’s possible to do dstnat. Following example shows how to redirect router’s own DNS queries to another port, but you can use it for anything. First mark routing for output traffic you need to dstnat, and then you can match it with in-interface=ipip-loop2 in dstnat chain.

/interface bridge
add name=loopback protocol-mode=none
/ip address
add address=127.0.0.2/32 interface=loopback
/interface ipip
add local-address=127.0.0.1 name=ipip-loop1 remote-address=127.0.0.2
add local-address=127.0.0.2 name=ipip-loop2 remote-address=127.0.0.1
/ip route
add distance=1 gateway=ipip-loop1 routing-mark=loophack
add distance=1 dst-address=10.10.10.10/32 gateway=ipip-loop2
/ip dns
set allow-remote-requests=yes servers=208.67.222.222,208.67.220.220
/ip firewall mangle
add action=mark-routing chain=output dst-port=53 new-routing-mark=loophack passthrough=no protocol=udp
add action=mark-routing chain=output dst-port=53 new-routing-mark=loophack passthrough=no protocol=tcp
/ip firewall nat
add action=src-nat chain=srcnat out-interface=ipip-loop1 to-addresses=10.10.10.10
add action=dst-nat chain=dstnat dst-port=53 in-interface=ipip-loop2 protocol=udp to-ports=5353
add action=dst-nat chain=dstnat dst-port=53 in-interface=ipip-loop2 protocol=tcp to-ports=5353
add action=masquerade chain=srcnat out-interface=<WAN>

(10.10.10.10 is some random address you don’t use anywhere else)

It works, but now my brain hurts again.

You sir, are a deadset legend.

I used this to solve an issue with The Dude running on a router, and needing to change the remote winbox port for some sites (which The Dude does not support). I had been beating my head against not being able to dst-nat in the outbound chain for a few hours. I was almost there and this got me the rest of the way.

Thank @sindy for this one, I’d never come up with such crazy idea myself. :slight_smile:

+1, for the same reason, about conditional DNS forwarding.

The loop trick is cool, but honestly I want a simpler solution :smiley: Maybe RoS7 and a new kernel…

Actually, the loop trick is really dirty trick, but if you’re really desperate, it could be used. Simpler solution would be to make dstnat in output available in RouterOS. It shouldn’t need new kernel, I found it mentioned in articles about Linux 2.4 and RouterOS has some 3.x, if I remember correctly. So it’s most likely there already and they probably just didn’t think that anyone would need it, so they didn’t expose it.

If you really need it, you can try sending official feature request to support. But if you want it for DNS, then better ask for what you really need and that’s Feature Request: Conditional DNS Forwarding. Dstnat in output would be only a workaround, slighly better than what we have now, but still not very good.

I can’t believe my eyes, look what’s possible in v7:

/ip firewall nat
add chain=output dst-address=192.168.80.1 action=dst-nat to-addresses=192.168.84.2

Do you see the chain=output in “/ip firewall nat”? Router takes it and doesn’t complain. So one extra rule:

/ip firewall mangle
add chain=postrouting protocol=icmp action=log

Followed by “ping 192.168.80.1”, and the log says:

22:14:10 firewall,info postrouting: in:(unknown 0) out:internal, proto ICMP (type 8, code 0), 192.168.80.183->192.168.84.2, NAT 192.168.80.183->(192.168.80.1->192.168.84.2), len 56

It works!

Are you saying that the feature has been Unhidden, (made available) and now folks can change the destination address on the output chain.
Can you provide an example that would make sense to those of us who would rarely come across such a requirement.

Aside from per-domain DNS forwarding mentioned in this thread (but it’s usually better handled by since then improved DNS cache and new FWD records), you could use it e.g. as a final piece addition to hairpin NAT.

Let’s say you have webserver in LAN on private address 192.168.88.20 and dstnat to it from your public address 1.2.3.4. Your www.example.tld points to 1.2.3.4, so anyone connected to internet can connect to it. From your own LAN it doesn’t work, but you already know how to fix that using hairpin NAT. Hooray, victory, now everyone can connect to www.example.tld! Yeah, not so fast, one device still can’t - your own router. If it tries to connect to www.example.tld, it will connect to 1.2.3.4, i.e. to itself, because connection won’t go in chain=dstnat, so it can’t be redirected. But now it’s possible using this rule:

/ip firewall nat
add chain=output dst-address=1.2.3.4 protocol=tcp dst-port=80,443 action=dst-nat to-addresses=192.168.88.20

You most likely won’t ever need it. But if such need arises, now it’s possible.

Yeah, as likely as touching my elbow to my nose!

That depends on where your elbow is situated. :wink:

Output in NAT needs some work to cut out some of the warning tape from the brain that has become obsolete now.