Skip to content

CheckMK Plugin

A CheckMK special agent plugin monitors flowwler's operational health and active-mitigation posture as native CheckMK services, by polling flowwler's own REST API. It is deliberately shallower than Prometheus metrics: no per-group traffic-rate time series or attack history — that stays Prometheus/Grafana's job. Use it alongside, not instead of, the /metrics endpoint.

The plugin is a separate project (checkmk-flowwler) from a separate repository, not bundled with the flowwler package or container images. It is not yet published to exchange.checkmk.com as of this writing.

Requirements

Component Minimum version
CheckMK 2.3.0p0
Python 3.11+ (bundled with CheckMK 2.3)
flowwler Any version exposing the v1 REST API

No third-party libraries are bundled or required — the special agent uses only the Python standard library.


Setup

  1. Install the MKP: bash mkp install flowwler-<version>.mkp cmk -R
  2. Create a CheckMK host whose address is the flowwler daemon's hostname or IP.
  3. Configure the agent rule — go to Setup → Agents → Other integrations → Networking and add the rule flowwler to that host, setting scheme (default http), port (default 9731), and authentication (default: none).
  4. Run a service discovery on the host. You should see flowwler Status, flowwler Mitigations, and one flowwler Router/BGP Peer/Notification Target/Prefix Source/Group service per entity flowwler currently knows about.

Authentication

flowwler has no authentication by default. If an API key is configured on the daemon (http.auth.api_key — see Configuration), select API Key in the agent rule; it's sent as the X-API-Key header. Bearer-token and HTTP Basic Auth (both also supported by flowwler itself) are not implemented by this plugin.


Services

Each service below is backed by one flowwler REST API endpoint, polled by the special agent.

Service Item Backing endpoint Reports
flowwler Status none GET /api/v1/status Version, uptime, dry-run mode; CRIT if the last config reload failed
flowwler Router <router> flow exporter address GET /api/v1/routers Up/down, protocol, sampling rate
flowwler BGP Peer <neighbor> BGP neighbor address GET /api/v1/bgp/peers Session established/not, ASN, update counts
flowwler Notification Target <name> target name GET /api/v1/notifications/targets Delivery health of the most recent attempt
flowwler Prefix Source <group>/<source> group + source GET /api/v1/prefix-sources Freshness of the last successful IRR/NetBox/URL refresh
flowwler Group <name> group name GET /api/v1/groups Active-mitigation posture: victim count and worst phase
flowwler Mitigations none GET /api/v1/mitigations Global count of active mitigations, broken down by type and source

flowwler Status and flowwler Mitigations have no check-parameters ruleset — their alerting logic is fixed (a failed reload is unambiguously CRIT; the mitigations count is purely informational, always OK). Every other service's thresholds are configurable via Setup → Services → Service monitoring rules.

flowwler Router

One service per flow exporter (NetFlow/IPFIX/sFlow) flowwler has seen. Considered down once no packets have arrived within the last 120 seconds (mirrors flowwler_router_up — see Metrics).

Parameter Default Description
State when router is down CRIT Monitoring state while a previously-seen router has gone silent

Example summary: Up (netflow, sampling 1:100) / Down (sflow)

flowwler BGP Peer

One service per configured BGP peer.

Parameter Default Description
State when session is not established CRIT Any SessionState other than established (idle, connect, active, opensent, openconfirm)

Example summary: Established (AS65000) / Session state: idle

flowwler Notification Target

One service per configured notification target (webhook, Slack, Teams, etc. — see Notifications).

Parameter Default Description
State when the last delivery attempt failed CRIT A broken alert channel is silent until the next real attack, hence CRIT by default

Example summary: Last delivery succeeded at 2026-08-30T09:00:00Z / Last delivery failed: connection refused

flowwler Prefix Source

One service per group that has an external prefix source configured (IRR, NetBox, or URL subnet/whitelist import — see Configuration).

Parameter Default Description
Warn when last refresh is older than 24 hours
Critical when last refresh is older than 72 hours

Example summary: Last refreshed 1.2h ago (340 IPv4 / 12 IPv6 routes)

flowwler Group

One service per configured group, rolling up its active_victims (from GET /api/v1/groups) into a single per-group status: how many victims are currently under mitigation, and the worst phase among them. Per-victim traffic rates are intentionally not surfaced here — that's what Metrics and the Grafana dashboards are for.

Parameter Default Description
State when any victim is in phase active WARN By the time a victim reaches active, the escalation engine has typically already applied a mitigation automatically — this defaults to WARN, not CRIT
State when victims are only in phase hold-down OK

Example summary: 2 active victim(s), worst phase: active

flowwler Mitigations

Itemless, global summary of active mitigations (blackhole/subnet-blackhole/flowspec, auto/manual) — a supplemental catch-all, particularly for manual mitigations that flowwler Group's rollup might not surface. Always OK.

Example summary: 3 active mitigation(s): 2 flowspec, 1 blackhole


Behavior when flowwler is partly unavailable

The special agent polls GET /health first. If that fails, the whole agent run aborts (exit 1, no sections at all) — nothing else is worth attempting when the daemon itself is unreachable.

Once /health succeeds, the remaining 7 monitoring endpoints are fetched concurrently and degrade independently: a single endpoint failing (timeout, non-2xx, malformed JSON) logs a warning to the agent's stderr and reports that section as empty for this cycle, rather than aborting the whole run. On the CheckMK side this typically surfaces as the affected services going UNKNOWN ("... not found in flowwler inventory" / "No status data available"), while every other service keeps reporting normally — check the special agent's stderr output (the service's "Check MK Discovery"/agent-output details, or cmk -d <host>) to see which endpoint failed and why.