FIREWALL / FORWARD CHAIN

Forward chain.

The forward chain matches traffic transiting the router — packets between your LAN and the internet, between VLANs, or between a VPN and the LAN. Most of the throughput-sensitive work lives here, which is why the rules have to be cheap and ordered carefully.

The full script

Six rules. The IPsec accept pair runs first because policy-matched traffic bypasses the rest of the chain and we want it short-circuited cheaply. FastTrack runs next so established flows skip the connection-tracker work on every packet.

forward-chain.rsc v6 18 lines · 803 bytes
# default forward-chain ruleset (RouterOS v6)
/ip firewall filter
add chain=forward action=accept ipsec-policy=in,ipsec \
  comment="mtkf: accept inbound IPsec policy"
add chain=forward action=accept ipsec-policy=out,ipsec \
  comment="mtkf: accept outbound IPsec policy"
add chain=forward action=fasttrack-connection \
  connection-state=established,related \
  comment="mtkf: fasttrack established/related"
add chain=forward action=accept \
  connection-state=established,related,untracked \
  comment="mtkf: accept established/related/untracked"
add chain=forward action=drop connection-state=invalid \
  comment="mtkf: drop invalid"
add chain=forward action=drop \
  connection-state=new connection-nat-state=!dstnat \
  in-interface-list=WAN \
  comment="mtkf: drop new WAN-ingress without dst-nat"
forward-chain.rsc v7 18 lines · 851 bytes
# default forward-chain ruleset (RouterOS v7)
/ip/firewall/filter
add chain=forward action=accept ipsec-policy=in,ipsec \
  comment="mtkf: accept inbound IPsec policy"
add chain=forward action=accept ipsec-policy=out,ipsec \
  comment="mtkf: accept outbound IPsec policy"
add chain=forward action=fasttrack-connection hw-offload=yes \
  connection-state=established,related \
  comment="mtkf: fasttrack established/related (hw-offload on supported boards)"
add chain=forward action=accept \
  connection-state=established,related,untracked \
  comment="mtkf: accept established/related/untracked"
add chain=forward action=drop connection-state=invalid \
  comment="mtkf: drop invalid"
add chain=forward action=drop \
  connection-state=new connection-nat-state=!dstnat \
  in-interface-list=WAN \
  comment="mtkf: drop new WAN-ingress without dst-nat"

What each rule does

1–2. Accept IPsec policy

Two rules — one for inbound, one for outbound. They pre-accept traffic matched by an IPsec policy so the connection-tracker doesn't have to re-evaluate every packet of an encrypted tunnel. If you don't run IPsec, these are no-ops and cost nothing.

3. FastTrack established/related

FastTrack is RouterOS's name for short-circuiting an established connection: subsequent packets skip most of the firewall and connection-tracking machinery. Massive throughput win on consumer hardware. Catch: a fast-tracked flow is invisible to most traffic accounting and to tool sniffer — you'll see the SYN handshake then nothing.

FastTrack hardware-offload differs

RouterOS v6

v6 doesn't expose hw-offload on FastTrack rules — the offload decision is implicit and depends on the hardware capabilities table.

RouterOS v7

v7 exposes hw-offload=yes|no explicitly. On supported boards (CCR2004, RB5009, hAP ax² and friends) this pushes flow handling into the switch chip — orders of magnitude faster than CPU forwarding.

4. Accept established, related, untracked

The fall-through accept for connections that didn't get FastTracked. Same reasoning as the input chain: return traffic for connections we already decided to allow.

5. Drop invalid

Same as input chain — packets that don't match any tracked connection and aren't legitimate new connections either. Cheap, no false positives.

6. Drop new from WAN without dst-nat

This is the rule that protects your LAN from the internet. A new connection arriving on a WAN interface, going to a destination that isn't a dst-nat target, has no business being forwarded — it's an unsolicited inbound to a NATted client, and dropping it is what makes IPv4 NAT incidentally a one-way membrane.

If you set up a port forward, RouterOS sets the connection's NAT state to dstnat before the firewall sees it, so this rule lets that traffic through. If you set up a port forward and traffic still gets dropped, your dst-nat rule probably runs after this filter rule — check the rule order in /ip firewall nat.

When you'd want to disable this

  • Running an IPv6-routed network without NAT (the common case for IPv6 ULA + delegated prefix). The rule still does the right thing for IPv4; for IPv6 see /firewall/ipv6.
  • Running a transparent proxy or bridge. FastTrack and the no-NAT-drop rule both assume normal NAT-edge behaviour; on a layer-2 bridge they don't apply.

References

  • MikroTik wiki: Manual:IP/Fasttrack
  • MikroTik wiki: Manual:IP/Firewall/Connection state