Skip to content

Connection Tracking

Connection Tracking (conntrack) maintains a state table of all active network flows through the router. It is the foundation of:

  • Stateful firewalling — matching established and related packets without explicit per-packet rules
  • NAT — translating addresses on the first packet and applying the translation to all subsequent packets in the same flow
  • Per-flow diagnostics — inspecting active connections to understand what traffic is traversing the router
/ip firewall connection print

Each row represents one tracked flow. Key fields include:

FieldDescription
protocolIP protocol (tcp, udp, icmp)
src-addressSource IP:port of the original flow direction
dst-addressDestination IP:port
reply-src-addressSource of the return direction (may differ after DNAT/SNAT)
reply-dst-addressDestination of the return direction
tcp-stateTCP connection phase (TCP only)
connection-stateHigh-level state: established, related, new, invalid, untracked
timeoutTime remaining before this entry expires
assuredyes when two-way traffic has been seen (SYN+SYN-ACK for TCP; request+reply for UDP)
seen-replyyes when at least one return packet has been received

Use print where to narrow down entries.

/ip firewall connection print where protocol=tcp
/ip firewall connection print where src-address~"192.168.88.50"
/ip firewall connection print where dst-address~"10.0.0."
/ip firewall connection print where seen-reply=no

Entries with seen-reply=no represent flows where the router has seen an outbound packet but no return traffic yet. Large numbers of these suggest:

  • Upstream firewall or routing blocking the return path
  • SYN flood — many TCP SYN packets with no SYN-ACK response
  • Asymmetric routing — return traffic arrives via a different path
/ip firewall connection print where tcp-state=syn-sent

RouterOS tracks TCP connections through the full connection lifecycle:

StateMeaning
syn-sentSYN sent, waiting for SYN-ACK
syn-receivedSYN received, SYN-ACK sent
establishedThree-way handshake complete, data flowing
fin-waitFIN sent, waiting for close from remote
close-waitRemote sent FIN, local hasn’t closed yet
time-waitBoth sides closed, waiting for stray packets to clear
closeConnection fully closed
listenServer socket waiting for incoming connection

The connection-state matcher in firewall rules uses a simplified view:

StateWhen Used
newFirst packet of a flow not yet tracked
establishedPacket belongs to a tracked bidirectional flow
relatedPacket belongs to a related flow (e.g. FTP data, ICMP error for an existing connection)
invalidPacket does not match any tracked flow and is not valid as a new connection
untrackedPacket from a flow explicitly marked to bypass conntrack

The example below uses in-interface-list=LAN and out-interface-list=WAN. These interface lists do not exist by default — create them and assign your interfaces first:

/interface list
add name=LAN
add name=WAN
/interface list member
add list=LAN interface=bridge
add list=WAN interface=ether1

Then apply the firewall baseline:

/ip firewall filter
add chain=forward connection-state=established,related,untracked action=accept comment="Allow established flows"
add chain=forward connection-state=invalid action=drop comment="Drop invalid packets"
add chain=forward connection-state=new action=accept in-interface-list=LAN out-interface-list=WAN comment="Allow new outbound"

View and tune global conntrack settings:

/ip firewall connection tracking print
SettingDescription
enabledyes / no / auto. Set auto to enable only when NAT or stateful filter rules require it
tcp-established-timeoutHow long to keep an established TCP flow after last packet (default: 1 day)
tcp-time-wait-timeoutTIME_WAIT duration (default: 10s)
udp-timeoutTimeout for unreplied UDP flows (default: 30s)
udp-stream-timeoutTimeout for replied UDP flows (default: 3m)
icmp-timeoutICMP flow timeout (default: 10s)
generic-timeoutTimeout for other protocols (default: 600s)

Tune these for specific traffic patterns — for example, lower udp-timeout if many short-lived UDP DNS queries are filling the table.

/ip firewall connection tracking set tcp-established-timeout=1h

Useful on routers with large numbers of idle TCP sessions consuming table memory.

NAT depends on conntrack. When NAT acts on the first packet of a new flow:

  1. Conntrack creates a new entry for the flow
  2. The NAT translation is stored in the connection entry
  3. All subsequent packets in that flow use the stored translation — no NAT rules are evaluated again

To verify NAT is translating correctly, inspect the reply-src-address and reply-dst-address fields:

/ip firewall connection print detail where protocol=tcp

If NAT is working, the reply fields will show the translated addresses.

FastTrack accelerates established/related TCP and UDP flows by bypassing most of the packet processing pipeline — including further firewall evaluation and queue rules. FastTrack requires an initial conntrack entry (created on the first packet) but then largely bypasses subsequent conntrack updates for that flow.

Effect on diagnostics: FastTracked connections may show stale timeout values in the connection table because they do not update conntrack on every packet.

When troubleshooting, disable FastTrack to restore full conntrack visibility:

/ip firewall filter disable [find action=fasttrack-connection]

Re-enable after the issue is resolved:

/ip firewall filter enable [find action=fasttrack-connection]
/ip firewall connection print where src-address~"192.168.88.100" and protocol=tcp

Check the reply-dst-address field. It should show the pre-NAT destination (the LAN IP), confirming masquerade or DNAT is working.

Asymmetric routing causes return packets to arrive via a different interface than expected, causing conntrack to classify them as invalid and the firewall to drop them.

# Check for invalid drops
/ip firewall filter print stats where action=drop
# Check for unreplied flows
/ip firewall connection print where seen-reply=no protocol=tcp

If invalid drops are increasing, check for asymmetric routing or resolve with rp-filter:

/ip settings set rp-filter=loose
/ip firewall connection print count-only where tcp-state=syn-sent

A large number of syn-sent entries is a strong indicator of a SYN flood or an upstream router not forwarding SYN-ACK responses.

If a connection appears stuck (e.g. stale entry preventing reconnection):

/ip firewall connection remove [find src-address~"10.0.0.50" and protocol=tcp]

This forces conntrack to remove the entry. The next packet from that source will create a new entry.

  • Firewall Filter — Stateful filtering using connection-state matchers
  • NAT — Address translation that depends on connection tracking
  • Torch — Real-time traffic visibility before firewall processing
  • Packet Sniffer — Full packet capture for protocol-level inspection
  • RouterOS Troubleshooting Methodology — Systematic approach to diagnosing connectivity issues