No description
  • Go 89.3%
  • Shell 9.4%
  • Dockerfile 1.3%
Find a file
chef 14118a81b7
Some checks failed
Run Gosec / GoSec Security Scanner (push) Failing after 10s
Nightly / nightly (push) Successful in 55s
dwadwa
2026-07-08 10:47:56 +02:00
.forgejo/workflows dwadwa 2026-07-08 10:47:56 +02:00
config batman 2026-07-03 00:37:02 +02:00
fetcher batman 2026-07-03 00:37:02 +02:00
influx rename and add release pipelines 2026-07-07 01:18:14 +02:00
packaging rename and add release pipelines 2026-07-07 01:18:14 +02:00
.env.example batman 2026-07-03 00:37:02 +02:00
.gitignore batman 2026-07-03 00:37:02 +02:00
.goreleaser.yml rename and add release pipelines 2026-07-07 01:18:14 +02:00
Containerfile rename and add release pipelines 2026-07-07 01:18:14 +02:00
go.mod rename and add release pipelines 2026-07-07 01:18:14 +02:00
go.sum batman 2026-07-03 00:37:02 +02:00
main.go rename and add release pipelines 2026-07-07 01:18:14 +02:00
README.md batman 2026-07-03 00:37:02 +02:00

opnsense-netflow-otel

Polls OPNsense's NetworkInsight API (interface bandwidth + top talkers/ports) and writes the results to InfluxDB as time series.

How it works

Every POLL_INTERVAL_SECONDS the daemon:

  1. Fetches per-interface octets/packets from FlowInterfaceTotals and writes them to the netflow_interface measurement (tags: interface, direction; fields: octets, packets, bps).
  2. Fetches the top TOP_N source addresses from FlowSourceAddrTotals and writes a snapshot to netflow_top_src_addr (tag: src_addr; field: octets).
  3. Fetches the top TOP_N destination ports from FlowDstPortTotals and writes a snapshot to netflow_top_dst_port (tags: dst_port, label; field: octets).

Each poll queries a window twice as wide as the interval, so a missed or slow tick never leaves a gap — InfluxDB overwrites points with an identical timestamp + tag set, so the overlap is safe to re-send.

Environment variables

Copy .env.example to .env and fill in the values. .env is loaded automatically on startup (real environment variables always take priority over it).

Variable Required Default Description
OPNSENSE_KEY yes OPNsense API key (System > Access > Users > user > API keys).
OPNSENSE_SECRET yes OPNsense API secret paired with the key above.
OPNSENSE_BASE_URL yes Base URL of the OPNsense instance, e.g. https://opnsense.local.
INFLUXDB_URL yes InfluxDB 2.x server URL, e.g. http://localhost:8086.
INFLUXDB_TOKEN yes InfluxDB API token with write access to the target bucket.
INFLUXDB_ORG yes InfluxDB organization name.
INFLUXDB_BUCKET yes InfluxDB bucket to write points into.
POLL_INTERVAL_SECONDS no 30 How often to poll OPNsense and write to InfluxDB, in seconds.
TOP_N no 10 How many entries to keep in each top-talkers/top-ports snapshot.
DEBUG no Unused by the app; kept for parity with .env.example.

The OPNsense NetworkInsight plugin (Reporting > Insight) must be enabled and have been collecting data for a while, otherwise the API returns empty results.

Running locally

1. Start a local InfluxDB 2.x

docker run -d --name netflow-influxdb -p 8086:8086 \
  -e DOCKER_INFLUXDB_INIT_MODE=setup \
  -e DOCKER_INFLUXDB_INIT_USERNAME=admin \
  -e DOCKER_INFLUXDB_INIT_PASSWORD=adminadmin \
  -e DOCKER_INFLUXDB_INIT_ORG=home \
  -e DOCKER_INFLUXDB_INIT_BUCKET=netflow \
  -e DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=devtoken123 \
  influxdb:2

Check it's up:

curl http://localhost:8086/health

The UI is at http://localhost:8086 (login admin / adminadmin).

2. Configure .env

cp .env.example .env

Fill in OPNSENSE_KEY, OPNSENSE_SECRET, OPNSENSE_BASE_URL for your OPNsense box, and set:

INFLUXDB_URL="http://localhost:8086"
INFLUXDB_TOKEN=devtoken123
INFLUXDB_ORG="home"
INFLUXDB_BUCKET="netflow"

(matching the container's org/bucket/token above).

3. Run the daemon

go run .

It logs each poll cycle and any fetch/write errors. Stop it with Ctrl+C.

4. Verify data is arriving

docker exec -it netflow-influxdb influx query \
  --org home --token devtoken123 \
  'from(bucket:"netflow") |> range(start: -10m) |> group(columns:["_measurement"]) |> count()'

You should see non-zero counts for netflow_interface, netflow_top_src_addr, and netflow_top_dst_port. Or browse the Data Explorer in the InfluxDB UI.

5. Tear down

docker rm -f netflow-influxdb

Building a binary

go build -o opnsense-netflow-otel .
./opnsense-netflow-otel