Getting Started¶
Get the OPNsense Exporter up and running in under five minutes.
Prerequisites¶
- An OPNsense firewall supported by the compatibility policy
- API access enabled on OPNsense
- Network connectivity from the exporter host to the OPNsense API
- Docker, a Kubernetes cluster, or a Linux host with systemd
Step 1: Create an OPNsense API key¶
- Log in to the OPNsense web UI.
- Navigate to System > Access > Users.
- Select the user you want to generate an API key for (or create a dedicated monitoring user).
- Scroll to API keys and click the + button to generate a new key pair.
- Save the downloaded
.txtfile: it contains the key and secret.
Least privilege
Avoid using the root user for API keys. Create a dedicated user and assign only the required permissions for the metrics you need.
Step 2: Deploy the exporter¶
docker run -p 8080:8080 \
-e OPNSENSE_EXPORTER_OPS_API_KEY=YOUR_API_KEY \
-e OPNSENSE_EXPORTER_OPS_API_SECRET=YOUR_API_SECRET \
ghcr.io/rknightion/opnsense-exporter:latest \
--opnsense.protocol=https \
--opnsense.address=opnsense.example.com \
--exporter.instance-label=my-firewall \
--web.listen-address=:8080
services:
opnsense-exporter:
image: ghcr.io/rknightion/opnsense-exporter:latest
restart: always
command:
- --opnsense.protocol=https
- --opnsense.address=opnsense.example.com
- --exporter.instance-label=my-firewall
- --web.listen-address=:8080
environment:
OPNSENSE_EXPORTER_OPS_API_KEY: "${OPS_API_KEY}"
OPNSENSE_EXPORTER_OPS_API_SECRET: "${OPS_API_SECRET}"
ports:
- "8080:8080"
Download the latest release from GitHub Releases, then run:
Production credentials
Avoid passing credentials as command-line flags: they are visible in the process list. For production, prefer file-based secrets via OPS_API_KEY_FILE / OPS_API_SECRET_FILE (see Security: File-based secrets).
Step 3: Verify metrics¶
Once the exporter is running, open your browser or use curl:
You should see output containing lines like:
# HELP opnsense_up Whether the OPNsense API was reachable on the last health poll (1 = reachable, 0 = unreachable), updated on --collector.poll-interval independently of scrapes. A reachable box reporting a degraded subsystem stays 1; see opnsense_system_status_code and the per-subsystem status metrics.
# TYPE opnsense_up gauge
opnsense_up{opnsense_instance="my-firewall"} 1
opnsense_up reflects whether the OPNsense API was reachable on the last health poll, not whether the box is healthy and not the last scrape — scraping replays an in-memory snapshot and makes no API call. If it is 0, check the exporter logs for connection or authentication errors around the poll interval. A reachable box that OPNsense itself reports as degraded (e.g. a leftover crash report) keeps opnsense_up=1. Check opnsense_system_status_code (2 = OK, 1 = NOTICE, 0 = WARNING, -1 = ERROR) and opnsense_crash_reporter_status / opnsense_firewall_status instead.
Step 4: Configure Prometheus¶
Add a scrape job to your prometheus.yml:
scrape_configs:
- job_name: opnsense
scrape_interval: 30s
static_configs:
- targets:
- "exporter-host:8080"
relabel_configs:
- source_labels: [__address__]
target_label: instance
replacement: "my-firewall"
What's next?¶
- Configuration: full reference for all CLI flags, environment variables, and collector switches
- Deployment: production deployment guides for Docker, Kubernetes, and systemd
- Security: API key permissions, TLS configuration, and file-based secrets
- Collectors: overview of all 63 collectors and what they monitor
- Integration & Dashboards: Grafana dashboard setup and PromQL examples