Skip to content

Add OPNsense by REST API - #808

Open
Garfieldttt wants to merge 4 commits into
zabbix:mainfrom
Garfieldttt:opnsense-rest-api
Open

Add OPNsense by REST API#808
Garfieldttt wants to merge 4 commits into
zabbix:mainfrom
Garfieldttt:opnsense-rest-api

Conversation

@Garfieldttt

Copy link
Copy Markdown
Contributor

OPNsense by REST API

A second OPNsense template next to OPNsense by HTTP-JSON, derived from it and considerably
wider. It carries its own name and its own uuids, so both can be linked to the same host and
importing one does not touch the other.

Everything below was measured against a live OPNsense 26.7 with a restricted monitoring key,
not taken from the documentation.

What it adds over the template it grew out of

  • processor utilisation split into user, system and interrupt, core count and load per core
  • the packet filter in depth: state and source tracking tables with their limits, pf counters,
    table entries against the configured ceiling, and the loaded ruleset with size, fingerprint,
    evaluation rate and unmatched rules
  • kernel network memory and mbuf clusters, netisr queue drops per protocol, IP and TCP
    protocol error rates
  • clock synchronisation with offset, stratum and reachable peers
  • service run state, swap per device and temperature per sensor, each discovered
  • inbound errors and link state per interface, and the blocked share of the firewall log
  • a dashboard of eight pages in place of three

107 items, 14 discovery rules with 70 item prototypes, 52 triggers, 36 macros.

Five defects of the original are fixed here rather than carried over

What Why it failed
diagnostics/firewall/pfStates and diagnostics/system/systemResources The privilege patterns are pf_states and system_resources, exact rather than wildcards, and ACL.php matches them with preg_match without the i modifier. An administrator key never notices, a monitoring key gets HTTP 403 on the firewall state items, the state table utilization and all memory items
IPsec phase 2 searchPhase2Action reads its connection from getPost('id') and the template asked with a plain GET, so phase 2 could only ever return an empty row set. It is an item prototype inside the phase 1 rule now, posting one request per connection
Gateway without a monitor address The API answers with a tilde for round trip time, loss and deviation, which was substituted with the literal 9999. That landed in history and made the gateway graphs unreadable. The reading is discarded instead, and the trigger that reports the disabled monitoring is Info rather than Average, since switching it off is a configuration decision
CARP discovery on a firewall without CARP get_vip_status answers with an empty rows list and a message saying no CARP interfaces are defined, which is the normal answer for a single firewall. The rule turned that into a custom error, so the host showed an unsupported rule while everything was fine. Observed on such a host: of 315 enabled items it was the only one unsupported
Raw masters keeping a day of history Fourteen master items carried history: 1d or 7d with value type TEXT. Nothing reads that: a master exists to feed dependent items, which store their own values. Measured on one small firewall, four interfaces and 143 rules, the raw text came to 0.9 MiB in 64 minutes, about 20 MiB a day per host

Compatibility

The export declares format 7.0 rather than 7.4, so it imports into Zabbix 7.0 and every
later release. Every widget type it uses (gauge, honeycomb, item, svggraph) exists in 7.0.

Privileges

The README lists the ten privileges the monitoring user needs with their internal ids. Eight
are read only. It also says what the other two permit and how to do without them.

Licensing

Derived from OPNsense by HTTP-JSON in this repository, MIT, Copyright (c) 2021 Zabbix. The
notice travels with it, in the template description and in the README.

Maintained at https://github.com/Garfieldttt/opnsense-zabbix-template.

@Garfieldttt
Garfieldttt force-pushed the opnsense-rest-api branch 2 times, most recently from 07555b3 to 48a038b Compare August 23, 2026 04:11
A second OPNsense template next to OPNsense by HTTP-JSON, derived from it
and considerably wider. It carries its own name and its own uuids, so both
can be linked to the same host and importing one does not touch the other.

