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.
# 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" # 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
v6 doesn't expose hw-offload on FastTrack rules — the offload decision is implicit and depends on the hardware capabilities table.
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