Skip to content
MikroTik RouterOS Docs

MikroTik RouterOS Firewall Filter Basics: A Complete Guide

MikroTik RouterOS Firewall Filter Basics: A Complete Guide

Section titled “MikroTik RouterOS Firewall Filter Basics: A Complete Guide”

RouterOS Version: 7.x+ Difficulty: Beginner Estimated Time: 30 minutes

For the impatient: here’s the 30-second version.

# Minimal stateful firewall setup
/ip firewall filter add chain=input connection-state=established,related action=accept
/ip firewall filter add chain=input src-address=192.168.88.0/24 action=accept
/ip firewall filter add chain=forward connection-state=established,related action=accept
/ip firewall filter add chain=forward connection-state=invalid action=drop

The firewall filter is RouterOS’s packet filtering engine - the first line of defense that determines which network traffic is allowed, blocked, or processed differently. Understanding firewall filters is essential because every packet that enters, exits, or passes through your MikroTik router can be inspected and controlled.

This guide explains the fundamental concepts of how packets flow through RouterOS, the three critical filter chains, and the decision points that determine whether traffic reaches its destination or gets dropped into the digital void.

Before diving into configuration, it’s crucial to understand where in the packet processing pipeline firewall filters operate. RouterOS processes packets through multiple stages, and filters sit at specific decision points:

Internet ──→ [Interface] ──→ [Routing Decision] ──→ [Filter Chains] ──→ Destination

But the reality is more complex. Here’s the complete packet flow with filter insertion points:

Packet Processing Pipeline

Key insight: The routing decision happens BEFORE filtering. This means the router already knows whether a packet is destined for itself, should be forwarded, or is originating from the router before any filter rules are evaluated.

RouterOS has three predefined filter chains that cannot be deleted. Each serves a specific purpose in the packet processing flow:

INPUT Chain

Purpose: Filters packets destined for the router’s own IP addresses.

Examples of INPUT traffic:

  • SSH connections to the router’s management IP
  • Web interface access (HTTP/HTTPS)
  • SNMP queries to the router
  • Ping to the router’s IP address
  • DNS queries when the router acts as a DNS server

Critical concept: If you block legitimate management traffic in the INPUT chain, you can lock yourself out of the router.

FORWARD Chain

Purpose: Filters packets passing through the router from one network to another.

Examples of FORWARD traffic:

  • LAN clients accessing the Internet
  • Traffic between different VLANs
  • VPN clients accessing internal resources
  • Any packet where the router is not the final destination

Critical concept: This is where most of your security policies are implemented. The FORWARD chain controls what your users can access.

OUTPUT Chain

Purpose: Filters packets originating from the router itself.

Examples of OUTPUT traffic:

  • Router making NTP time synchronization requests
  • Router performing DNS lookups
  • Router downloading software updates
  • Router sending SNMP traps or syslog messages

Critical concept: OUTPUT filtering is often overlooked but important for preventing compromised routers from becoming attack platforms.

When a packet matches a firewall rule, the specified action determines what happens next. The three fundamental actions form the foundation of all firewall policies:

action=accept

Behavior: The packet is allowed to continue, and no further rules in the same chain are processed.

Use when: You want to explicitly permit traffic and ensure it doesn’t get blocked by later rules.

Example scenario: Allow SSH from management network:

/ip firewall filter add chain=input src-address=192.168.99.0/24 dst-port=22 protocol=tcp action=accept

Critical insight: ACCEPT stops rule processing in the current chain. If you have a “drop all” rule at the end, accepted packets won’t reach it.

action=drop

Behavior: The packet is silently discarded. No response is sent to the sender.

Use when: You want to block traffic without revealing that a firewall exists.

Example scenario: Drop invalid connection attempts:

/ip firewall filter add chain=forward connection-state=invalid action=drop

Security benefit: Attackers can’t distinguish between a filtered port and a non-existent service, making reconnaissance harder.

action=reject

Behavior: The packet is blocked, but an ICMP error message is sent back to the sender.

Use when: You want to block traffic but provide feedback that the connection was actively refused.

Example scenario: Reject HTTP access with “port unreachable”:

/ip firewall filter add chain=input dst-port=80 protocol=tcp action=reject reject-with=icmp-port-unreachable

Trade-off: REJECT is more “polite” but reveals the presence of a firewall. It also generates additional traffic.

