A Working RouterOS Firewall Input Chain, Line by Line
Six rules that decide what can reach the router itself, in the order they must run — and the one rule every tutorial leaves out that makes the rest mean anything.
Most firewall tutorials show you how to allow things. Allow the LAN, allow the tunnel, allow ICMP. Then they stop.
The trouble is that a list of allow rules, on its own, allows nothing in particular and everything in general. RouterOS reads the input chain top to bottom and stops at the first rule that matches. If a packet reaches the bottom without matching an accept, what happens to it depends entirely on one rule most guides never mention — the one at the end.
This is the input chain from a working RouterOS 7.24 router, printed with packet counters so you can see which rules actually carry traffic:
/ip firewall filter print stats
Columns: CHAIN, ACTION, BYTES, PACKETS
# CHAIN ACTION BYTES PACKETS
;;; MGMT - lab only
0 input accept 8 713 51
1 input accept 0 0
2 input drop 0 0
3 input accept 0 0
4 input accept 1 116 6
;;; drop all else
5 input drop 18 711 63
Look at rule 5 before anything else. drop all else has dropped 63 packets, 18KB —
more than any accept rule has passed. That is the rule doing the most work on this
router, and it is the one a tutorial built only from allow rules would never have told
you to add. Without it, every one of those 63 packets would have reached the router
instead of being dropped.
Now the rules in order, because on this chain order is not a style choice — it is the logic.
Rule 0 — management access, first
/ip firewall filter
add chain=input action=accept in-interface-list=MGMT comment="MGMT - lab only"
0 ;;; MGMT - lab only
chain=input action=accept in-interface-list=MGMT
Management goes first for one reason: if you lock yourself out with a later rule, this is the rule that still lets you back in to fix it. Put your recovery path at the top, before anything that could match your own traffic and drop it.
The comment says lab only, and that is deliberate. This rule accepts anything arriving on the MGMT interface list with no source restriction, which is fine for an isolated lab segment and wrong for production. On a real device you would either bind management to a specific source subnet:
add chain=input action=accept in-interface-list=MGMT src-address=10.0.0.0/24 \
comment="MGMT from ops subnet"
or drop the interface-list rule entirely and reach the router only over a VPN that terminates before the firewall. The principle stays the same — recovery path first — but “any source on this interface” is not a recovery path you want exposed.
At 51 packets, this is where the traffic actually is: it is the SSH session used to run these commands.
Rule 1 — established and related
add chain=input action=accept connection-state=established,related
1 chain=input action=accept connection-state=established,related
This is the rule that makes a stateful firewall stateful. When the router makes an outbound connection — a DNS query, an NTP sync, a package check — the reply comes back inbound. This rule recognises that reply as part of a connection the router already started and accepts it, so you do not need a separate accept rule for every service the router talks to.
It sits near the top because the overwhelming majority of legitimate inbound packets are return traffic, and matching them early means the rest of the chain never has to be evaluated for them. On a busy router this is the rule with the highest counter. It reads zero here only because this lab router has barely talked to anything yet — the counters are honest, not illustrative.
Rule 2 — drop invalid
add chain=input action=drop connection-state=invalid
2 chain=input action=drop connection-state=invalid
A packet is invalid when the connection tracker cannot place it in any known
connection — a stray ACK, a malformed segment, a fragment that never reassembled.
Nothing legitimate is invalid, so it is dropped.
The position matters. This drop comes after established/related, not before — because you want the tracker to have its say on genuine return traffic first. It comes before every accept below it, so a malformed packet can never slip through by matching a looser rule further down.
Rule 3 — ICMP, on purpose
add chain=input action=accept protocol=icmp
3 chain=input action=accept protocol=icmp
There is a long-standing habit of blocking all ping. It is usually a mistake. ICMP is
how path MTU discovery works, how traceroute works, and how you find out whether a
device is even alive during an incident. A router that silently drops all ICMP is a
router that is harder to diagnose, including by you.
Accepting ICMP here is a deliberate decision, not an oversight. If you have a specific reason to rate-limit or restrict it, do that explicitly — but “drop all ping because security” costs more than it buys.
Rule 4 — the LAN
add chain=input action=accept in-interface-list=LAN
4 chain=input action=accept in-interface-list=LAN
Traffic from the trusted LAN interface list, addressed to the router itself — DNS queries to the router’s resolver, DHCP, management from inside. This is the “allow the LAN” rule that tutorials do include.
Six packets here, against 51 on the management rule, tells its own small story about where this router is actually reached from.
Rule 5 — drop all else
add chain=input action=drop comment="drop all else"
5 ;;; drop all else
chain=input action=drop
This is the rule. Everything above it is an exception carved out of this one line.
Without rule 5, RouterOS has a default policy of accept — a packet that matches none of your rules is allowed. So a chain of five accept rules and no final drop is not a whitelist. It is an open router with five accept rules that happen to be redundant, because anything they would have accepted was going to be accepted anyway. The accepts only mean something because this drop exists to catch everything they did not name.
Its 63-packet counter is the proof. Those are packets that matched none of rules 0 through 4 — scanning, stray internet noise on the WAN, connection attempts to services that should not be reachable — and rule 5 is the only thing that stopped them.
Why the order is the whole thing
Read the six rules as a sequence and the design is visible:
- Let yourself back in (management).
- Let return traffic through (established/related).
- Throw away garbage (invalid).
- Allow the diagnostics you actually want (ICMP).
- Allow the trusted segment (LAN).
- Drop everything else.
Move rule 5 (the final drop) above rule 0 and you lock yourself out — the drop matches your management traffic before the accept can. Move rule 2 (drop invalid) above rule 1 and you risk dropping the tail of legitimate connections. Delete rule 5 entirely and the other five stop meaning anything.
The forward chain below it follows the same shape — accept established, drop invalid, accept LAN-to-WAN, drop the rest — for exactly the same reasons, applied to traffic passing through the router rather than to it.
The test that matters
After you build a chain like this, do not check that your allow rules work. Check that the final drop is catching things. Print the stats and look at the last rule’s counter:
/ip firewall filter print stats
If drop all else reads zero after the router has been on a live network for a while,
either nothing is reaching it — unlikely, on any public address — or a rule above it is
accepting more than you think. A terminating drop that never fires is a terminating drop
that is not terminating anything.
Verified on RouterOS 7.24 (stable), build 2026-08-14, running as CHR on VMware Workstation. Counters captured live from the running chain; behaviour changes between releases, so check the version against what you run.