Measured against a live OPNsense 26.7 rather than taken from documentation,
including the privilege table in the README, which is derived from the
patterns the firewall publishes under auth/priv/search.

127 items, 15 discovery rules with 71 item prototypes, 58 triggers, 41
macros and a dashboard of nine pages. Over the template it grew out of it
adds processor utilisation split into user, system and interrupt, the packet
filter in depth with the state and source tracking tables, pf counters,
table entries and the loaded ruleset, kernel network memory, netisr queues,
protocol error rates, clock synchronisation, service state, swap and
temperature discovery, inbound errors and link state per interface, the
Unbound resolver, certificate validity and DHCP lease counters.

Five defects of the original are fixed rather than carried over:

  * diagnostics/firewall/pfStates and diagnostics/system/systemResources in
    camelCase, where the privilege patterns are exact and ACL.php matches
    them case sensitively, so a monitoring key gets HTTP 403
  * IPsec phase 2 asking with a GET although searchPhase2Action reads its
    connection from getPost('id'), so it could only return an empty set
  * the literal 9999 substituted for round trip time, loss and deviation on
    a gateway without a monitor address, which landed in history and made
    the gateway graphs unreadable
  * the CARP discovery turning unsupported on a firewall without CARP, where
    an empty list is the correct answer
  * fourteen raw master items keeping a day of raw payloads that nothing
    reads, about 20 MiB a day per host

The export declares format 7.0, so it imports into Zabbix 7.0 and every
later release. Every widget type it uses exists in 7.0.
@burghy86

Copy link
Copy Markdown

thank you. i test. in a desktop openvpn i don't see a user connnect but a name of istance
immagine

search_sessions returns one flat list in which a running server that has
clients connected is represented by those clients alone, each carrying the
description and type of its instance. Discovered as it stood, every session
was named after the instance it belonged to, and the instance itself
disappeared for as long as anybody was connected.

A script on the master item now splits the answer into instances and
sessions and rebuilds the instance from its sessions. Discovery follows in
two rules: instances keep their items and their key, sessions are new and
carry the client name, its source address and the traffic of that one
client.

Three more defects the same answer explains:

- a server keeps no traffic counters of its own, so the instance figures
  were always empty. They are now the sum over the connected clients, and
  the rate steps are guarded because that sum drops when a client leaves
- a client instance and a server in point to point mode report the state of
  their own tunnel, connected rather than ok, which made the down trigger
  fire on a healthy instance
- an instance that is enabled but not running is returned with no status at
  all, which was discarded, so a dead instance never reached the trigger.
  It is reported as stopped

Read off ServiceController::searchSessionsAction and ovpn_status.py and
reproduced from their output, because the firewall this template was
measured against runs no OpenVPN.
@Garfieldttt

Copy link
Copy Markdown
Contributor Author

@burghy86
The API returns a busy server as its clients only, each inheriting the
instance description, so sessions were named after the instance. Fixed on this branch, they
now carry the client name.

Thomas Rzen added 2 commits August 24, 2026 21:11
An audit against the live firewall evaluated every item and prototype of
the template: 219 carry a value, none fail, and the six that stay empty are
the ones the README already explains, the gateway metrics without a monitor
address and the CARP discovery on a firewall without CARP.

Two things it did turn up:

- calculated items referenced their own host in two styles, twelve as
  //key and eight as /{HOST.HOST}/key. Both work, the shorter one is what
  the Zabbix templates use, so all twenty read the same way now
- the README claimed the UPS master answers HTTP 403 without the page-nut
  privilege. It does, but on a firewall without the NUT plugin the route
  does not exist at all and the answer is 404. Both cases are named now,
  together with the reason the item ships disabled
The README says every raw item stores nothing, and every one of them did
except the intermediate item of the filesystem discovery, which kept an
hour of text per discovered filesystem without anything reading it. A
dependent item is fed from the value as it arrives, so history 0 costs
nothing and saves eleven text items per firewall here.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants