OPNsense monitoring
The firewall is monitored over the LAN by two exporters that feed the
Prometheus stack in monitoring/:
os-node-exporterplugin on OPNsense. CPU, RAM, load, uptime, filesystem, swap, and NIC counters (node_*) under theopnsense-nodejob.opnsense-exportercontainer (monitoring/compose.yaml). Gateways, API health, firmware, services, and interface counters pulled from the OPNsense API (jobopnsense-api). Its LAN endpoint is supplied through the private monitoring environment rather than repeated in public documentation.
Dashboard: OPNsense Firewall (uid: opnsense). Alerts:
monitoring/prometheus/rules/opnsense.yml.
One-time GUI setup
SSH to OPNsense is read-only, so do all of this in the web UI.
-
Install the node-exporter plugin. System > Firmware > Plugins, install
os-node-exporter. Then Services > Node Exporter: enable it, listen on the LAN interface, port9100, and turn on these collectors: -
CPU Statistics
- Filesystem Statistics
- Memory Statistics
- Network Interface Statistics
CPU supplies utilization and Filesystem supplies root-capacity monitoring.
Uptime is exported automatically. The dashboard does not use the EXEC, NTP,
Device, or ZFS collectors. Confirm from the server that the configured LAN
scrape endpoint returns metrics.
2. Create a read-only monitoring user and API key. System > Access > Users,
add a dedicated monitoring user (no shell, no GUI). Give it a group whose
privileges are limited to exactly these 8 pages (using the exact OPNsense
privilege names): System: Gateways, System: Status, System: Firmware,
Status: Services, Reporting: Traffic, Diagnostics: ARP Table, Diagnostics:
Firewall statistics, Diagnostics: Netstat. Do not grant the Unbound, VPN,
Kea, or Cron pages: the corresponding exporters are outside this dashboard's
scope and are disabled in Compose.
Generate
an API key, paste the key and secret into monitoring/.env on the server as
OPNSENSE_EXPORTER_OPS_API_KEY and _SECRET.
3. Firewall rule. Confirm the monitoring host can reach the node-exporter
endpoint over the LAN. The default LAN-to-firewall allow usually covers
this.
What is monitored
The dashboard shows current WAN status, RTT, jitter, loss, and throughput plus their 24-hour history; API health; host CPU, memory, normalized load, filesystem, swap, and uptime; firmware and reboot state; interface traffic and errors in both directions; service history; and actionable API endpoint errors.
opnsense-exporter v0.0.16 cannot parse one very large protocol-statistics
counter that this firewall returns. The resulting
api/diagnostics/interface/get_protocol_statistics error is a known upstream
limitation (AthennaMind/opnsense-exporter#112), so it is excluded from the
actionable-error panel and its alert. Every other endpoint error stays visible
and alerts after repeated failures. This dashboard does not use the protocol
statistics.
Two more v0.0.16 quirks are handled explicitly:
- OPNsense 26.1 omits
metadata.Firewallfromapi/core/system/status, which makes the exporter'sopnsense_firewall_statusfalsely report0. The dashboard and alerts use the reliableopnsense_upAPI-health metric instead. - The exporter reports a zero gateway high-latency threshold on this installation, so the latency alert and graph fall back to 100 ms when no positive configured threshold is available.
The OPNsense node-exporter exposes no temperature metric on this hardware, so normalized one-minute load fills the panel and alert that would otherwise track temperature.
After deploying, confirm the new series exist before trusting the panels:
curl -s 'http://localhost:9090/api/v1/query?query=node_load1%7Bjob%3D%22opnsense-node%22%7D'
curl -s 'http://localhost:9090/api/v1/query?query=node_filesystem_size_bytes%7Bjob%3D%22opnsense-node%22%2Cmountpoint%3D%22%2F%22%7D'
curl -s 'http://localhost:9090/api/v1/query?query=opnsense_exporter_endpoint_errors_total%7Bjob%3D%22opnsense-api%22%7D'
Deploy
Deploy the four Compose projects through Ansible:
cd /opt/homelab
git pull
cd ansible
ansible-playbook -c local playbooks/deploy.yml
Run deploy.yml first so it renders the tracked rule or scrape-config change
into .generated/monitoring, then reload Prometheus:
docker exec prometheus wget -qO- --post-data= http://localhost:9090/-/reload
If Alertmanager configuration changed, reload it without restarting the container:
docker kill --signal HUP alertmanager
Grafana normally reloads provisioned dashboards within 30 seconds.