Skip to content

The two firewall traps

This page answers why an agent that is running can still be unreachable on a router with the MikroTik default firewall, and what install changes in that firewall so it is not. It adds two list memberships and nothing else; without --expose it writes no firewall rule.

Two rules that drop everything a container sends

Section titled “Two rules that drop everything a container sends”

The MikroTik default firewall carries two raw rules that silently drop every packet a container sends:

  • drop the rest (in-interface-list=!LAN) matches a packet that enters on an interface outside the LAN interface list, and a new veth is outside it.
  • drop local if not from default IP range (src-address-list=!LANs) matches a source address outside the LANs address list, and the container’s /30 is outside it.

The drop is silent. From your host the agent does not answer, and that looks the same as a container that is not running — which is why the probe after install asks the router whether the container runs before it suggests anything else.

install adds the veth to your LAN interface list and the container’s /30 to your LANs address list. Both are additions to lists that already exist, both carry the tag, and uninstall removes both by that tag plus the list and the member. With the defaults the two writes are:

Step Command
interface-list membership /interface/list/member/add list="LAN" interface="veth-mikroscope" comment="mikroscope:mikroscope (managed by mikroscope)"
address-list membership /ip/firewall/address-list/add list="LANs" address=172.30.10.0/30 comment="mikroscope:mikroscope (managed by mikroscope)"

On RB5009UG+S+, RouterOS 7.24.2, these two memberships were enough for a host on the LAN to reach the agent directly through the router.

A membership is not scoped to mikroscope. Any other rule on your router that matches the LAN interface list or the LANs address list matches the container’s traffic too, for as long as it is installed. Read your own rules with that in mind.

Pass the names your rules use:

  • --iface-list (MIKROSCOPE_IFACE_LIST): the list your in-interface-list=!… drop rule uses.
  • --addr-list (MIKROSCOPE_ADDR_LIST): the list your drop local if not from default IP range rule uses.

doctor checks both before install writes anything. An interface list that does not exist is reported with the fix /interface/list/add name=…, or the flag. An address list with no entries is reported too; its fix text says an empty list is fine only if no such rule exists, but the check still counts as missing, and only --no-doctor gets past it, skipping every other check with it. uninstall, status and upgrade need the same two flags again, because the selectors are built from them; with other names upgrade finds the memberships missing and refuses with nothing to upgrade: run install first.

If the veth is already in the interface list, or the /30 is already in the address list, and that entry does not carry mikroscope’s tag, install stops at that step and names it: the effect exists, but mikroscope did not create it and will not later remove it. Pick another --veth or --subnet, or remove your entry by hand if it is yours. uninstall never touches it.

Only --expose writes firewall rules: a dst-nat on the router’s LAN address and a forward accept placed before the first forward drop, both tagged, both removed by uninstall --expose --lan-address <the same address> --token: the dst-nat selector matches the LAN address, and --expose is refused without a token even though no selector uses it. What that opens and why the token becomes mandatory is on What –expose opens; how to use it is on Reaching the agent.