Add additional OpenBSD PF graphs (#13963)

* Add additional OpenBSD PF graphs

Some of these were already present for PFSense (matches, badoffset,
fragmented, short, normalized, memdropped) and reuse existing graph
types; the others are are added as new types.

* collect-snmp-data.php: support IPv6 hosts

* Add SNMP data for new OpenBSD OIDs

* Stack all OpenBSD PF drops into a single graph/rrdfile

* Pull additional drops in to pf_drops

The MIB descriptions don't say "drop", but reading the OpenBSD source:

c471a73b65/sys/net/pfvar.h (L1196)

it's clear that badoff, frag, short, and norm are all drop reasons.
Pull them in into the stacked drop graph, too.

* ./scripts/save-test-data.php -o openbsd -v pf

* Include device_graphs in saved os module test data

* Revert "Include device_graphs in saved os module test data"

This reverts commit a85c902fe9.

* Update to use SnmpQuery

Co-authored-by: Kevin Wallace <kevinwallace@users.noreply.github.com>
Co-authored-by: Tony Murray <murraytony@gmail.com>
This commit is contained in:
Kevin Wallace
2022-06-06 21:49:42 -07:00
committed by GitHub
parent 52f70d6bcf
commit 1b1859051f
6 changed files with 156 additions and 49 deletions

View File

@@ -33,58 +33,69 @@ class Openbsd extends Unix implements OSPolling
{
public function pollOS(): void
{
$oids = snmp_get_multi($this->getDeviceArray(), ['pfStateCount.0', 'pfStateSearches.0', 'pfStateInserts.0', 'pfStateRemovals.0'], '-OQUs', 'OPENBSD-PF-MIB');
$oids = \SnmpQuery::get([
'OPENBSD-PF-MIB::pfStateCount.0',
'OPENBSD-PF-MIB::pfStateSearches.0',
'OPENBSD-PF-MIB::pfStateInserts.0',
'OPENBSD-PF-MIB::pfStateRemovals.0',
'OPENBSD-PF-MIB::pfCntMatch.0',
'OPENBSD-PF-MIB::pfCntBadOffset.0',
'OPENBSD-PF-MIB::pfCntFragment.0',
'OPENBSD-PF-MIB::pfCntShort.0',
'OPENBSD-PF-MIB::pfCntNormalize.0',
'OPENBSD-PF-MIB::pfCntMemory.0',
'OPENBSD-PF-MIB::pfCntTimestamp.0',
'OPENBSD-PF-MIB::pfCntCongestion.0',
'OPENBSD-PF-MIB::pfCntIpOption.0',
'OPENBSD-PF-MIB::pfCntProtoCksum.0',
'OPENBSD-PF-MIB::pfCntStateMismatch.0',
'OPENBSD-PF-MIB::pfCntStateInsert.0',
'OPENBSD-PF-MIB::pfCntStateLimit.0',
'OPENBSD-PF-MIB::pfCntSrcLimit.0',
'OPENBSD-PF-MIB::pfCntSynproxy.0',
'OPENBSD-PF-MIB::pfCntTranslate.0',
'OPENBSD-PF-MIB::pfCntNoRoute.0',
])->values();
if (is_numeric($oids[0]['pfStateCount'] ?? null)) {
$rrd_def = RrdDefinition::make()->addDataset('states', 'GAUGE', 0);
$this->graphOID('states', ['states' => $oids['OPENBSD-PF-MIB::pfStateCount.0']], 'GAUGE');
$this->graphOID('searches', ['searches' => $oids['OPENBSD-PF-MIB::pfStateSearches.0']]);
$this->graphOID('inserts', ['inserts' => $oids['OPENBSD-PF-MIB::pfStateInserts.0']]);
$this->graphOID('removals', ['removals' => $oids['OPENBSD-PF-MIB::pfStateRemovals.0']]);
$this->graphOID('matches', ['matches' => $oids['OPENBSD-PF-MIB::pfCntMatch.0']]);
$fields = [
'states' => $oids[0]['pfStateCount'],
];
$this->graphOID('drops', [
'badoffset' => $oids['OPENBSD-PF-MIB::pfCntBadOffset.0'],
'fragmented' => $oids['OPENBSD-PF-MIB::pfCntFragment.0'],
'short' => $oids['OPENBSD-PF-MIB::pfCntShort.0'],
'normalized' => $oids['OPENBSD-PF-MIB::pfCntNormalize.0'],
'memory' => $oids['OPENBSD-PF-MIB::pfCntMemory.0'],
'timestamp' => $oids['OPENBSD-PF-MIB::pfCntTimestamp.0'],
'congestion' => $oids['OPENBSD-PF-MIB::pfCntCongestion.0'],
'ipoption' => $oids['OPENBSD-PF-MIB::pfCntIpOption.0'],
'protocksum' => $oids['OPENBSD-PF-MIB::pfCntProtoCksum.0'],
'statemismatch' => $oids['OPENBSD-PF-MIB::pfCntStateMismatch.0'],
'stateinsert' => $oids['OPENBSD-PF-MIB::pfCntStateInsert.0'],
'statelimit' => $oids['OPENBSD-PF-MIB::pfCntStateLimit.0'],
'srclimit' => $oids['OPENBSD-PF-MIB::pfCntSrcLimit.0'],
'synproxy' => $oids['OPENBSD-PF-MIB::pfCntSynproxy.0'],
'translate' => $oids['OPENBSD-PF-MIB::pfCntTranslate.0'],
'noroute' => $oids['OPENBSD-PF-MIB::pfCntNoRoute.0'],
]);
}
private function graphOID(string $graphName, array $oids, string $type = 'COUNTER'): void
{
$rrd_def = RrdDefinition::make();
$fields = [];
foreach ($oids as $field => $oid) {
if (is_numeric($oid ?? null)) {
$rrd_def->addDataset($field, $type, 0);
$fields[$field] = $oid;
}
}
$tags = compact('rrd_def');
data_update($this->getDeviceArray(), 'pf_states', $tags, $fields);
data_update($this->getDeviceArray(), "pf_$graphName", $tags, $fields);
$this->enableGraph('pf_states');
}
if (is_numeric($oids[0]['pfStateSearches'] ?? null)) {
$rrd_def = RrdDefinition::make()->addDataset('searches', 'COUNTER', 0);
$fields = [
'searches' => $oids[0]['pfStateSearches'],
];
$tags = compact('rrd_def');
data_update($this->getDeviceArray(), 'pf_searches', $tags, $fields);
$this->enableGraph('pf_searches');
}
if (is_numeric($oids[0]['pfStateInserts'] ?? null)) {
$rrd_def = RrdDefinition::make()->addDataset('inserts', 'COUNTER', 0);
$fields = [
'inserts' => $oids[0]['pfStateInserts'],
];
$tags = compact('rrd_def');
data_update($this->getDeviceArray(), 'pf_inserts', $tags, $fields);
$this->enableGraph('pf_inserts');
}
if (is_numeric($oids[0]['pfStateCount'] ?? null)) {
$rrd_def = RrdDefinition::make()->addDataset('removals', 'COUNTER', 0);
$fields = [
'removals' => $oids[0]['pfStateCount'],
];
$tags = compact('rrd_def');
data_update($this->getDeviceArray(), 'pf_removals', $tags, $fields);
$this->enableGraph('pf_removals');
}
$this->enableGraph("pf_$graphName");
}
}

View File

@@ -213,7 +213,7 @@ class ModuleTestHelper
$collection_output = preg_replace('/\033\[[\d;]+m/', '', $collection_output);
// extract snmp queries
$snmp_query_regex = '/SNMP\[.*snmp(?:bulk)?([a-z]+)\' .+(udp|tcp|tcp6|udp6):[^:]+:[0-9]+\' \'(.+)\']/';
$snmp_query_regex = '/SNMP\[.*snmp(?:bulk)?([a-z]+)\' .+(udp|tcp|tcp6|udp6):(?:\[[0-9a-f:]+\]|[^:]+):[0-9]+\' \'(.+)\']/';
preg_match_all($snmp_query_regex, $collection_output, $snmp_matches);
// extract mibs and group with oids

View File

@@ -0,0 +1,39 @@
<?php
$rrd_filename = Rrd::name($device['hostname'], 'pf_drops');
$i = 0;
foreach ([
'badoffset' => 'BadOffset',
'fragmented' => 'Fragmented',
'short' => 'Short',
'normalized' => 'Normalized',
'memory' => 'Memory',
'timestamp' => 'Timestamp',
'congestion' => 'Congestion',
'ipoption' => 'IpOption',
'protocksum' => 'ProtoCksum',
'statemismatch' => 'StateMismatch',
'stateinsert' => 'StateInsert',
'statelimit' => 'StateLimit',
'srclimit' => 'SrcLimit',
'synproxy' => 'Synproxy',
'translate' => 'Translate',
'noroute' => 'NoRoute',
] as $ds => $descr) {
$rrd_list[$i]['filename'] = $rrd_filename;
$rrd_list[$i]['descr'] = $descr;
$rrd_list[$i]['ds'] = $ds;
$i++;
}
$unit_text = 'Dropped Packets';
$units = 'Packets';
$total_units = 'Packets';
$colours = 'psychedelic';
$scale_min = '0';
require 'includes/html/graphs/generic_multi_simplex_seperated.inc.php';

View File

@@ -2725,6 +2725,14 @@
},
"type": "graph"
},
"graph_types.device.pf_drops": {
"default": {
"section": "firewall",
"order": 11,
"descr": "Drops"
},
"type": "graph"
},
"graph_types.device.pf_fragmented": {
"default": {
"section": "firewall",

View File

@@ -0,0 +1,23 @@
{
"os": {
"discovery": {
"devices": [
{
"sysName": "<private>",
"sysObjectID": ".1.3.6.1.4.1.30155.23.1",
"sysDescr": "OpenBSD hostname.example.com 7.1 GENERIC.MP#465 amd64",
"sysContact": "<private>",
"version": "7.1",
"hardware": null,
"features": null,
"os": "openbsd",
"type": "server",
"serial": null,
"icon": "openbsd.svg",
"location": "<private>"
}
]
},
"poller": "matches discovery"
}
}

View File

@@ -0,0 +1,26 @@
1.3.6.1.2.1.1.1.0|4|OpenBSD hostname.example.com 7.1 GENERIC.MP#465 amd64
1.3.6.1.2.1.1.2.0|6|1.3.6.1.4.1.30155.23.1
1.3.6.1.2.1.1.4.0|4|<private>
1.3.6.1.2.1.1.5.0|4|<private>
1.3.6.1.2.1.1.6.0|4|<private>
1.3.6.1.4.1.30155.1.2.1.0|70|11209
1.3.6.1.4.1.30155.1.2.2.0|70|0
1.3.6.1.4.1.30155.1.2.3.0|70|0
1.3.6.1.4.1.30155.1.2.4.0|70|0
1.3.6.1.4.1.30155.1.2.5.0|70|1
1.3.6.1.4.1.30155.1.2.6.0|70|0
1.3.6.1.4.1.30155.1.2.7.0|70|0
1.3.6.1.4.1.30155.1.2.8.0|70|0
1.3.6.1.4.1.30155.1.2.9.0|70|2
1.3.6.1.4.1.30155.1.2.10.0|70|3
1.3.6.1.4.1.30155.1.2.11.0|70|165
1.3.6.1.4.1.30155.1.2.12.0|70|0
1.3.6.1.4.1.30155.1.2.13.0|70|0
1.3.6.1.4.1.30155.1.2.14.0|70|0
1.3.6.1.4.1.30155.1.2.15.0|70|0
1.3.6.1.4.1.30155.1.2.16.0|70|0
1.3.6.1.4.1.30155.1.2.17.0|70|0
1.3.6.1.4.1.30155.1.3.1.0|66|100
1.3.6.1.4.1.30155.1.3.2.0|70|117796
1.3.6.1.4.1.30155.1.3.3.0|70|10654
1.3.6.1.4.1.30155.1.3.4.0|70|10552