I have a simple Dst NAT that forwards incoming TCP connections on port 23516 from WAN interface to an internal server IP on LAN interface on port 8080. This works fine AFAIK.
What I don’t understand is that I also have a Firewall Filter that drops everything from WAN unless it’s an established or related TCP connection, but if I log what’s dropped, I see TCP stuff dropped on that explicitly DNAT’ed port 23516:
input: in:WAN out:(none), src-mac {REDACTED}, proto TCP (ACK,FIN), {REDACTED}:53878->{WAN_IP}:23516, len 52
Why is that? How come these TCP packets even make it to the firewall filter in the first place since they should be DNAT’ed? I thought if packets are DNAT’ed then when they go through the firewall filter, they are not considered to come from the “input” chain / WAN interface but are from the “forward” chain instead?
The NAT chain is part of pre-routing processing. Every packet that goes through the router goes through a pre-routing, routing, and post-routing process. Your dst-nat rule effectively tells the router that the inbound packet should go to the FORWARD chain, as the packet should transit the router, rather than terminate at the router. Your NAT rule looks to be correctly set up, but you’ll want to update your FORWARD chain.
First of all, you have a fasttrack rule, but not every packet can be fasttracked. You want to put an ACCEPT rule right below the fasttrack rule to catch any non-fasttracked rel/est sessions. You probably also want to add a rule to allow forwarding between your internal LANs, and allow forwarding of outbound traffic from your internal LANs to the Internet. Also create an ACCEPT rule for your dst-natted traffic, and end your FORWARD chain with a “Drop-All-and-Log” rule.
Unless you need to to generate statistics, you should never use the “passthrough” action. It essentially creates a dummy rule that simply counts packets that haven’t been processed by prior rules. You need action=accept for the firewall to allow the traffic.
The NAT chain is part of pre-routing processing. Every packet that goes through the router goes through a pre-routing, routing, and post-routing process. Your dst-nat rule effectively tells the router that the inbound packet should go to the FORWARD chain, as the packet should transit the router, rather than terminate at the router.
Right, but that doesn’t explain why, if all the TCP packets entering the router on port 23516 are DNAT’ed to the FORWARD chain, some (ACK,FIN) ones are still making it into the INPUT chain and are therefore caught by the Drop All WAN rule? This doesn’t make sense to me. Furthermore if this were to be expected, how does this affect these TCP connections? Are they not closing properly from the perspective of the external client reaching in?
First of all, you have a fasttrack rule, but not every packet can be fasttracked. You want to put an ACCEPT rule right below the fasttrack rule to catch any non-fasttracked rel/est sessions. You probably also want to add a rule to allow forwarding between your internal LANs, and allow forwarding of outbound traffic from your internal LANs to the Internet. Also create an ACCEPT rule for your dst-natted traffic, and end your FORWARD chain with a “Drop-All-and-Log” rule.
The reason I didn’t do any of this (yet) is that since the default action for a chain is ACCEPT, the effect should be the same. And I don’t want to drop all on the LAN at this time either (want to make sure I get the inbound stuff right first and be careful about not blocking myself out of the router).
Well, this is an efficiency thing - it’s much quicker to accept established,related right away instead of working down through several rules before this decision - the vast majority of packets are going to be in established or related connection tracking state, so go ahead and allow them right away. Think of it like trains - you think of an entire train as one entity - you schedule it and route it as a whole, so you don’t have to make all of the same decisions and paperwork for each and every car of each and every train…
Any you can’t kick yourself out of a Mikrotik with the forward chain - this is impossible - because talking to the Mikrotik itself goes through the INPUT/OUTPUT chains, and not the forward chain - even if you’re on 192.168.1.123 and talking to the Mikrotik on an interface 192.168.2.1 - even though you’re going “through” the Mikrotik from one interface to the other, in reality you aren’t because the packets don’t go to the other interface, they just go up into the Mikrotik’s brain.
Any you can’t kick yourself out of a Mikrotik with the forward chain - this is impossible - because talking to the Mikrotik itself goes through the INPUT/OUTPUT chains, and not the forward chain …
Ah, that’s a good point, thanks
Regarding efficiency, the FASTRACK rule is the last FORWARD one, so adding an explicit ACCEPT afterwards shouldn’t make a difference anyway. That said I agree it’s good practice!
So here’s how I have my FORWARD chain configured. It’s not as locked down as I intend it to be, but it does everything I need it to at the moment…(note, I’ve removed the dst. addresses from my “Accept inbound…” rules)
Screen Shot 2016-03-11 at 11.18.15 AM.png
As you can see, the fasttrack rules are at the top. MT recommends putting the Accept rel/est immediately after the Fasttrack rule to catch any non-fasttrackable packets. I then allow forwarding between all internal interfaces (note I simply negated my WAN interface as the inbound AND outbound port), as well as allow forwarding of all traffic that goes out my WAN port. Then I have my accept rules for the few dst-natted ports I allow inbound (my mail and VPN servers), and then I drop and log all at the end of it. If your ACCEPT rules are properly configured, you really shouldn’t see any packets hit the drop-and-log rule. While doing the initial set up though, you can always place a temporary Allow-All rule just above it (enable logging) so you can see what traffic hasn’t been covered by a prior rule without causing any problems. Just remember to create explicit rules for the traffic you want to allow and then disable/delete the Allow-All rule as it’s a serious security risk.
If you’re using Winbox, I recommend using the filter to display only one chain at a time. When creating your rulesets, remember that the most restrictive rules should be at the top as packets are processed against the ruleset from the top down - and the first rule that matches a packet causes the packet to jump to the next chain (i.e. post-routing). While you generally want your most restrictive rules closer to the top, also pay attention to the counters to see how many packets are being processed by each rule. You also want your most frequently matched rules as close to the top of the chain as possible to minimize the amount of wasted processing.