Add multiple items, dashboards, and discovery rules. - #802
Closed
Garfieldttt wants to merge 7 commits into
Closed
Conversation
zabbix_export:
version: '7.4'
template_groups:
- uuid: 36bff6c29af64692839d077febfc7079
name: 'Templates/Network devices'
- uuid: 846977d1dfed4968bc5f8bdb363285bc
name: 'Templates/Operating systems'
templates:
- uuid: dd3517f0536a49dc89e09fff62ec369b
template: 'OPNsense by HTTP-JSON'
name: 'OPNsense by HTTP-JSON'
vendor:
name: 'community'
version: '0.30'
groups:
- name: 'Templates/Network devices'
- name: 'Templates/Operating systems'
items:
- uuid: 1f53848b6556415bad14ca593e242312
name: 'UPS Battery Charge'
type: DEPENDENT
key: nut.battery.charge
units: '%'
preprocessing:
- type: JSONPATH
parameters:
- '$.[''battery.charge'']'
master_item:
key: opns.ups.raw
triggers:
- uuid: fa0f6277664d4427a8674f572646653a
expression: 'last(/OPNsense by HTTP-JSON/nut.battery.charge)<{$OPNS.NUT.BAT.LOW}'
name: 'Battery charge is below {$OPNS.NUT.BAT.LOW}'
opdata: '{ITEM.LASTVALUE}'
priority: WARNING
- uuid: 9905b20ba7b94ceaa89383fef9d65881
name: 'UPS Battery Load'
type: DEPENDENT
key: nut.battery.load
units: '%'
preprocessing:
- type: JSONPATH
parameters:
- '$.[''ups.load'']'
master_item:
key: opns.ups.raw
triggers:
- uuid: 6d5a3fb4005e499e9431992e931435ba
expression: 'last(/OPNsense by HTTP-JSON/nut.battery.load)>{$OPNS.NUT.HIGH.LOAD}'
name: 'High Load on UPS Battery'
opdata: '{ITEM.LASTVALUE}'
priority: AVERAGE
- uuid: 038a71496e2a48eaa790e5ef621e9a8b
name: 'UPS Battery Runtime'
type: DEPENDENT
key: nut.battery.runtime
units: s
preprocessing:
- type: JSONPATH
parameters:
- '$.[''battery.runtime'']'
master_item:
key: opns.ups.raw
triggers:
- uuid: 010e7496f772485e863eded1daa1b679
expression: 'last(/OPNsense by HTTP-JSON/nut.battery.runtime)<{$OPNS.NUT.BAT.RUNTIME}'
name: 'Remaining battery runtime is low'
opdata: '{ITEM.LASTVALUE}'
priority: HIGH
- uuid: 4dc13074716e448ba307cf03701daaaf
name: 'UPS Input Frequency'
type: DEPENDENT
key: nut.input.frequency
units: Hz
preprocessing:
- type: JSONPATH
parameters:
- '$.[''input.frequency'']'
master_item:
key: opns.ups.raw
- uuid: 4bdbb273b5eb45d190a07373868f2fa1
name: 'UPS Input Voltage'
type: DEPENDENT
key: nut.input.voltage
units: V
preprocessing:
- type: JSONPATH
parameters:
- '$.[''input.voltage'']'
master_item:
key: opns.ups.raw
- uuid: 5cf8a50cf85a4be59946184960bc9baa
name: 'UPS Model'
type: DEPENDENT
key: nut.model
value_type: TEXT
preprocessing:
- type: JSONPATH
parameters:
- '$.[''ups.model'']'
master_item:
key: opns.ups.raw
- uuid: 5e6a558e1c6d42ca9140213cb709d983
name: 'UPS Output Voltage'
type: DEPENDENT
key: nut.output.voltage
units: V
preprocessing:
- type: JSONPATH
parameters:
- '$.[''output.voltage'']'
master_item:
key: opns.ups.raw
- uuid: 47bd34b6852b4bb292fa19a682359004
name: 'UPS Status'
type: DEPENDENT
key: nut.status
value_type: TEXT
description: |
OL = On Line = UPS is powered by mains electricity, supplying power to connected devices.
OB = On Battery = UPS is running on battery power due to mains failure.
LB = Low Battery = Battery charge is critically low. UPS will shut down soon.
RB = Replace Battery = Battery needs replacement (age or health issue).
HB = High Battery = Battery is fully charged (rare, but possible).
CHRG = Charging = Battery is currently being charged.
DISCHRG = Discharging = Battery is discharging (same as OB, but more specific).
OVER = Overload = UPS is overloaded (load exceeds capacity).
ALARM = Alarm Active = UPS has triggered an alarm (e.g., overload, battery fault).
CAL = Calibrating = UPS is performing battery calibration.
COMMLOST = Communication Lost = Communication with UPS is lost.
OFF = Off = UPS is powered off.
ONBATT = On Battery = Same as OB.
TRIM = Trim = Mains voltage is low, UPS is reducing voltage (step-down).
BOOST = Boost = Mains voltage is high, UPS is increasing voltage (step-up).
SYNC = Synchronizing = UPS is synchronizing with mains (rare).
TEST = Test = Running UPS is running a self-test.
preprocessing:
- type: JSONPATH
parameters:
- '$.[''ups.status'']'
master_item:
key: opns.ups.raw
triggers:
- uuid: 1e308c6da595465297a191b4f6abe7fb
expression: 'find(/OPNsense by HTTP-JSON/nut.status,#1,"like","LB")=1'
name: 'Battey low'
priority: DISASTER
- uuid: 7e29741d0a604e7f9f6a58f473285603
expression: 'find(/OPNsense by HTTP-JSON/nut.status,#1,"like","OB")=1'
name: 'UPS on Battery'
priority: HIGH
- uuid: bf7c17f8b2094ec391ae4c4f58f45be3
name: 'CPU load'
type: DEPENDENT
key: opns.cpu.load
history: 1d
value_type: FLOAT
preprocessing:
- type: JSONPATH
parameters:
- $.loadavg
- type: REGEX
parameters:
- ^(\d+\.\d+)
- \1
master_item:
key: opns.raw.load
triggers:
- uuid: 139a626f4d2a486ba7eb21d3eda124bd
expression: 'min(/OPNsense by HTTP-JSON/opns.cpu.load,5m)>{$OPNS.CPU.LOAD.MAX}'
name: 'CPU load is high'
opdata: '{ITEM.LASTVALUE}'
priority: WARNING
- uuid: e525a08df2e24efea29f8b9ceb1cd48a
name: 'Firewall states current'
type: DEPENDENT
key: opns.fw.states.current
history: 1d
preprocessing:
- type: JSONPATH
parameters:
- $.current
master_item:
key: opns.raw.fw.states
tags:
- tag: component
value: firewall
- uuid: 54937ff84f994bfcba2b4cd2e1d9465d
name: 'Firewall states max'
type: DEPENDENT
key: opns.fw.states.max
history: 1d
preprocessing:
- type: JSONPATH
parameters:
- $.limit
master_item:
key: opns.raw.fw.states
tags:
- tag: component
value: firewall
- uuid: f6fab497a5734651a596ef0752999120
name: 'RAW IPsec Phase1'
type: HTTP_AGENT
key: opns.ipsec.phase1.raw
delay: 5m
history: 1d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
preprocessing:
- type: JSONPATH
parameters:
- $.rows
- type: JAVASCRIPT
parameters:
- |
// searchPhase1 leaves phase1desc null when the connection carries no description, and the
// discovery uses that field as the entity identity in every prototype key. name is always
// set, so it stands in. Anyone who does have descriptions keeps the keys they already have.
var rows = JSON.parse(value);
for (var i = 0; i < rows.length; i++) {
var desc = rows[i]['phase1desc'];
if (desc === null || desc === undefined || String(desc).trim() === '') {
rows[i]['phase1desc'] = rows[i]['name'];
}
}
return JSON.stringify(rows);
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/ipsec/sessions/searchPhase1'
tags:
- tag: component
value: raw
- uuid: 7945ce5b7e174b9e8f6ea6da6dd64060
name: 'RAW WireGuard'
type: HTTP_AGENT
key: opns.wireguard.raw
delay: 1m
history: 1d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
preprocessing:
- type: JSONPATH
parameters:
- $.rows
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/wireguard/service/show'
tags:
- tag: component
value: raw
- uuid: f8800baa079b46f485a049ee02d61b57
name: 'ARC Memory'
type: DEPENDENT
key: opns.memory.arc
history: 1d
units: B
preprocessing:
- type: JSONPATH
parameters:
- $.memory.arc
master_item:
key: opns.raw.memory.status
- uuid: 552ff5f7fb0f49f0aa069311a22fe282
name: 'Total Memory'
type: DEPENDENT
key: opns.memory.total
history: 1d
units: B
preprocessing:
- type: JSONPATH
parameters:
- $.memory.total
master_item:
key: opns.raw.memory.status
- uuid: 3b0ee64a3c204c22a6d10662db8569ca
name: 'Used Memory'
type: DEPENDENT
key: opns.memory.used
history: 1d
units: B
preprocessing:
- type: JSONPATH
parameters:
- $.memory.used
master_item:
key: opns.raw.memory.status
- uuid: bc1340c5c93f49f09608f02a06cbbb14
name: 'Memory utilization in %'
type: CALCULATED
key: opns.memory.util
units: '%'
params: 'last(//opns.memory.used)*100/last(//opns.memory.total)'
tags:
- tag: component
value: memory
triggers:
- uuid: 9da4ebacfb764e0b9c5942ceb86cc62d
expression: 'min(/OPNsense by HTTP-JSON/opns.memory.util,5m)>{$OPNS.MEMORY.UTIL.MAX}'
name: 'Memory utilization is high'
opdata: '{ITEM.LASTVALUE}'
priority: AVERAGE
- uuid: 90c1c7dd19ed45038ec9281727d8a32b
name: 'Licensed until'
type: DEPENDENT
key: opns.product.licenseuntil
trends: '0'
preprocessing:
- type: JSONPATH
parameters:
- $.product.product_license.valid_to
error_handler: CUSTOM_VALUE
error_handler_params: '0'
- type: JAVASCRIPT
parameters:
- |
function convertDateToUnixTimestamp(input) {
if (input === '0' || input === '' || input === null) {
return 0;
}
const date = new Date(input);
const unixTimestamp = Math.floor(date.getTime() / 1000);
if (isNaN(unixTimestamp)) {
return 0;
}
return unixTimestamp;
}
return convertDateToUnixTimestamp(value);
master_item:
key: opns.raw.product.info
triggers:
- uuid: 740c029a6e7a49cb8eedc53e759eb6bb
expression: 'last(/OPNsense by HTTP-JSON/opns.product.licenseuntil)>0 and (last(/OPNsense by HTTP-JSON/opns.product.licenseuntil) - now()) / 86400 < {$OPNS.LICENSE.EXPIRY.WARN}'
name: 'OPNSense Business License expires soon'
event_name: 'OPNSense Business License expires soon (less than {$OPNS.LICENSE.EXPIRY.WARN} days)'
priority: AVERAGE
- uuid: 6ebbcee115654039a5735c835bbdaa78
name: 'Firmware update count'
type: DEPENDENT
key: opns.firmware.update.count
history: 30d
preprocessing:
- type: JAVASCRIPT
parameters:
- |
var data = JSON.parse(value);
if (data.status !== 'update' && data.status !== 'upgrade') {
return 0;
}
if (data.all_packages) {
return Object.keys(data.all_packages).length;
}
if (data.all_sets) {
return Object.keys(data.all_sets).length;
}
return 0;
master_item:
key: opns.raw.firmware.status
tags:
- tag: component
value: firmware
- uuid: daba216c1e654377982db23dfad0b0a0
name: 'Firmware update packages'
type: DEPENDENT
key: opns.firmware.update.packages
history: 30d
value_type: TEXT
trends: '0'
preprocessing:
- type: JAVASCRIPT
parameters:
- |
var data = JSON.parse(value);
var packages = data.all_packages || data.all_sets || {};
var result = [];
Object.keys(packages).sort().forEach(function (name) {
var pkg = packages[name];
result.push(pkg.name + ': ' + pkg.old + ' -> ' + pkg.new + ' (' + pkg.reason + ')');
});
return result.join('\n');
master_item:
key: opns.raw.firmware.status
tags:
- tag: component
value: firmware
- uuid: c38e9bd38f2749839673580d91239005
name: 'Firmware update requires reboot'
type: DEPENDENT
key: opns.firmware.update.reboot
history: 30d
preprocessing:
- type: JSONPATH
parameters:
- $.status_reboot
error_handler: CUSTOM_VALUE
error_handler_params: '0'
master_item:
key: opns.raw.firmware.status
tags:
- tag: component
value: firmware
- uuid: ec1dbbdb46a1445f9c5595ab24a76083
name: 'Firmware update status'
type: DEPENDENT
key: opns.firmware.update.status
history: 30d
value_type: TEXT
trends: '0'
preprocessing:
- type: JSONPATH
parameters:
- $.status
master_item:
key: opns.raw.firmware.status
tags:
- tag: component
value: firmware
triggers:
- uuid: 6003bfd5a8f44a6d9a04f08de932fef1
expression: 'find(/OPNsense by HTTP-JSON/opns.firmware.update.status,#1,"regexp","^(update|upgrade)$")=1 and last(/OPNsense by HTTP-JSON/opns.firmware.update.count)>0'
name: 'OPNsense firmware updates are available'
event_name: 'OPNsense firmware updates are available ({ITEM.LASTVALUE})'
opdata: 'Updates: {ITEM.LASTVALUE2}'
priority: INFO
description: 'A firmware update or major upgrade is available.'
- uuid: a5755520c5e2491cb9b44cd9d1f438af
expression: 'find(/OPNsense by HTTP-JSON/opns.firmware.update.status,#1,"eq","error")=1'
name: 'OPNsense firmware update check failed'
opdata: '{ITEM.LASTVALUE}'
priority: WARNING
description: 'The OPNsense firmware update check returned an error.'
- uuid: 68ad33be2ee3422c8b711a243a860ca5
name: 'Firmware update status message'
type: DEPENDENT
key: opns.firmware.update.status_msg
history: 30d
value_type: TEXT
trends: '0'
preprocessing:
- type: JSONPATH
parameters:
- $.status_msg
master_item:
key: opns.raw.firmware.status
tags:
- tag: component
value: firmware
- uuid: 164f961df24a445aa57872068e5a1f99
name: 'RAW Disk'
type: HTTP_AGENT
key: opns.raw.disk
delay: 5m
history: 1d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
preprocessing:
- type: JAVASCRIPT
parameters:
- |
var raw = value;
var data;
try {
data = JSON.parse(raw);
} catch(e) {
throw 'JSON parse error: ' + e + ' | raw value: ' + raw;
}
if (!data || typeof data.devices === 'undefined') {
throw 'No devices key found. Data: ' + JSON.stringify(data);
}
function toBytes(str) {
if (!str || str === '-') return 0;
var units = {
'K': 1024,
'M': 1024 * 1024,
'G': 1024 * 1024 * 1024,
'T': 1024 * 1024 * 1024 * 1024
};
var s = String(str).trim();
var lastChar = s.charAt(s.length - 1).toUpperCase();
if (units[lastChar]) {
var num = parseFloat(s.slice(0, -1));
return Math.round(num * units[lastChar]);
}
return Math.round(parseFloat(s));
}
for (var i = 0; i < data.devices.length; i++) {
var d = data.devices[i];
d.blocks = toBytes(d.blocks);
d.used = toBytes(d.used);
d.available = toBytes(d.available);
}
return JSON.stringify(data);
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/diagnostics/system/system_disk'
tags:
- tag: component
value: raw
- uuid: b8a1ea18da234409af64be5edef3115a
name: 'RAW Firewallaction'
type: HTTP_AGENT
key: opns.raw.fw.action
history: 1d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/diagnostics/firewall/stats?group_by=action'
tags:
- tag: component
value: raw
- uuid: 4f89efb7b9014c209f585e153f557f7e
name: 'RAW Firewall Interfaces'
type: HTTP_AGENT
key: opns.raw.fw.interface.stat
history: 1d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/diagnostics/firewall/pf_statistics/interfaces'
tags:
- tag: component
value: raw
- uuid: d15b7b8cdec9486a97450b16166eaf81
name: 'RAW Firewall States'
type: HTTP_AGENT
key: opns.raw.fw.states
history: 1d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/diagnostics/firewall/pf_states'
tags:
- tag: component
value: raw
- uuid: 984a9170893d488f8c3140b9d3a5c7c2
name: 'RAW Gatewaystatus'
type: HTTP_AGENT
key: opns.raw.gateway.status
history: 1d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
preprocessing:
- type: JSONPATH
parameters:
- $.items
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/routes/gateway/status'
tags:
- tag: component
value: raw
triggers:
- uuid: 20ff02c55d314364964f900d1f4ca0f3
expression: 'nodata(/OPNsense by HTTP-JSON/opns.raw.gateway.status,5m)=1'
name: 'No data from OPNsense'
priority: HIGH
description: 'can''t access the OPNsense API'
- uuid: 533374a5ae2e48168a900807da13b335
name: 'RAW Carp Interfaces'
type: HTTP_AGENT
key: opns.raw.interfaces.carp
history: 1d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/diagnostics/interface/get_vip_status'
tags:
- tag: component
value: raw
- uuid: 69e94d002b4149e2b9fe418a1186c7d5
name: 'RAW Interfaces'
type: HTTP_AGENT
key: opns.raw.interfaces.stat
history: 1d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
preprocessing:
- type: JSONPATH
parameters:
- $.interfaces
- type: JSONPATH
parameters:
- '$.*'
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/diagnostics/traffic/_interface'
tags:
- tag: component
value: raw
- uuid: eaa9d3bfec0d45b79d79452f33c04b2d
name: 'RAW Load'
type: HTTP_AGENT
key: opns.raw.load
delay: 5m
history: 1d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/diagnostics/system/system_time'
tags:
- tag: component
value: raw
- uuid: 9a4ce32c699b4fbcb0263d964186c8aa
name: 'RAW Memorystatus'
type: HTTP_AGENT
key: opns.raw.memory.status
delay: 5m
history: 1d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/diagnostics/system/system_resources'
tags:
- tag: component
value: raw
- uuid: feadfb993c31464aba5fa96a31033cb8
name: 'RAW Product Info'
type: HTTP_AGENT
key: opns.raw.product.info
delay: 30m
history: 1d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/core/firmware/info'
tags:
- tag: component
value: raw
- uuid: d50283b96ba64d769fbd744e9a71f327
name: 'RAW Firmware Status'
type: HTTP_AGENT
key: opns.raw.firmware.status
delay: 1d
history: 7d
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
request_method: POST
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/core/firmware/status'
tags:
- tag: component
value: raw
- uuid: 2bc82e7f22a3476396ce1731aee50d8f
name: 'States table utilization in %'
type: CALCULATED
key: opns.states.util
history: 30d
value_type: FLOAT
units: '%'
params: 'last(//opns.fw.states.current)*100/last(//opns.fw.states.max)'
tags:
- tag: component
value: firewall
triggers:
- uuid: 7421fd082b4a4fb0b5e57d20475b310f
expression: 'min(/OPNsense by HTTP-JSON/opns.states.util,#3)>{$OPNS.STATE.TABLE.UTIL.MAX}'
name: 'State table usage is high'
event_name: 'State table usage more than {$OPNS.STATE.TABLE.UTIL.MAX}.'
opdata: 'Current utilization: {ITEM.LASTVALUE}'
priority: WARNING
description: 'Please check the number of connections.'
- uuid: f58b046d6e554f129272472d79f00389
name: 'System Uptime'
type: DEPENDENT
key: opns.system.uptime
history: 1d
value_type: FLOAT
units: uptime
preprocessing:
- type: JSONPATH
parameters:
- $.uptime
- type: JAVASCRIPT
parameters:
- |
var str = value.trim();
var days = 0;
var hours = 0;
var minutes = 0;
var seconds = 0;
// Extract days if present
var dayMatch = str.match(/(\d+)\s*days?/);
if (dayMatch) {
days = parseInt(dayMatch[1]);
}
// Extract HH:MM:SS
var timeMatch = str.match(/(\d{1,2}):(\d{2}):(\d{2})/);
if (timeMatch) {
hours = parseInt(timeMatch[1]);
minutes = parseInt(timeMatch[2]);
seconds = parseInt(timeMatch[3]);
}
return (days * 86400) + (hours * 3600) + (minutes * 60) + seconds;
master_item:
key: opns.raw.load
triggers:
- uuid: 2bf11a893917405195b8aef0620f4a30
expression: 'last(/OPNsense by HTTP-JSON/opns.system.uptime)<600'
name: '{HOST.NAME} has been restarted'
priority: INFO
- uuid: 4dee0747d2ef4530999ae8535d8aba49
name: 'RAW UPS'
type: HTTP_AGENT
key: opns.ups.raw
delay: 5m
history: 1d
value_type: TEXT
status: DISABLED
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
preprocessing:
- type: JAVASCRIPT
parameters:
- |
var data = JSON.parse(value);
var raw = data.response || "";
var result = {};
var lines = raw.split("\n");
for (var i = 0; i < lines.length; i++) {
var line = lines[i].trim();
var idx = line.indexOf(": ");
if (idx > -1) {
var key = line.substring(0, idx).trim();
var val = line.substring(idx + 2).trim();
result[key] = val;
}
}
return JSON.stringify(result);
url: 'https://{HOST.IP}:{$OPNS.PORT}/api/nut/diagnostics/upsstatus'
tags:
- tag: component
value: raw
# --- added from OPNsense by HTTP API (github.com/Garfieldttt/opnsense-zabbix-api) ---
- uuid: ca1cc6c4ceb04a459cfbabea9930a531
name: 'OPNsense: System activity (raw)'
type: HTTP_AGENT
key: opns.activity.raw
delay: 1m
history: '0'
value_type: TEXT
trends: '0'
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
description: Header block of the process listing, which is the only place the API states how busy the processor actually is. The bulk of the response is the process table itself and is not evaluated, so nothing is stored from it.
timeout: 15s
url: https://{HOST.IP}:{$OPNS.PORT}/api/diagnostics/activity/get_activity
tags:
- tag: component
value: raw
preprocessing:
- type: REGEX
parameters:
- (CPU:[^"]+)
- \1
- uuid: c2dfbbc5575e47d19daabd6e2c7d9dc1
name: 'OPNsense: Alias tables (raw)'
type: HTTP_AGENT
key: opns.alias.raw
delay: 10m
history: '0'
value_type: TEXT
trends: '0'
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
description: Entries held by all pf tables together with the configured ceiling. Polled every ten minutes because block lists and GeoIP feeds move on that scale, not by the second.
timeout: 10s
url: https://{HOST.IP}:{$OPNS.PORT}/api/firewall/alias/get_table_size
tags:
- tag: component
value: raw
- uuid: fcf7225b97e0426d8acc5d80b142a439
name: 'CARP: Demotion factor'
type: DEPENDENT
key: opns.carp.demotion
delay: '0'
description: How strongly this node is holding itself back from becoming master. Zero means it is willing; anything above means a subsystem has demoted it, which is the usual reason a node refuses to take over when the peer fails.
preprocessing:
- type: JSONPATH
parameters:
- $.carp.demotion
error_handler: DISCARD_VALUE
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 3m
master_item:
key: opns.raw.interfaces.carp
tags:
- tag: component
value: carp
- uuid: f9b63e90b8a7473cb3d30ef7e4ad8c12
name: 'CARP: Maintenance mode'
type: DEPENDENT
key: opns.carp.maintenance
delay: '0'
valuemap:
name: Enabled state
description: Maintenance mode hands every virtual address to the peer and keeps it there. Worth watching because it is easy to switch on for a planned change and just as easy to forget afterwards, leaving the pair permanently one sided.
preprocessing:
- type: JSONPATH
parameters:
- $.carp.maintenancemode
error_handler: DISCARD_VALUE
- type: BOOL_TO_DECIMAL
parameters:
- ''
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 3m
master_item:
key: opns.raw.interfaces.carp
tags:
- tag: component
value: carp
triggers:
- uuid: 8509721dbf00419ea296a06b7e1f98f6
expression: min(/OPNsense by HTTP-JSON/opns.carp.maintenance,30m)=1
name: 'OPNsense: CARP maintenance mode has been on for 30 minutes'
priority: WARNING
description: Long enough to suggest it was left on rather than switched on for a change in progress. While it is on there is no redundancy.
manual_close: 'YES'
tags:
- tag: scope
value: availability
- uuid: be29426c9d954f1da7d758ab4b7f741c
name: 'OPNsense: Configuration last changed'
type: DEPENDENT
key: opns.config.changed
delay: '0'
units: unixtime
description: Timestamp OPNsense records when the configuration is written. Covers every change, not only firewall rules, and needs no extra request because it rides along with the system time that is already polled. The reading is what the firewall itself reports, so a clock that is off shifts it accordingly.
preprocessing:
- type: JAVASCRIPT
parameters:
- |
// "Thu Aug 13 12:03:17 UTC 2026". Date.parse is unreliable with this
// format, so it is taken apart by position.
var m = JSON.parse(value).config.match(
/^\w{3}\s+(\w{3})\s+(\d{1,2})\s+(\d{1,2}):(\d{2}):(\d{2})\s+\S+\s+(\d{4})$/);
if (m === null) { throw 'cannot read config timestamp: ' + value; }
var months = {Jan:0,Feb:1,Mar:2,Apr:3,May:4,Jun:5,Jul:6,Aug:7,Sep:8,Oct:9,Nov:10,Dec:11};
return Math.round(Date.UTC(+m[6], months[m[1]], +m[2], +m[3], +m[4], +m[5]) / 1000);
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 6h
master_item:
key: opns.raw.load
tags:
- tag: component
value: system
triggers:
- uuid: fed19fbe4cd0446b9defc959b7256d10
expression: change(/OPNsense by HTTP-JSON/opns.config.changed)<>0 and last(/OPNsense by HTTP-JSON/opns.config.changed,#2)>0
name: 'OPNsense: Configuration has been changed'
priority: INFO
description: Someone wrote a new configuration. Broader than the ruleset fingerprint, which reacts to rules only, and the two together tell whether a change touched the firewall rules or something else. The second condition suppresses the jump out of a zero, which is what an item reports after a gap in collection rather than a real change.
manual_close: 'YES'
tags:
- tag: scope
value: notice
- uuid: 006b445c232e4455b8ed653c13cb104f
name: 'CPU: Cores'
type: DEPENDENT
key: opns.cpu.cores
delay: '0'
description: Physical core count, needed to put the load average into proportion. Parsed by position rather than by wording, because the source string is translated on a localised firewall.
preprocessing:
- type: JSONPATH
parameters:
- $[0]
- type: REGEX
parameters:
- \(([0-9]+)[^)]*\)\s*$
- \1
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1d
master_item:
key: opns.cpu.raw
tags:
- tag: component
value: cpu
- uuid: 6a1b99c362f3490d85328c902b73cdc4
name: 'CPU: Idle time'
type: DEPENDENT
key: opns.cpu.idle
delay: '0'
description: Share of processor time spent idle. The one figure top(1) states directly, which is why utilization is derived from it rather than the other way round.
master_item:
key: opns.activity.raw
tags:
- tag: component
value: cpu
value_type: FLOAT
units: '%'
preprocessing:
- type: REGEX
parameters:
- ([0-9.]+)%\s*idle
- \1
- uuid: 46b364421d04418db8878cdbea616ed2
name: 'CPU: Interrupt time'
type: DEPENDENT
key: opns.cpu.interrupt
delay: '0'
value_type: FLOAT
units: '%'
description: Share spent servicing hardware interrupts. On a firewall this is largely network cards, and a high figure means the packet rate is close to what the hardware can take, well before the total utilisation looks alarming.
preprocessing:
- type: REGEX
parameters:
- ([0-9.]+)%\s*interrupt
- \1
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.activity.raw
tags:
- tag: component
value: cpu
- uuid: 7d989e887e55448ea9dedc52ada14e4d
name: 'OPNsense: CPU type (raw)'
type: HTTP_AGENT
key: opns.cpu.raw
delay: 1m
history: '0'
value_type: TEXT
trends: '0'
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
description: Processor model with core and thread count. Static inventory, but polled at the same interval as the load average it is divided into, because a calculated item goes unsupported while a referenced item has no data yet. The dependent item discards unchanged values, so this costs a request rather than history. This is also the only endpoint addressed in camelCase, because the action name carries consecutive capitals that the snake_case spelling does not reproduce; its privilege matches by wildcard, so the spelling raises no access problem.
timeout: 10s
url: https://{HOST.IP}:{$OPNS.PORT}/api/diagnostics/cpu_usage/get_c_p_u_type
tags:
- tag: component
value: raw
- uuid: 3f4ca8d7a51f40078851cd2ffba320a5
name: 'CPU: System time'
type: DEPENDENT
key: opns.cpu.system
delay: '0'
value_type: FLOAT
units: '%'
description: Share spent in the kernel, which on a firewall is mostly packet forwarding and rule evaluation.
preprocessing:
- type: REGEX
parameters:
- ([0-9.]+)%\s*system
- \1
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.activity.raw
tags:
- tag: component
value: cpu
- uuid: cf0c3bd1b1f548e09213d87a27dde773
name: 'CPU: User time'
type: DEPENDENT
key: opns.cpu.user
delay: '0'
value_type: FLOAT
units: '%'
description: Share spent in user space, which covers the web interface, the configuration daemon and plugins such as an IDS.
preprocessing:
- type: REGEX
parameters:
- ([0-9.]+)%\s*user
- \1
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.activity.raw
tags:
- tag: component
value: cpu
- uuid: 8043ef39cc2b4391b1aeb307c8fbfc8c
name: 'CPU: Utilization'
type: CALCULATED
key: opns.cpu.util
delay: 1m
value_type: FLOAT
units: '%'
description: Everything that is not idle. Derived from the idle share the firewall reports, because that is the one figure the API states directly and the rest have to be added up otherwise.
tags:
- tag: component
value: cpu
triggers:
- uuid: e8d0b77076fe4903869e67e299b2e7ec
expression: avg(/OPNsense by HTTP-JSON/opns.cpu.util,10m)>{$OPNS.CPU.UTIL.WARN}
name: 'OPNsense: CPU utilization is high'
priority: WARNING
description: 'Sustained load on the processor. Read alongside the interrupt share: if that dominates, the limit is packet handling rather than anything running on the box.'
manual_close: 'YES'
tags:
- tag: scope
value: performance
params: 100-last(//opns.cpu.idle)
- uuid: e077b57bcd454ed0a624523f88d8fbd5
name: 'Firewall log: Blocked entries'
type: DEPENDENT
key: opns.fwlog.block
delay: '0'
description: Blocked entries in the window the endpoint returns. Meaningful only against the window size, which is what the blocked share divides by.
master_item:
key: opns.raw.fw.action
tags:
- tag: component
value: firewall
preprocessing:
- type: JSONPATH
parameters:
- $[?(@.label == "block")].value.first()
- uuid: cc2d8b5a080045c2a5e8d63c6b63e0e3
name: 'Firewall log: Blocked share'
type: CALCULATED
key: opns.fwlog.block.pct
delay: 1m
value_type: FLOAT
units: '%'
description: 'Share of blocked entries among the most recent logged packets. Deliberately a share and not a count: the endpoint returns a fixed window of the last log entries, so the counts always add up to that window size and say nothing on their own. The span of time covered therefore varies with how much the firewall logs, and only rules with logging enabled appear at all. What a normal share looks like differs per site, so this ships without a trigger.'
tags:
- tag: component
value: firewall
params: last(//opns.fwlog.block) / last(//opns.fwlog.total) * 100
- uuid: ffa7c087de8f4d3b9b69519003b6c95f
name: 'Firewall log: Window size'
type: DEPENDENT
key: opns.fwlog.total
delay: '0'
description: Number of entries the endpoint reports on. A fixed window of the most recent logged packets, so this normally sits at a constant value, and only rules with logging enabled are counted at all.
master_item:
key: opns.raw.fw.action
tags:
- tag: component
value: firewall
preprocessing:
- type: JSONPATH
parameters:
- $[*].value.sum()
- uuid: 12982d3c12294f8a8ca6bd0d07b370a1
name: 'mbuf: Clusters in use'
type: DEPENDENT
key: opns.mbuf.cluster.current
description: mbuf clusters currently taken from the fixed kernel pool. Grows with the number of packets in flight, not with configured memory.
delay: '0'
preprocessing:
- type: JSONPATH
parameters:
- $['mbuf-statistics']['cluster-current']
error_handler: DISCARD_VALUE
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.mbuf.raw
tags:
- tag: component
value: memory
- uuid: a45aef2894fe4e8fb23fcdda213ed314
name: 'mbuf: Cluster limit'
type: DEPENDENT
key: opns.mbuf.cluster.max
description: Upper bound of the cluster pool, set by kern.ipc.nmbclusters. Raising that sysctl is the remedy when the pool runs dry.
delay: '0'
preprocessing:
- type: JSONPATH
parameters:
- $['mbuf-statistics']['cluster-max']
error_handler: DISCARD_VALUE
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.mbuf.raw
tags:
- tag: component
value: memory
- uuid: eceba8258d2a432eb961c6180eee59d1
name: 'mbuf: Cluster utilization'
type: CALCULATED
key: opns.mbuf.cluster.pused
delay: 1m
value_type: FLOAT
units: '%'
params: last(/{HOST.HOST}/opns.mbuf.cluster.current) / last(/{HOST.HOST}/opns.mbuf.cluster.max) * 100
description: mbuf clusters are a fixed kernel pool. Once it is exhausted the firewall stops forwarding traffic while still answering ping and reporting free system memory, which makes this failure hard to recognise from the outside.
tags:
- tag: component
value: memory
triggers:
- uuid: 1bff1afca74c4a28a5f7dbcf39c824c7
expression: min(/OPNsense by HTTP-JSON/opns.mbuf.cluster.pused,5m)>{$OPNS.MBUF.UTIL.WARN}
dependencies:
- name: 'OPNsense: Kernel denied network memory requests'
expression: change(/OPNsense by HTTP-JSON/opns.mbuf.denied)>0
name: 'OPNsense: mbuf cluster pool is filling up'
priority: AVERAGE
description: Approaching the cluster limit. Raise kern.ipc.nmbclusters before it is reached, because exhaustion costs traffic, not just performance.
manual_close: 'YES'
tags:
- tag: scope
value: capacity
- uuid: e1ec47b6adcd4a94a975339584df83a2
name: 'mbuf: Denied requests'
type: DEPENDENT
key: opns.mbuf.denied
delay: '0'
description: Sum of the mbuf, cluster and packet allocation failures reported by the kernel. A cumulative counter since boot that should stay at zero for the entire uptime, so the trigger fires on any increase rather than on a threshold.
preprocessing:
- type: JSONPATH
parameters:
- $['mbuf-statistics']['mbuf-failures','cluster-failures','packet-failures','jumbop-failures','jumbo9-failures','jumbo16-failures','sfbufs-alloc-failed'].sum()
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.mbuf.raw
tags:
- tag: component
value: memory
triggers:
- uuid: ef9f92401e7442ec906779ed8a311d36
expression: change(/OPNsense by HTTP-JSON/opns.mbuf.denied)>0
name: 'OPNsense: Kernel denied network memory requests'
priority: HIGH
description: The kernel ran out of mbufs or clusters and dropped traffic. Raise kern.ipc.nmbclusters. The counter never decreases, so this fires once per new occurrence.
manual_close: 'YES'
tags:
- tag: scope
value: capacity
- uuid: eed27adcc6d14ac886f846d31525fbbc
name: 'OPNsense: mbuf statistics (raw)'
type: HTTP_AGENT
key: opns.mbuf.raw
delay: 1m
history: '0'
value_type: TEXT
trends: '0'
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
description: Kernel network memory pool, the libxo output of netstat -m.
timeout: 10s
url: https://{HOST.IP}:{$OPNS.PORT}/api/diagnostics/interface/get_memory_statistics
tags:
- tag: component
value: raw
- uuid: b73b209143d64fe1a51bc35e354bd41f
name: 'netisr: Queue drops'
type: DEPENDENT
key: opns.netisr.queue.drops
delay: '0'
description: Packets discarded because a netisr queue was full, summed over all protocols and worker streams. This is the symptom of a firewall that cannot keep up with its offered load, and it is invisible in interface counters.
preprocessing:
- type: JSONPATH
parameters:
- $.netisr.workstream[*].work[*]['queue-drops'].sum()
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.netisr.raw
tags:
- tag: component
value: network
triggers:
- uuid: 2230eaed50934fca8032cf7c4334929f
expression: change(/OPNsense by HTTP-JSON/opns.netisr.queue.drops)>0
name: 'OPNsense: netisr queue is dropping packets'
priority: AVERAGE
description: The kernel discarded packets before they reached the firewall rules. Check load, interface queue lengths and net.isr tuning. The counter never decreases, so this fires once per new occurrence.
manual_close: 'YES'
tags:
- tag: scope
value: capacity
- uuid: 81e13419ac25457aae76832f18973b21
name: 'OPNsense: netisr statistics (raw)'
type: HTTP_AGENT
key: opns.netisr.raw
delay: 1m
history: '0'
value_type: TEXT
trends: '0'
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
description: Network dispatch queues, the libxo output of netstat -Q.
timeout: 10s
url: https://{HOST.IP}:{$OPNS.PORT}/api/diagnostics/interface/get_netisr_statistics
tags:
- tag: component
value: raw
- uuid: f74d5a2f3e854b038f5ff20aa13956a2
name: 'NTP: Offset of the selected peer'
type: DEPENDENT
key: opns.ntp.offset
delay: '0'
value_type: FLOAT
units: ms
description: How far the local clock sits from the peer it is currently steering by. A drifting firewall clock breaks IPsec, certificate validation and the correlation of its own logs, and it does so without any other symptom.
preprocessing:
- type: JSONPATH
parameters:
- $.rows[?(@.status == "*" || @.status == "o")].offset.first()
- type: LTRIM
parameters:
- +
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.ntp.raw
tags:
- tag: component
value: system
triggers:
- uuid: 88a39044e34e42b79469d1271f033633
expression: abs(last(/OPNsense by HTTP-JSON/opns.ntp.offset))>{$OPNS.NTP.OFFSET.WARN}
name: 'OPNsense: Clock offset is high'
priority: WARNING
description: The local clock has drifted away from its time source. Check reachability of the configured servers.
manual_close: 'YES'
tags:
- tag: scope
value: notice
- uuid: 1d2232e131f94e308f3f27e2dc57e107
name: 'NTP: Reachable peers'
type: DEPENDENT
key: opns.ntp.peers.reachable
delay: '0'
description: Configured time sources that have answered recently. Pool placeholders are excluded, they are not servers but slots the daemon still has to fill.
preprocessing:
- type: JSONPATH
parameters:
- $.rows[?(@.reach != "0")].length()
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.ntp.raw
tags:
- tag: component
value: system
- uuid: 78094f0d9d1d4e2daaad72d7068ebc1d
name: 'OPNsense: NTP peers (raw)'
type: HTTP_AGENT
key: opns.ntp.raw
delay: 5m
history: '0'
value_type: TEXT
trends: '0'
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
description: Peer list of the time daemon with selection state, stratum, reach, offset and jitter.
timeout: 10s
url: https://{HOST.IP}:{$OPNS.PORT}/api/ntpd/service/status
tags:
- tag: component
value: raw
- uuid: a8c6cbd180b14b88909e02a27d6db1e3
name: 'NTP: Stratum of the selected peer'
type: DEPENDENT
key: opns.ntp.stratum
delay: '0'
description: Distance of the chosen source from a reference clock. A stratum of 16 means the daemon is not synchronised at all.
preprocessing:
- type: JSONPATH
parameters:
- $.rows[?(@.status == "*" || @.status == "o")].stratum.first()
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.ntp.raw
tags:
- tag: component
value: system
- uuid: 8e5588431dd347dbaf22b097235857d5
name: 'NTP: Synchronised'
type: DEPENDENT
key: opns.ntp.synced
delay: '0'
valuemap:
name: NTP sync state
description: 'Whether the daemon has settled on a time source. Unsynchronised is the state that matters: the clock then follows nothing and drifts freely.'
preprocessing:
- type: JSONPATH
parameters:
- $.rows[?(@.status == "*" || @.status == "o")].status.first()
- type: STR_REPLACE
parameters:
- '*'
- '1'
- type: STR_REPLACE
parameters:
- o
- '1'
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 15m
master_item:
key: opns.ntp.raw
tags:
- tag: component
value: system
triggers:
- uuid: f3c6e34d75c94b6e9d22b716bdb5224d
expression: min(/OPNsense by HTTP-JSON/opns.ntp.synced,30m)=0
name: 'OPNsense: Clock is not synchronised'
priority: WARNING
description: No time source has been selected for half an hour. Right after a boot this is normal for a few minutes, beyond that the configured servers are unreachable or refusing.
manual_close: 'YES'
tags:
- tag: scope
value: notice
- uuid: f1912c86490242bead36dcc962738cc7
name: 'OpenVPN: sessions (raw)'
type: HTTP_AGENT
key: opns.openvpn.raw
delay: 1m
history: '0'
trends: '0'
value_type: TEXT
authtype: BASIC
username: '{$OPNS.KEY}'
password: '{$OPNS.SECRET}'
timeout: 15s
url: https://{HOST.IP}:{$OPNS.PORT}/api/openvpn/service/search_sessions
description: Every OpenVPN instance and every client connected to a server, in one request. Instances that are enabled but not running are included with an empty status, so a server that died is still discovered rather than disappearing.
preprocessing:
- type: JSONPATH
parameters:
- $.rows
tags:
- tag: component
value: raw
- uuid: 0218fd02165d499abf5b6e99899ac1f5
name: 'pf: Bad offset packets per second'
type: DEPENDENT
key: opns.pf.counter.badoffset.rate
description: Packets whose header offset field was invalid. Normally zero for the whole uptime.
delay: '0'
value_type: FLOAT
units: '!p/s'
preprocessing:
- type: JSONPATH
parameters:
- $.info.counters['bad-offset'].rate
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.pfinfo.raw
tags:
- tag: component
value: firewall
triggers:
- uuid: 6cd8c6c52d4d40dfb77440f49bd8d012
expression: last(/OPNsense by HTTP-JSON/opns.pf.counter.badoffset.rate)>0
name: 'OPNsense: pf is seeing malformed packets'
priority: WARNING
description: Packets with a bad offset are normally zero. A sustained rate points at a broken sender or an attack.
manual_close: 'YES'
tags:
- tag: scope
value: security
- uuid: 7a31f50e52f14e4699b7721de4bf6cde
name: 'pf: Fragmented packets per second'
type: DEPENDENT
key: opns.pf.counter.fragment.rate
description: Fragmented packets seen by pf. Some fragmentation is normal, a rising rate usually means an MTU mismatch somewhere on the path.
delay: '0'
value_type: FLOAT
units: '!p/s'
preprocessing:
- type: JSONPATH
parameters:
- $.info.counters.fragment.rate
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.pfinfo.raw
tags:
- tag: component
value: firewall
- uuid: 98c05249f1b946fba0946f29970e16b1
name: 'pf: Rule matches per second'
type: DEPENDENT
key: opns.pf.counter.match.rate
description: Packets that matched a filter rule. The general throughput measure of the ruleset.
delay: '0'
value_type: FLOAT
units: '!p/s'
preprocessing:
- type: JSONPATH
parameters:
- $.info.counters.match.rate
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.pfinfo.raw
tags:
- tag: component
value: firewall
- uuid: 0aea85a0efa849a6b3aadf3a3e271c77
name: 'pf: Packets dropped for memory per second'
type: DEPENDENT
key: opns.pf.counter.memdrop.rate
description: Packets dropped because pf could not allocate memory for a state or a fragment. Traffic is lost when this is non zero.
delay: '0'
value_type: FLOAT
units: '!p/s'
preprocessing:
- type: JSONPATH
parameters:
- $.info.counters.memory.rate
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.pfinfo.raw
tags:
- tag: component
value: firewall
triggers:
- uuid: 1a515d1149fc456d9924e56117521b9e
expression: last(/OPNsense by HTTP-JSON/opns.pf.counter.memdrop.rate)>0
name: 'OPNsense: pf is dropping packets due to memory'
priority: HIGH
description: pf ran out of memory for states or fragments. Traffic is being lost. Check the state and table limits.
manual_close: 'YES'
tags:
- tag: scope
value: capacity
- uuid: 6dac0fe927e746ebb3ea8416930e2403
name: 'pf: Normalized packets per second'
type: DEPENDENT
key: opns.pf.counter.normalize.rate
description: Packets rewritten by scrub rules, most often reassembled fragments.
delay: '0'
value_type: FLOAT
units: '!p/s'
preprocessing:
- type: JSONPATH
parameters:
- $.info.counters.normalize.rate
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.pfinfo.raw
tags:
- tag: component
value: firewall
- uuid: caeb2c07455a4019be35e91c81d1c9c2
name: 'pf: Short packets per second'
type: DEPENDENT
key: opns.pf.counter.short.rate
description: Packets shorter than their own header claimed. Normally zero, and malformed by definition.
delay: '0'
value_type: FLOAT
units: '!p/s'
preprocessing:
- type: JSONPATH
parameters:
- $.info.counters.short.rate
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.pfinfo.raw
tags:
- tag: component
value: firewall
- uuid: 54f2082907fd45ac9bbefc55d3332e1e
name: 'pf: Source limit hits per second'
type: DEPENDENT
key: opns.pf.counter.srclimit.rate
description: Connections refused because one source exceeded the number of states its rule allows it.
delay: '0'
value_type: FLOAT
units: '!p/s'
preprocessing:
- type: JSONPATH
parameters:
- $.info.counters['src-limit'].rate
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.pfinfo.raw
tags:
- tag: component
value: firewall
triggers:
- uuid: 6f99ebf6ed89485aabcc850cb4d92047
expression: last(/OPNsense by HTTP-JSON/opns.pf.counter.srclimit.rate)>0
name: 'OPNsense: pf source limit is being hit'
priority: WARNING
description: A single source exceeded its allowed number of states.
manual_close: 'YES'
tags:
- tag: scope
value: security
- uuid: 875adf308ec14afeb8fa9cf6b65b442f
name: 'pf: State limit hits per second'
type: DEPENDENT
key: opns.pf.counter.statelimit.rate
description: Connections refused because the state table is at its limit. Every one of these is a connection that did not happen.
delay: '0'
value_type: FLOAT
units: '!p/s'
preprocessing:
- type: JSONPATH
parameters:
- $.info.counters['state-limit'].rate
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.pfinfo.raw
tags:
- tag: component
value: firewall
triggers:
- uuid: 05bc928b25364783802c1ec3e6e565f6
expression: last(/OPNsense by HTTP-JSON/opns.pf.counter.statelimit.rate)>0
name: 'OPNsense: pf state limit is being hit'
priority: HIGH
description: New connections are refused because the state limit is reached. Raise the limit or find the source.
manual_close: 'YES'
tags:
- tag: scope
value: capacity
- uuid: 7f915ddd699e49eeb910d9b0baefa1a1
name: 'pf: State mismatches per second'
type: DEPENDENT
key: opns.pf.counter.statemismatch.rate
description: Packets that did not fit the state they were matched against. Isolated ones are normal on an asymmetric path, a sustained rate is not.
delay: '0'
value_type: FLOAT
units: '!p/s'
preprocessing:
- type: JSONPATH
parameters:
- $.info.counters['state-mismatch'].rate
- type: DISCARD_UNCHANGED_HEARTBEAT
parameters:
- 1h
master_item:
key: opns.pfinfo.raw
tags:
- tag: component
value: firewall
- uuid: c8b50233181d4c1e8035be31cb3ba920
name: 'pf: Overload table insertions per second'
type: DEPENDENT
key: opns.pf.overload.rate
description: Entries added to the overload table, where pf collects sources that tripped a connection rate limit. Rises during brute force attempts against an exposed service.
delay: '0'
value_type: FLOAT
units: '!/…
Updated README.md to include community template details and corrections for OPNsense integration.
Garfieldttt
marked this pull request as ready for review
August 20, 2026 04:32
|
descending version number. It should be 0.32. |
The FortiSwitch README had been overwritten with the OPNsense template export by mistake; it is back to the upstream content. The vendor version went backwards from 0.31 to 0.30 and is now 0.32.
Contributor
Author
|
Sorry, my mistake it should be fine now. |
Read from an OPNsense 26.7 whose gateways have no monitor address, with a
restricted monitoring key:
{"name":"WANGW","address":"10.0.10.1","status":"none",
"loss":"~","delay":"~","stddev":"~","monitor":"~",
"status_translated":"Online"}
That is the normal shape for a gateway the firewall never probes, and it is
a configuration, not a fault. Round trip time, loss and deviation turned
each tilde into the literal 9999 through a custom value on a
NOT_MATCHES_REGEX step, so the value landed in history: the Gateways page
plotted 9999 ms and 9999 percent for as long as monitoring stayed off, and
every minimum, average and maximum over that period was worthless. The host
showed a gateway reading Online next to a round trip time of 9999 ms. The
three packet loss triggers were guarded against exactly that number and
stayed silent, which was the only reason it caused no alert storm.
The three items now take the leading number with a REGEX step and discard
the reading when there is none, so they stay empty instead of carrying a
number nobody measured. The capture also drops the unit, which makes the
RTRIM step that followed unnecessary.
The disabled trigger no longer compares three sentinels. It reads nodata()
over the same three items and drops from Average to Info, because switching
gateway monitoring off is a deliberate setting and a permanent Average
problem for it teaches people to ignore the host. Its description now also
says the part that was missing: while monitoring is off, an outage of that
gateway raises nothing at all, since the down trigger works on packet loss.
It gains a dependency on "No data from OPNsense" so an unreachable API
raises one alarm instead of one per gateway.
Contributor
Author
|
Closing in favour of #807, which brings the same work as a template of its own rather than as a change to The three defect fixes from this PR are contained there:
Thanks for the time anyone spent looking at this one. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add multiple items, dashboards, and discovery rules.