Expose on the LAN
--expose publishes the agent on the router’s LAN address, for a client that cannot reach the veth
/30: a Prometheus job, a browser, curl. It adds two tagged firewall rules and makes a token
mandatory.
mikroscope install --expose --lan-address 192.168.88.1Keep the token in MIKROSCOPE_TOKEN, which keeps it off the command line.
What install --expose adds
- two firewall rules, tagged
- a token becomes mandatory
uninstallandstatusfind the two rules through the manifest and the tag, with or without--expose
Every object carries the comment mikroscope:<name> (managed by mikroscope)
mikroscope plan prints every command before anything is written.
Default reachability
Section titled “Default reachability”The agent binds to the container’s address, the .2 of --subnet (172.30.10.2 by default), on
--port (9123). Without --expose it is reachable only from hosts the router routes to that veth
/30, through the two list memberships every install adds (Network
access).
Firewall rules
Section titled “Firewall rules”install --expose adds, after the list memberships and before the container, a dst-nat from the
router’s LAN address on the agent port to the veth:
/ip/firewall/nat/add chain=dstnat dst-address=<router LAN IP> protocol=tcp dst-port=9123 action=dst-nat to-addresses=172.30.10.2 to-ports=9123 comment="mikroscope:mikroscope (managed by mikroscope)"and a forward accept for that flow, placed before the first chain=forward action=drop rule, or
appended when the forward chain has no drop:
/ip/firewall/filter/add chain=forward dst-address=172.30.10.2 protocol=tcp dst-port=9123 connection-nat-state=dstnat action=accept comment="mikroscope:mikroscope (managed by mikroscope)" place-before=<first forward drop>- The addresses and the port are the defaults.
<first forward drop>stands for the lookup the real command does on the router before it adds the rule.planprints both commands exactly as they run, with your values. - Both carry the tag. The pair lets the LAN reach the agent through the router’s own address (verified).
--lan-addressmust be an IPv4 address;installrefuses--exposewithout one (--expose needs the router's IPv4 LAN address).doctorchecks that an interface of the router holds it and that it is not on the uplink.- An existing rule with the same chain, destination address, port and protocol that does not carry
the tag stops
install, as any foreign object does (Installer safeguards).
Reachable hosts
Section titled “Reachable hosts”Every LAN host can reach the agent at <router LAN IP>:9123. Neither rule restricts the source: the
dst-nat has no in-interface and no src-address, and the accept matches only the destination, the
port and connection-nat-state=dstnat. Which hosts get through is decided by which hosts can send a
packet to the router’s LAN address, and by whatever your other rules do before these. Whether
anything outside the LAN reaches that address depends on the rest of your firewall, which mikroscope
neither reads nor changes (not tested).
Because the agent is no longer reachable only through the veth, install and upgrade refuse
--expose without a token (--expose makes the agent reachable from the LAN: a token is mandatory).
With a token set, every endpoint the agent serves except /healthz returns 401 token required,
with WWW-Authenticate: Bearer, unless the request carries Authorization: Bearer <token>:
/capabilities, /sampler, /snapshot, /stream, /captures, /captures/{id} (including
DELETE) and POST /capture. A path the agent does not serve gets 404, and a wrong method 405,
token or not. The agent strips an optional "Bearer " prefix before comparing, so a header holding
the bare token is accepted too.
/healthz stays open. It returns the agent’s version, rate, sequence numbers, uptime, slip count,
capabilities hash, its wall and monotonic clocks, and the board’s device-tree model. The model is
there on purpose: it is what an operator is asked to send when their board has no kernel-to-RouterOS
port map yet.
What the token is, and is not:
- It may contain letters, digits,
_,.and-, up to 128 characters; anything else is refused before the first command. - It is stored in the envlist as
TOKEN. Aread,apiuser can list every container’senvlistproperty (verified); whether that user reads the entries’ values was not checked, and the design assumes it can. Treat the token as guarding the agent’s HTTP paths from the LAN, not from the router’s ownreadusers. doctor,statusandupgradecount theTOKENentries and never read their value; the install manifest says onlytoken=yesortoken=no.- A token set without
--exposeis still written and still required. - The agent compares it as a plain string, over plain HTTP: the dst-nat carries no TLS, so the header crosses the LAN unencrypted.
Clients of the address
Section titled “Clients of the address”The rules serve a client that addresses <router LAN IP>:<port>: a Prometheus job, a browser, a
curl with the header. mikroscope’s own commands do not use that address:
recordandforwardbuild the agent’s URL from--subnetand--port, so they always dial the container’s address. No flag points them at the LAN address.install,upgradeandstatusprobe/healthzat the container’s address too, anddoctorreads/healthzand then the agent’s ring there, presenting the token if one is given.- The relay transport cannot carry the token:
/tool fetchon the router sends noAuthorizationheader. Against an agent with a token, the relay’s/healthzanswers and every sample request is refused. A token needs the direct transport, or a deployment without a token.
Upgrade
Section titled “Upgrade”upgrade keeps both rules. It reads from the router that the install is exposed, removes the
container step (the container, the envlist <name>-env and the image) and creates it again, with the
envlist written from the flags given to upgrade.
- It refuses an install whose envlist holds a
TOKENwhen no token is given:the install named mikroscope asks for a token and upgrade would write its envlist without one: pass --token (or MIKROSCOPE_.TOKEN) - A tuning flag left out comes back at its default. Pass the
--rate,--buffer,--mem-limit-mb,--capture-mb,--triggers,--floor-hz,--memory-max,--privileged,--restart-max-countand--restart-intervalyou installed with.
Remove the rules
Section titled “Remove the rules”uninstall removes both rules with the rest of the install. It reads the install’s shape from the
router, so it needs neither --expose nor --lan-address, and no token:
mikroscope uninstall # lists what it would remove, the two rules includedmikroscope uninstall --yes # removes it- Each rule is selected by the tag together with the chain, destination address, port and protocol.
Any other object that carries the install’s tag in
/ip/firewall/nator/ip/firewall/filteris removed by the tag. - It then counts what is left, per step and per menu, and fails naming anything that remains.
- Those
findselectors quote every non-numeric value except thechainandactionenums. Unquoted, an address or a port is parsed as a typed value and matches nothing (verified), and a bare word such astcpis read as a variable name, whose unset value is empty.