Firewall rules are processed sequentially from top to bottom until a terminating action is reached. Understanding this flow is crucial for effective firewall design:

Rule Processing Logic

Terminating actions: accept, drop, reject Non-terminating actions: log, passthrough, add-src-to-address-list

Example rule order:

# Rule 1: Accept established connections (most traffic matches here)
/ip firewall filter add chain=forward connection-state=established,related action=accept
# Rule 2: Accept new HTTP connections (specific allow)
/ip firewall filter add chain=forward dst-port=80 protocol=tcp connection-state=new action=accept
# Rule 3: Drop everything else (default deny)
/ip firewall filter add chain=forward action=drop

Critical mistake: Placing a broad “drop all” rule before specific allow rules will block everything.

Connection State: The Foundation of Stateful Filtering

Section titled “Connection State: The Foundation of Stateful Filtering”

RouterOS maintains a connection tracking table that remembers the state of network connections. This enables stateful filtering - making decisions based on the connection’s history, not just individual packets.

established: Packets belonging to an existing, active connection.

  • Example: Data packets in an ongoing HTTP download
  • Performance tip: Accept these first to bypass further rule processing

related: Packets that are related to an existing connection but start a new flow.

  • Example: FTP data connection spawned from FTP control connection
  • Example: ICMP error messages related to an existing TCP connection

new: The first packet of a new connection.

  • Example: Initial TCP SYN packet
  • Security focus: This is where you implement your access policies

invalid: Packets that don’t match any known connection state.

  • Example: TCP packets with wrong sequence numbers
  • Security practice: Always drop invalid packets

The most common and effective firewall pattern:

# Accept established and related connections (performance)
/ip firewall filter add chain=forward connection-state=established,related action=accept
# Drop invalid packets (security)
/ip firewall filter add chain=forward connection-state=invalid action=drop
# Allow specific new connections (policy)
/ip firewall filter add chain=forward connection-state=new dst-port=80 protocol=tcp action=accept
# Drop everything else (default deny)
/ip firewall filter add chain=forward action=drop

Why this works:

  1. Existing connections flow through quickly (performance)
  2. Malformed traffic is blocked immediately (security)
  3. New connections are evaluated against policy (control)
  4. Unknown traffic is denied (security)
# Accept established connections
/ip firewall filter add chain=input connection-state=established,related action=accept
# Accept management from trusted network
/ip firewall filter add chain=input src-address=192.168.99.0/24 action=accept
# Accept ICMP (ping, traceroute)
/ip firewall filter add chain=input protocol=icmp action=accept
# Drop everything else
/ip firewall filter add chain=input action=drop
# Accept established connections
/ip firewall filter add chain=forward connection-state=established,related action=accept
# Drop invalid packets
/ip firewall filter add chain=forward connection-state=invalid action=drop
# Allow LAN to Internet
/ip firewall filter add chain=forward src-address=192.168.88.0/24 action=accept
# Drop everything else
/ip firewall filter add chain=forward action=drop
# Accept established connections
/ip firewall filter add chain=forward connection-state=established,related action=accept
# Allow management VLAN to access everything
/ip firewall filter add chain=forward src-address=10.99.0.0/24 action=accept
# Allow user VLAN to Internet only
/ip firewall filter add chain=forward src-address=10.100.0.0/24 dst-address=!10.0.0.0/8 action=accept
# Allow guest VLAN to Internet and DNS only
/ip firewall filter add chain=forward src-address=10.200.0.0/24 dst-address=!10.0.0.0/8 action=accept
/ip firewall filter add chain=forward src-address=10.200.0.0/24 dst-address=10.99.0.1 dst-port=53 protocol=udp action=accept
# Drop everything else
/ip firewall filter add chain=forward action=drop

This section provides a minimal testable configuration that demonstrates the core firewall filter concepts from this guide.

Protect the router itself with a simple INPUT chain policy:

/ip firewall filter add chain=input connection-state=established,related action=accept comment="Allow established connections
/ip firewall filter add chain=input src-address=192.168.88.0/24 action=accept comment="Allow LAN management access

Control traffic passing through the router:

/ip firewall filter add chain=forward connection-state=established,related action=accept comment="Allow established connections
/ip firewall filter add chain=forward connection-state=invalid action=drop comment="Drop invalid packets

Confirm your firewall rules are active and processing traffic:

