# Network access

Reach the agent on its veth address from your host, directly, through a static route, over the RouterOS API relay or with --expose, and read what the probe after install says.

Source: https://docs.jmrp.io/mikroscope/install/reaching-the-agent/

The agent listens on its veth address only, `http://172.30.10.2:9123` with the defaults, and opens
no outbound connection. Your host reaches it in one of three ways: directly through the router, over
the RouterOS API relay, or on the router's LAN address with `--expose`.

## Compare transports

| Way        | Needs                                                                   | Limits                                                                                                                                                 |
| ---------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| direct     | a route from your host to the /30 through the router                    | none beyond the two list memberships `install` adds                                                                                                    |
| relay      | an API user with `read,api,test`; `--transport relay`, or `auto`        | 64 512 B and 13 samples per call, about 1 s for about half the calls, no token |
| `--expose` | `--lan-address` and a token; two firewall rules on the router           | reachable from the whole LAN; `record`, `forward`, the probe and `doctor`'s health read do not use it                                                  |

## Direct (default)

Your host sends plain HTTP to the agent's address, and the router forwards it to the veth. Two
things make that work:

- **The firewall lets it through.** The two list memberships `install` adds are enough for the raw
  drop rules of MikroTik's advanced firewall ([verified](https://docs.jmrp.io/mikroscope/about/status/#verified-direct-lists));
  [Firewall lists](https://docs.jmrp.io/mikroscope/install/firewall/) has the rules and `doctor`'s check of your own.
- **Your host routes the /30 to the router.** A host whose default gateway is the router already
  does.

With a token set, the direct transport sends `Authorization: Bearer <token>`, from `--token` or
`MIKROSCOPE_TOKEN`. `/healthz` never needs it.

### Static route

A host whose default gateway is another router needs a route for the /30 through the router's LAN
address. On Linux, with your `--subnet` and the router's LAN address:

```sh
sudo ip route add 172.30.10.0/30 via 192.168.88.1
```

A wider prefix that holds the /30 works too, such as `172.30.0.0/16`
([tested](https://docs.jmrp.io/mikroscope/about/status/#virtual-lab)). Make the route permanent the way your system keeps
its network configuration.

## API relay

`record` and `forward` with `--transport relay` run `/tool fetch` on the router over the binary API,
and the router, which reaches its own veth, fetches from the agent.

1. Create a RouterOS user with the `read,api,test` policy: `/tool fetch` requires `test`
   ([verified](https://docs.jmrp.io/mikroscope/about/status/#verified-test-policy)), and without it the call returns
   `not enough permissions (9)`. [API user](https://docs.jmrp.io/mikroscope/security/api-user/) has the commands.
2. Give the CLI `--api host:port` (`MIKROSCOPE_API_ADDR`), `--api-user` (`MIKROSCOPE_API_USER`) and
   the password in `MIKROSCOPE_API_PASSWORD`. The password has no flag.
3. Run `record` or `forward` with `--transport relay`.

What the relay cannot do:

- **Large replies.** RouterOS truncates a reply longer than 64 512 B,
  silently. The relay asks for at most 13 samples per call and refuses
  a reply that reaches the cap rather than parse it truncated. `forward` warns at start when that
  cannot keep up with the agent's rate.
- **Fast calls.** A call takes either about 3 ms or about 1 s, and about half take 1 s
  ([measured](https://docs.jmrp.io/mikroscope/about/status/#campaign-relay-fetch)).
- **A token.** The relay passes only the URL to `/tool fetch`, with no header. Every path but
  `/healthz` returns 401 without the token, so an agent installed with one needs the direct
  transport.

`--transport auto`, the default, tries the direct transport first. If `/healthz` does not answer and
`--api` and `--api-user` are set, it tries the relay; otherwise it fails with
``direct transport did not answer and the relay is not configured: … (or `install --expose`)``.

## Expose on the LAN

```sh
mikroscope install --expose --lan-address 192.168.88.1
```

Keep the token in `MIKROSCOPE_TOKEN`, which keeps it off the command line.

**What `install --expose` adds**

- two firewall rules, tagged
- a token becomes mandatory
- `uninstall` and `status` find 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.

`--expose` adds a dst-nat from the router's LAN address on the agent port to the veth, and a forward
accept for that flow placed before the first forward drop, or appended when the forward chain has no
drop. Every LAN host can then reach the agent, so:

- `install` and `upgrade` refuse `--expose` without a token (`--token` or `MIKROSCOPE_TOKEN`) or
  without an IPv4 `--lan-address`.
- `status` and `uninstall` need neither flag: they read from the router that the install is exposed,
  and `uninstall` removes both rules with the rest.
- `doctor` checks the address:

The checks doctor runs:

| Check, as printed | Passes when | The fix it names |
| --- | --- | --- |
| --lan-address <address> is the router's | with `--expose`: an interface of the router holds that address | pass the address the router has on its LAN, as `/ip/address/print` lists it |
| --lan-address is not on the uplink | a warning, with `--expose`: the interface that holds the address carries no default route, is in no `WAN` list, and shares no interface list with the interface that carries the default route | pass the router's LAN address: on the uplink the dst-nat would publish the agent on the Internet side |

A client you point at `http://<router LAN IP>:9123` uses the exposed path: Prometheus, `curl`, a
browser. The CLI's own transports do not. `record`, `forward`, the probe after `install` and the
health read of `doctor` build the agent's address from `--subnet` and `--port`, and no flag points
them at the LAN address. `doctor`'s health read does not use the relay either: it reads directly or
not at all.

[Expose on the LAN](https://docs.jmrp.io/mikroscope/security/expose/) has both rules, the token, and who reaches the
agent through them.

## Install probe

After `install` and `upgrade`, the CLI probes the agent from your host: a TCP connect to the agent's
address and port, then `GET /healthz`. Each attempt times out after 2 s and is retried a second
later, for up to 30 s. When the agent answers, the CLI prints its version, rate, sequence number,
slipped ticks and the round trip:

```text
probing http://172.30.10.2:9123/healthz from this host …
  direct transport ok: agent 1.6.1 (<commit>) built <time>, 10 Hz, seq 4, 0 slipped, 2ms round trip
```

An agent the CLI built reports the CLI's own version, commit and build time. One the router pulled,
or loaded from a release tar, reports the release it was built for.

When the agent does not answer, the CLI asks the router, in one more connect, whether the container
runs, because a veth is up only while its container runs:

| The CLI prints                                                                                | Means                                                              | Do                                                                                                  |
| --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- |
| ``the container is not running on the router: check `/log/print where topics~"container"` `` | the container stopped or never started, so its veth is down         | read the router log; the firewall is not the problem yet                                            |
| `the container runs; this host cannot reach 172.30.10.2. Options: …`                          | a firewall rule or a missing route stands between this host and the /30 | check [Firewall lists](https://docs.jmrp.io/mikroscope/install/firewall/), add a [static route](https://docs.jmrp.io/mikroscope/install/reaching-the-agent/#static-route), or use the relay or `--expose` |
| `could not ask the router whether the container runs: …`                                      | the connect that asks failed                                       | run `mikroscope status`                                                                             |

Either way the command fails with `agent installed but not reachable from this host`, and everything
it created stays on the router.

## See also

- [Firewall lists](https://docs.jmrp.io/mikroscope/install/firewall/): the memberships the direct transport depends on.
- [API user](https://docs.jmrp.io/mikroscope/security/api-user/): the user the relay needs, and where to restrict it.
- [Expose on the LAN](https://docs.jmrp.io/mikroscope/security/expose/): the two rules and the token.
- [Run the collector](https://docs.jmrp.io/mikroscope/sinks/): what pulls from the agent once it is reachable.
