Skip to content

Firewall Raw Table

The RouterOS firewall raw table provides the earliest point to intercept packets — before connection tracking runs. This makes it the right place to drop unwanted traffic cheaply (no conntrack entry is ever created) and to exempt trusted high-throughput flows from stateful tracking overhead.

Two built-in chains are available: prerouting for all arriving packets, and output for packets originating from the router itself.

Drop known-bad sources and bypass connection tracking for trusted transit before conntrack sees any packet:

/ip firewall raw
# Drop bogon sources immediately — no conntrack entry created
add chain=prerouting src-address-list=bogon action=drop comment="drop bogons pre-conntrack"
# Exempt trusted high-throughput transit from connection tracking
add chain=prerouting src-address=10.0.0.0/8 dst-address=10.0.0.0/8 \
action=notrack comment="bypass conntrack for trusted transit"
add chain=output src-address=10.0.0.0/8 dst-address=10.0.0.0/8 \
action=notrack comment="bypass conntrack router-generated transit"
# Allow everything else through to normal conntrack/filter processing
add chain=prerouting action=accept comment="pass remaining to conntrack"

After using notrack, update filter rules to allow untracked packets:

/ip firewall filter
# Accept established, related, AND untracked — required when notrack is used
add chain=forward action=accept \
connection-state=established,related,untracked comment="accept tracked and untracked"
add chain=forward action=drop connection-state=invalid comment="drop invalid"
ChainProcessesTypical Use
preroutingAll packets arriving on any interface, before routing decisionEarly drops, connection tracking bypass for inbound and forwarded traffic
outputPackets originating from the router itself, before they leaveBypass conntrack for router-generated traffic (routing protocols, DNS, etc.)

prerouting runs on every packet the router receives — whether destined for the router itself or to be forwarded. It fires before connection tracking, so:

  • Dropping here prevents a conntrack entry from being created at all.
  • notrack here marks the packet so it bypasses the conntrack engine entirely.
# Drop packets from a blacklist before any conntrack work
/ip firewall raw add chain=prerouting \
src-address-list=attackers action=drop comment="pre-conntrack blacklist drop"
# Bypass tracking for a specific UDP service (e.g. game server, media stream)
/ip firewall raw add chain=prerouting protocol=udp dst-port=9000-9100 \
action=notrack comment="notrack high-rate UDP service"

output processes packets the router itself generates (routing protocol hellos, NTP, DNS queries, management traffic). Using notrack here can reduce conntrack overhead for high-rate router-originated traffic.

# Exempt OSPF multicast from connection tracking
/ip firewall raw add chain=output protocol=89 \
action=notrack comment="notrack OSPF"
# Exempt router DNS queries from conntrack
/ip firewall raw add chain=output protocol=udp dst-port=53 \
action=notrack comment="notrack router DNS queries"

Bypassing Connection Tracking with notrack

Section titled “Bypassing Connection Tracking with notrack”

The notrack action tells the conntrack engine to ignore a packet entirely. The packet moves through the rest of the pipeline as connection-state=untracked.

When notrack makes sense:

  • High-packet-rate UDP flows where statefulness is not needed (media, game servers, certain VoIP paths)
  • Pure transit between known-good networks where NAT and stateful inspection are not required
  • Routing protocol traffic (OSPF, BGP) originated or received by the router
  • Any class of traffic where conntrack overhead is measurable and tracking provides no benefit

Consequences of notrack — read before applying:

FeatureEffect when notrack is used
Stateful filter matching (connection-state)Not available — packet appears as untracked
NAT (masquerade, src-nat, dst-nat)Does not apply to untracked packets
Connection accountingNot tracked
FastTrack offloadRequires conntrack — unavailable for untracked flows

Scope notrack narrowly. Applying it broadly breaks NAT and stateful firewall policies for affected traffic.

Adjusting filter rules after notrack:

# Without this, untracked packets may hit a default drop rule in forward chain
/ip firewall filter add chain=forward \
connection-state=established,related,untracked action=accept \
comment="accept tracked and untracked forwarded traffic"

Dropping attack traffic in the raw table is more efficient than dropping in filter because the packet is discarded before a conntrack entry is ever allocated. Under volumetric floods, this prevents conntrack table exhaustion.

/ip firewall raw
add chain=prerouting src-address-list=ddos-attackers \
dst-address-list=ddos-targets action=drop \
comment="Drop attack flows pre-conntrack"

Dynamic Detection (Filter) + Enforcement (Raw)

Section titled “Dynamic Detection (Filter) + Enforcement (Raw)”

The recommended pattern: detect attack pairs in the filter table where richer matching is available, populate address lists, then enforce the drop in raw.

# Step 1 — detect in filter (new connections only)
/ip firewall filter
add chain=forward connection-state=new action=jump \
jump-target=detect-ddos comment="check new connections for flood"
add chain=detect-ddos dst-limit=32,32,src-and-dst-addresses/10s \
action=return comment="within rate limit — return to forward"
add chain=detect-ddos action=add-dst-to-address-list \
address-list=ddos-targets address-list-timeout=10m \
comment="mark flood target"
add chain=detect-ddos action=add-src-to-address-list \
address-list=ddos-attackers address-list-timeout=10m \
comment="mark flood source"
# Step 2 — enforce in raw (before conntrack)
/ip firewall raw
add chain=prerouting src-address-list=ddos-attackers \
dst-address-list=ddos-targets action=drop \
comment="Drop identified attack flows pre-conntrack"

Once attacker/target pairs are in the address lists, subsequent packets from those sources are dropped in raw without touching conntrack or filter at all.

AspectRaw tableFilter table
Position in packet flowBefore connection trackingAfter connection tracking
Connection tracking costZero for dropped/notrack packetsAlways incurred
Available actionsaccept, drop, notrack, jump, return, log, passthroughFull action set including reject, fasttrack, tarpit
Stateful matchers (connection-state, connection-mark)Not available (no conntrack yet)Available
Address/port/protocol matchingYesYes
NAT interactionNone — NAT runs after rawNAT (src/dst) applies to tracked packets
Best forVolumetric drops, conntrack bypass, routing protocol exemptionsStateful policy enforcement, per-connection control

Use raw when:

  • Dropping garbage traffic at maximum efficiency (flood mitigation, blacklists)
  • Bypassing conntrack for specific high-throughput flows
  • Exempting routing protocol traffic from tracking

Use filter when:

  • Enforcing policy based on connection state (new, established, related, invalid)
  • Rules depend on connection marks set by mangle
  • NAT interaction matters
  • Full action flexibility is needed (reject, fasttrack, etc.)

A common production pattern combines both: raw handles volume drops cheaply, filter handles policy for everything that gets through.

Check rule hit counts:

/ip firewall raw print stats

Compare CPU load before/after moving drops to raw:

/tool profile
/system resource monitor

Verify conntrack table is not exhausted during a flood:

/ip firewall connection print count-only
/ip firewall connection tracking print

IPv6 raw table — the same concepts apply under /ipv6 firewall raw, with prerouting and output chains.