/ip firewall filter print

Expected Output:

Flags: X - disabled, I - invalid, D - dynamic
# CHAIN ACTION SRC-ADDRESS CONNECTION-STATE
0 input accept established,related
1 input accept 192.168.88.0/24
2 forward accept established,related
3 forward drop invalid
/ip firewall filter print stats

Expected Output:

# CHAIN ACTION BYTES PACKETS
0 input accept 1,234,567 8,901
1 input accept 45,678 234
2 forward accept 9,876,543 12,345
3 forward drop 1,024 8

Problem: “I can’t access the router after adding firewall rules

Section titled “Problem: “I can’t access the router after adding firewall rules”

Cause: INPUT chain rules are blocking management access.

Solution:

  1. Connect via serial console or safe mode
  2. Check INPUT chain rules: /ip firewall filter print where chain=input
  3. Add management access rule: /ip firewall filter add chain=input src-address=YOUR_MANAGEMENT_NETWORK action=accept place-before=0

Problem: “Internet access stopped working after adding FORWARD rules

Section titled “Problem: “Internet access stopped working after adding FORWARD rules”

Cause: FORWARD chain is blocking outbound traffic or return traffic.

Solution:

  1. Check if established connections are accepted first
  2. Verify NAT rules are still working: /ip firewall nat print
  3. Temporarily disable FORWARD rules to test: /ip firewall filter disable [find chain=forward]

Cause: Rules may be unreachable due to earlier terminating actions.

Solution:

  1. Check rule order: /ip firewall filter print
  2. Look for broad ACCEPT or DROP rules that might match first
  3. Use /ip firewall filter move to reorder rules

Problem: “Connection timeouts instead of immediate blocks

Section titled “Problem: “Connection timeouts instead of immediate blocks”

Cause: Using DROP instead of REJECT for user-facing services.

Solution: Change action to REJECT for better user experience:

/ip firewall filter set [find action=drop] action=reject

Always end each chain with a default deny rule:

/ip firewall filter add chain=input action=drop comment="Default deny INPUT
/ip firewall filter add chain=forward action=drop comment="Default deny FORWARD

Invalid packets should be dropped immediately:

/ip firewall filter add chain=input connection-state=invalid action=drop place-before=0
/ip firewall filter add chain=forward connection-state=invalid action=drop place-before=0

Add logging to monitor potential attacks:

/ip firewall filter add chain=input action=drop log=yes log-prefix="INPUT-DROP: " comment="Log and drop

Create address lists for easier management:

/ip firewall address-list add list=management-networks address=192.168.99.0/24
/ip firewall address-list add list=management-networks address=10.0.0.0/8
/ip firewall filter add chain=input src-address-list=management-networks action=accept

Wrong: Trying to block Internet access in INPUT chain

# This won't work - INPUT is for traffic TO the router
/ip firewall filter add chain=input dst-address=facebook.com action=drop

Right: Use FORWARD chain for transit traffic

# This works - FORWARD is for traffic THROUGH the router
/ip firewall filter add chain=forward dst-address=facebook.com action=drop

Wrong: Specific rules after general rules

/ip firewall filter add chain=input action=drop comment="Drop all
/ip firewall filter add chain=input src-address=192.168.88.0/24 action=accept comment="Allow management

Right: Specific rules before general rules

/ip firewall filter add chain=input src-address=192.168.88.0/24 action=accept comment="Allow management
/ip firewall filter add chain=input action=drop comment="Drop all

Wrong: Blocking return traffic

/ip firewall filter add chain=forward src-address=192.168.88.0/24 action=accept
/ip firewall filter add chain=forward action=drop

Right: Allow established connections

/ip firewall filter add chain=forward connection-state=established,related action=accept
/ip firewall filter add chain=forward src-address=192.168.88.0/24 action=accept
/ip firewall filter add chain=forward action=drop

For high-bandwidth connections, use FastTrack to bypass CPU processing:

/ip firewall filter add chain=forward connection-state=established,related action=fasttrack-connection
/ip firewall filter add chain=forward connection-state=established,related action=accept

Note: FastTrack only works with simple routing scenarios and may conflict with advanced features.

  1. Most specific rules first: Place frequently matched rules at the top
  2. Use connection state: Accept established connections early
  3. Minimize rule complexity: Simple rules process faster
  4. Use hardware offloading: When available on your device