add Suricata monitoring (#13942)

* add poller

* add a generic alert graph

* add support for .total

* add the initial work on the suricata app page

* add applayer flow sources

* more rrd work and add more fields

* add a missing graph to the suricata page

* add suricata to the apps page

* all working now for suricata

* add some suricata alert examples

* all done with the php

* update the application docs for Suricata

* add another note about Suricata stats in the docs

* add the test file

* add the test JSON

* remove a unneeded newline from the appication docs

* correct the type uptime type

* packets graph should by packets/sec

* minor formatting cleanup

* one more minor formatting cleanup

* shot in the dark to see if something fixes the angry linter

* fix snmpsim file

* add metrics

* add values to the metrics

* add a missing comma to the json

* add a missing line to snmprec and cleanup json a bit

* a few more minor changes to see if this makes it happy... regened via scripts/json-app-tool.php

* see if this will make it happy

* add suricata to app discovery and hope that fixes it... take a shot in the dark as to why the linter errors strangely on two of the files

* fix json

* add a missing ] to the json

* rename two graphs so it does not trigger one alert and add a missing metric

* whoops, *_alertString is not a metric
This commit is contained in:
Zane C. Bowers-Hadley 2022-04-25 20:30:49 -05:00 committed by GitHub
parent f8d76b0571
commit cdf457fbc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 2402 additions and 0 deletions

View File

@ -2152,6 +2152,37 @@ extend supervisord /etc/snmp/supervisord.py
systemctl restart snmpd
```
## Suricata
### SNMP Extend
1. Install the extend.
```
cpanm Suricata::Monitoring
```
2. Setup cron. Below is a example.
```
*/5 * * * * /usr/local/bin/suricata_stat_check > /dev/null
```
3. Configure snmpd.conf
```
extend suricata-stats /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin suricata_stat_check -c
```
4. Restart snmpd on your system.
You will want to make sure Suricata is set to output the stats
to the eve file once a minute. This will help make sure that
it won't be to far back in the file and will make sure it is
recent when the cronjob runs.
Any configuration of suricata_stat_check should be done in the cron
setup. If the default does not work, check the docs for it at
[MetaCPAN for
suricata_stat_check](https://metacpan.org/dist/Suricata-Monitoring/view/bin/suricata_stat_check)
## TinyDNS aka djbdns
### Agent

View File

@ -46,6 +46,7 @@ if ($results) {
$applications['osupdate'] = 'os-updates';
$applications['phpfpmsp'] = 'php-fpm';
$applications['postfixdetailed'] = 'postfix';
$applications['suricata-stats'] = 'suricata';
}
d_echo(PHP_EOL . 'Available: ' . implode(', ', array_keys($applications)) . PHP_EOL);

View File

@ -1324,6 +1324,33 @@ function get_sensor_label_color($sensor, $type = 'sensors')
return "<span class='label $label_style'>" . trim(Number::formatSi($sensor['sensor_current'], 2, 3, $unit)) . '</span>';
}
/**
* Returns a list of the various suricata instances for
* the specified device id.
*
* @param $device_id
* @return array
*/
function get_suricata_instances($device_id)
{
$options = [
'filter' => [
'type' => ['=', 'suricata'],
],
];
$component = new LibreNMS\Component();
$ourc = $component->getComponents($device_id, $options);
if (isset($ourc[$device_id])) {
$id = $component->getFirstComponentID($ourc, $device_id);
return json_decode($ourc[$device_id][$id]['instances']);
}
return [];
}
/**
* @params int unix time
* @params int seconds

View File

@ -0,0 +1,29 @@
<?php
$name = 'suricata';
$app_id = $app['app_id'];
$unit_text = 'status';
$colours = 'psychedelic';
$dostack = 0;
$printtotal = 0;
$addarea = 0;
$transparency = 15;
if (isset($vars['instance'])) {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id'], $vars['instance']]);
} else {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id']]);
}
$rrd_list = [];
if (Rrd::checkRrdExists($rrd_filename)) {
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Alert Status',
'ds' => 'alert',
];
} else {
d_echo('RRD "' . $rrd_filename . '" not found');
}
require 'includes/html/graphs/generic_multi_line.inc.php';

View File

@ -0,0 +1,154 @@
<?php
$name = 'suricata';
$app_id = $app['app_id'];
$unit_text = 'flows/sec';
$colours = 'psychedelic';
$dostack = 0;
$printtotal = 0;
$addarea = 0;
$transparency = 15;
if (isset($vars['instance'])) {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id'], $vars['instance']]);
} else {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id']]);
}
$rrd_list = [];
if (Rrd::checkRrdExists($rrd_filename)) {
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'DCERPC TCP',
'ds' => 'af_dcerpc_tcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'DCERPC UDP',
'ds' => 'af_dcerpc_udp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'DHCP',
'ds' => 'af_dhcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'DNS TCP',
'ds' => 'af_dns_tcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'DNS UDP',
'ds' => 'af_dns_udp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Failed TCP',
'ds' => 'af_failed_tcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Failed UDP',
'ds' => 'af_failed_udp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'FTP',
'ds' => 'af_ftp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'FTP-DATA',
'ds' => 'af_ftp_data',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'HTTP',
'ds' => 'af_http',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'IKEv2',
'ds' => 'af_ikev2',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'IMAP',
'ds' => 'af_imap',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Krb5 TCP',
'ds' => 'af_krb5_tcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Krb5 UDP',
'ds' => 'af_krb5_udp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'MQTT',
'ds' => 'af_mqtt',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'NFS TCP',
'ds' => 'af_nfs_tcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'NFS UDP',
'ds' => 'af_nfs_udp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'RDP',
'ds' => 'af_rdp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'RFB',
'ds' => 'af_rfb',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'SIP',
'ds' => 'af_sip',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'SMB',
'ds' => 'af_smb',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'SMTP',
'ds' => 'af_smtp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'SNMP',
'ds' => 'af_snmp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'ssh',
'ds' => 'af_ssh',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'TFTP',
'ds' => 'af_tftp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'TLS',
'ds' => 'af_tls',
];
} else {
d_echo('RRD "' . $rrd_filename . '" not found');
}
require 'includes/html/graphs/generic_multi_line.inc.php';

View File

@ -0,0 +1,144 @@
<?php
$name = 'suricata';
$app_id = $app['app_id'];
$unit_text = 'tx/sec';
$colours = 'psychedelic';
$dostack = 0;
$printtotal = 0;
$addarea = 0;
$transparency = 15;
if (isset($vars['instance'])) {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id'], $vars['instance']]);
} else {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id']]);
}
$rrd_list = [];
if (Rrd::checkRrdExists($rrd_filename)) {
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'DCERPC TCP',
'ds' => 'at_dcerpc_tcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'DCERPC UDP',
'ds' => 'at_dcerpc_udp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'DHCP',
'ds' => 'at_dhcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'DNS TCP',
'ds' => 'at_dns_tcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'DNS UDP',
'ds' => 'at_dns_udp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'FTP',
'ds' => 'at_ftp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'FTP-DATA',
'ds' => 'at_ftp_data',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'HTTP',
'ds' => 'at_http',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'IKEv2',
'ds' => 'at_ikev2',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'IMAP',
'ds' => 'at_imap',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Krb5 TCP',
'ds' => 'at_krb5_tcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Krb5 UDP',
'ds' => 'at_krb5_udp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'MQTT',
'ds' => 'at_mqtt',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'NFS TCP',
'ds' => 'at_nfs_tcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'NFS UDP',
'ds' => 'at_nfs_udp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'RDP',
'ds' => 'at_rdp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'RFB',
'ds' => 'at_rfb',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'SIP',
'ds' => 'at_sip',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'SMB',
'ds' => 'at_smb',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'SMTP',
'ds' => 'at_smtp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'SNMP',
'ds' => 'at_snmp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'ssh',
'ds' => 'at_ssh',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'TFTP',
'ds' => 'at_tftp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'TLS',
'ds' => 'at_tls',
];
} else {
d_echo('RRD "' . $rrd_filename . '" not found');
}
require 'includes/html/graphs/generic_multi_line.inc.php';

View File

@ -0,0 +1,29 @@
<?php
$name = 'suricata';
$app_id = $app['app_id'];
$unit_text = 'bytes/sec';
$colours = 'psychedelic';
$dostack = 0;
$printtotal = 0;
$addarea = 0;
$transparency = 15;
if (isset($vars['instance'])) {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id'], $vars['instance']]);
} else {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id']]);
}
$rrd_list = [];
if (Rrd::checkRrdExists($rrd_filename)) {
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Bytes',
'ds' => 'bytes',
];
} else {
d_echo('RRD "' . $rrd_filename . '" not found');
}
require 'includes/html/graphs/generic_multi_line.inc.php';

View File

@ -0,0 +1,114 @@
<?php
$name = 'suricata';
$app_id = $app['app_id'];
$unit_text = 'packets/sec';
$colours = 'psychedelic';
$dostack = 0;
$printtotal = 0;
$addarea = 0;
$transparency = 15;
if (isset($vars['instance'])) {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id'], $vars['instance']]);
} else {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id']]);
}
$rrd_list = [];
if (Rrd::checkRrdExists($rrd_filename)) {
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'IPv4',
'ds' => 'dec_ipv4',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'IPv6',
'ds' => 'dec_ipv6',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'TCP',
'ds' => 'dec_tcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'UDP',
'ds' => 'dec_udp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'SCTP',
'ds' => 'dec_sctp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'CHDLC',
'ds' => 'dec_chdlc',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'GENEVE',
'ds' => 'dec_geneve',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'IEEE 802.1ah',
'ds' => 'dec_ieee8021ah',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'IPv4 in IPv6',
'ds' => 'dec_ipv4_in_ipv6',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'MPLS',
'ds' => 'dec_mpls',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'PPP',
'ds' => 'dec_ppp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'PPPoE',
'ds' => 'dec_pppoe',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'SLL',
'ds' => 'dec_sll',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Teredo',
'ds' => 'dec_teredo',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'VLAN',
'ds' => 'dec_vlan',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'VLAN Q-in-Q',
'ds' => 'dec_vlan_qinq',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'VNTAG',
'ds' => 'dec_vntag',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'VXLAN',
'ds' => 'dec_vxlan',
];
} else {
d_echo('RRD "' . $rrd_filename . '" not found');
}
require 'includes/html/graphs/generic_multi_line.inc.php';

View File

@ -0,0 +1,44 @@
<?php
$name = 'suricata';
$app_id = $app['app_id'];
$unit_text = 'flows';
$colours = 'psychedelic';
$dostack = 0;
$printtotal = 0;
$addarea = 0;
$transparency = 15;
if (isset($vars['instance'])) {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id'], $vars['instance']]);
} else {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id']]);
}
$rrd_list = [];
if (Rrd::checkRrdExists($rrd_filename)) {
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'ICMPv4',
'ds' => 'f_icmpv4',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'ICMPv6',
'ds' => 'f_icmpv6',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'TCP',
'ds' => 'f_tcp',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'UDP',
'ds' => 'f_udp',
];
} else {
d_echo('RRD "' . $rrd_filename . '" not found');
}
require 'includes/html/graphs/generic_multi_line.inc.php';

View File

@ -0,0 +1,49 @@
<?php
$name = 'suricata';
$app_id = $app['app_id'];
$unit_text = 'bytes';
$colours = 'psychedelic';
$dostack = 0;
$printtotal = 0;
$addarea = 0;
$transparency = 15;
if (isset($vars['instance'])) {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id'], $vars['instance']]);
} else {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id']]);
}
$rrd_list = [];
if (Rrd::checkRrdExists($rrd_filename)) {
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Flow',
'ds' => 'f_memuse',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'FTP',
'ds' => 'ftp_memuse',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'HTTP',
'ds' => 'http_memuse',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'TCP',
'ds' => 'tcp_memuse',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'TCP Reass',
'ds' => 'tcp_reass_memuse',
];
} else {
d_echo('RRD "' . $rrd_filename . '" not found');
}
require 'includes/html/graphs/generic_multi_line.inc.php';

View File

@ -0,0 +1,49 @@
<?php
$name = 'suricata';
$app_id = $app['app_id'];
$unit_text = 'packets/sec';
$colours = 'psychedelic';
$dostack = 0;
$printtotal = 0;
$addarea = 0;
$transparency = 15;
if (isset($vars['instance'])) {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id'], $vars['instance']]);
} else {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id']]);
}
$rrd_list = [];
if (Rrd::checkRrdExists($rrd_filename)) {
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Dropped',
'ds' => 'dropped',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'IfDropped',
'ds' => 'ifdropped',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Errors',
'ds' => 'errors',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Dec_Invalid',
'ds' => 'dec_invalid',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Too_Many_Layers',
'ds' => 'dec_too_many_layer',
];
} else {
d_echo('RRD "' . $rrd_filename . '" not found');
}
require 'includes/html/graphs/generic_multi_line.inc.php';

View File

@ -0,0 +1,39 @@
<?php
$name = 'suricata';
$app_id = $app['app_id'];
$unit_text = 'Percent_Of_Packets';
$colours = 'psychedelic';
$dostack = 0;
$printtotal = 0;
$addarea = 0;
$transparency = 15;
if (isset($vars['instance'])) {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id'], $vars['instance']]);
} else {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id']]);
}
$rrd_list = [];
if (Rrd::checkRrdExists($rrd_filename)) {
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Dropped',
'ds' => 'drop_percent',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'If_Dropped',
'ds' => 'ifdrop_percent',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Error',
'ds' => 'error_percent',
];
} else {
d_echo('RRD "' . $rrd_filename . '" not found');
}
require 'includes/html/graphs/generic_multi_line.inc.php';

View File

@ -0,0 +1,44 @@
<?php
$name = 'suricata';
$app_id = $app['app_id'];
$unit_text = 'packets/sec';
$colours = 'psychedelic';
$dostack = 0;
$printtotal = 1;
$addarea = 0;
$transparency = 15;
if (isset($vars['instance'])) {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id'], $vars['instance']]);
} else {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id']]);
}
$rrd_list = [];
if (Rrd::checkRrdExists($rrd_filename)) {
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Packets',
'ds' => 'packets',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Dec. Packets',
'ds' => 'dec_packets',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Dropped',
'ds' => 'dropped',
];
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'If Dropped',
'ds' => 'ifdropped',
];
} else {
d_echo('RRD "' . $rrd_filename . '" not found');
}
require 'includes/html/graphs/generic_multi_line.inc.php';

View File

@ -0,0 +1,29 @@
<?php
$name = 'suricata';
$app_id = $app['app_id'];
$unit_text = 'seconds';
$colours = 'psychedelic';
$dostack = 0;
$printtotal = 0;
$addarea = 0;
$transparency = 15;
if (isset($vars['instance'])) {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id'], $vars['instance']]);
} else {
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app['app_id']]);
}
$rrd_list = [];
if (Rrd::checkRrdExists($rrd_filename)) {
$rrd_list[] = [
'filename' => $rrd_filename,
'descr' => 'Uptime',
'ds' => 'uptime',
];
} else {
d_echo('RRD "' . $rrd_filename . '" not found');
}
require 'includes/html/graphs/generic_multi_line.inc.php';

View File

@ -309,6 +309,18 @@ $graphs['freeradius'] = [
'proxy_acct',
'queue',
];
$graphs['suricata'] = [
'alert',
'packets',
'nasty_delta',
'nasty_percent',
'dec_proto',
'flow_proto',
'app_flows',
'app_tx',
'bytes',
'mem_use',
];
$graphs['zfs'] = [
'arc_misc',
'arc_size',

View File

@ -0,0 +1,73 @@
<?php
$suricata_instances = get_suricata_instances($device['device_id']);
$link_array = [
'page' => 'device',
'device' => $device['device_id'],
'tab' => 'apps',
'app' => 'suricata',
];
print_optionbar_start();
echo generate_link('Totals', $link_array);
echo '| Instances:';
$int_int = 0;
while (isset($suricata_instances[$int_int])) {
$instance = $suricata_instances[$int_int];
$label = $instance;
if ($vars['instance'] == $instance) {
$label = '<span class="pagemenu-selected">' . $instance . '</span>';
}
$int_int++;
$append = '';
if (isset($pools[$int_int])) {
$append = ', ';
}
echo generate_link($label, $link_array, ['pool'=>$pool]) . $append;
}
print_optionbar_end();
$graphs = [
'suricata_packets'=>'Packets',
'suricata_bytes'=>'Bytes',
'suricata_nasty_delta'=>'Drops or Errors Delta',
'suricata_nasty_percent'=>'Drops or Errors Percent',
'suricata_dec_proto'=>'Decoder Protocols',
'suricata_flow_proto'=>'Flow Protocols',
'suricata_app_flows'=>'App Layer Flows',
'suricata_app_tx'=>'App Layer TX',
'suricata_mem_use'=>'Memory Usage',
'suricata_uptime'=>'Uptime',
'suricata_alert'=>'Alert Status',
];
foreach ($graphs as $key => $text) {
$graph_type = $key;
$graph_array['height'] = '100';
$graph_array['width'] = '215';
$graph_array['to'] = \LibreNMS\Config::get('time.now');
$graph_array['id'] = $app['app_id'];
$graph_array['type'] = 'application_' . $key;
if (isset($vars['instance'])) {
$graph_array['instance'] = $vars['instance'];
}
echo '<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">' . $text . '</h3>
</div>
<div class="panel-body">
<div class="row">';
include 'includes/html/print-graphrow.inc.php';
echo '</div>';
echo '</div>';
echo '</div>';
}

View File

@ -0,0 +1,219 @@
<?php
use LibreNMS\Exceptions\JsonAppException;
use LibreNMS\RRD\RrdDefinition;
$name = 'suricata';
$app_id = $app['app_id'];
try {
$suricata = json_app_get($device, 'suricata-stats');
} catch (JsonAppException $e) {
echo PHP_EOL . $name . ':' . $e->getCode() . ':' . $e->getMessage() . PHP_EOL;
update_application($app, $e->getCode() . ':' . $e->getMessage(), []); // Set empty metrics and error message
return;
}
// grab the alert here as it is the global one
$metrics = ['alert'=>$suricata['alert']];
$rrd_def = RrdDefinition::make()
->addDataset('af_dcerpc_tcp', 'DERIVE', 0)
->addDataset('af_dcerpc_udp', 'DERIVE', 0)
->addDataset('af_dhcp', 'DERIVE', 0)
->addDataset('af_dns_tcp', 'DERIVE', 0)
->addDataset('af_dns_udp', 'DERIVE', 0)
->addDataset('af_failed_tcp', 'DERIVE', 0)
->addDataset('af_failed_udp', 'DERIVE', 0)
->addDataset('af_ftp', 'DERIVE', 0)
->addDataset('af_ftp_data', 'DERIVE', 0)
->addDataset('af_http', 'DERIVE', 0)
->addDataset('af_ikev2', 'DERIVE', 0)
->addDataset('af_imap', 'DERIVE', 0)
->addDataset('af_krb5_tcp', 'DERIVE', 0)
->addDataset('af_krb5_udp', 'DERIVE', 0)
->addDataset('af_mqtt', 'DERIVE', 0)
->addDataset('af_nfs_tcp', 'DERIVE', 0)
->addDataset('af_nfs_udp', 'DERIVE', 0)
->addDataset('af_ntp', 'DERIVE', 0)
->addDataset('af_rdp', 'DERIVE', 0)
->addDataset('af_rfb', 'DERIVE', 0)
->addDataset('af_sip', 'DERIVE', 0)
->addDataset('af_smb', 'DERIVE', 0)
->addDataset('af_smtp', 'DERIVE', 0)
->addDataset('af_snmp', 'DERIVE', 0)
->addDataset('af_ssh', 'DERIVE', 0)
->addDataset('af_tftp', 'DERIVE', 0)
->addDataset('af_tls', 'DERIVE', 0)
->addDataset('alert', 'GAUGE', 0)
->addDataset('at_dcerpc_tcp', 'DERIVE', 0)
->addDataset('at_dcerpc_udp', 'DERIVE', 0)
->addDataset('at_dhcp', 'DERIVE', 0)
->addDataset('at_dns_tcp', 'DERIVE', 0)
->addDataset('at_dns_udp', 'DERIVE', 0)
->addDataset('at_ftp', 'DERIVE', 0)
->addDataset('at_ftp_data', 'DERIVE', 0)
->addDataset('at_http', 'DERIVE', 0)
->addDataset('at_ikev2', 'DERIVE', 0)
->addDataset('at_imap', 'DERIVE', 0)
->addDataset('at_krb5_tcp', 'DERIVE', 0)
->addDataset('at_krb5_udp', 'DERIVE', 0)
->addDataset('at_mqtt', 'DERIVE', 0)
->addDataset('at_nfs_tcp', 'DERIVE', 0)
->addDataset('at_nfs_udp', 'DERIVE', 0)
->addDataset('at_ntp', 'DERIVE', 0)
->addDataset('at_rdp', 'DERIVE', 0)
->addDataset('at_rfb', 'DERIVE', 0)
->addDataset('at_sip', 'DERIVE', 0)
->addDataset('at_smb', 'DERIVE', 0)
->addDataset('at_smtp', 'DERIVE', 0)
->addDataset('at_snmp', 'DERIVE', 0)
->addDataset('at_ssh', 'DERIVE', 0)
->addDataset('at_tftp', 'DERIVE', 0)
->addDataset('at_tls', 'DERIVE', 0)
->addDataset('bytes', 'DERIVE', 0)
->addDataset('dec_avg_pkt_size', 'DERIVE', 0)
->addDataset('dec_chdlc', 'DERIVE', 0)
->addDataset('dec_ethernet', 'DERIVE', 0)
->addDataset('dec_geneve', 'DERIVE', 0)
->addDataset('dec_ieee8021ah', 'DERIVE', 0)
->addDataset('dec_invalid', 'DERIVE', 0)
->addDataset('dec_ipv4', 'DERIVE', 0)
->addDataset('dec_ipv4_in_ipv6', 'DERIVE', 0)
->addDataset('dec_ipv6', 'DERIVE', 0)
->addDataset('dec_max_pkt_size', 'DERIVE', 0)
->addDataset('dec_mpls', 'DERIVE', 0)
->addDataset('dec_mx_mac_addrs_d', 'DERIVE', 0)
->addDataset('dec_mx_mac_addrs_s', 'DERIVE', 0)
->addDataset('dec_packets', 'DERIVE', 0)
->addDataset('dec_ppp', 'DERIVE', 0)
->addDataset('dec_pppoe', 'DERIVE', 0)
->addDataset('dec_raw', 'DERIVE', 0)
->addDataset('dec_sctp', 'DERIVE', 0)
->addDataset('dec_sll', 'DERIVE', 0)
->addDataset('dec_tcp', 'DERIVE', 0)
->addDataset('dec_teredo', 'DERIVE', 0)
->addDataset('dec_too_many_layer', 'DERIVE', 0)
->addDataset('dec_udp', 'DERIVE', 0)
->addDataset('dec_vlan', 'DERIVE', 0)
->addDataset('dec_vlan_qinq', 'DERIVE', 0)
->addDataset('dec_vntag', 'DERIVE', 0)
->addDataset('dec_vxlan', 'DERIVE', 0)
->addDataset('drop_percent', 'GAUGE', 0)
->addDataset('dropped', 'DERIVE', 0)
->addDataset('error_percent', 'GAUGE', 0)
->addDataset('errors', 'DERIVE', 0)
->addDataset('f_icmpv4', 'DERIVE', 0)
->addDataset('f_icmpv6', 'DERIVE', 0)
->addDataset('f_memuse', 'GAUGE', 0)
->addDataset('f_tcp', 'DERIVE', 0)
->addDataset('f_udp', 'DERIVE', 0)
->addDataset('ftp_memuse', 'GAUGE', 0)
->addDataset('http_memuse', 'GAUGE', 0)
->addDataset('ifdrop_percent', 'GAUGE', 0)
->addDataset('ifdropped', 'DERIVE', 0)
->addDataset('packets', 'DERIVE', 0)
->addDataset('tcp_memuse', 'GAUGE', 0)
->addDataset('tcp_reass_memuse', 'GAUGE', 0)
->addDataset('uptime', 'GAUGE', 0);
// keys that need to by migrated from the instance to the
$instance_keys = [
'af_dcerpc_tcp', 'af_dcerpc_udp', 'af_dhcp', 'af_dns_tcp', 'af_dns_udp', 'af_failed_tcp', 'af_failed_udp', 'af_ftp',
'af_ftp_data', 'af_http', 'af_ikev2', 'af_imap', 'af_krb5_tcp', 'af_krb5_udp', 'af_mqtt', 'af_nfs_tcp', 'af_nfs_udp',
'af_ntp', 'af_rdp', 'af_rfb', 'af_sip', 'af_smb', 'af_smtp', 'af_snmp', 'af_ssh', 'af_tftp', 'af_tls', 'alert',
'at_dcerpc_tcp', 'at_dcerpc_udp', 'at_dhcp', 'at_dns_tcp', 'at_dns_udp', 'at_ftp', 'at_ftp_data', 'at_http', 'at_ikev2',
'at_imap', 'at_krb5_tcp', 'at_krb5_udp', 'at_mqtt', 'at_nfs_tcp', 'at_nfs_udp', 'at_ntp', 'at_rdp', 'at_rfb', 'at_sip',
'at_smb', 'at_smtp', 'at_snmp', 'at_ssh', 'at_tftp', 'at_tls', 'bytes', 'dec_avg_pkt_size', 'dec_chdlc', 'dec_ethernet',
'dec_geneve', 'dec_ieee8021ah', 'dec_invalid', 'dec_ipv4', 'dec_ipv4_in_ipv6', 'dec_ipv6', 'dec_max_pkt_size', 'dec_mpls',
'dec_mx_mac_addrs_d', 'dec_mx_mac_addrs_s', 'dec_packets', 'dec_ppp', 'dec_pppoe', 'dec_raw', 'dec_sctp', 'dec_sll',
'dec_tcp', 'dec_teredo', 'dec_too_many_layer', 'dec_udp', 'dec_vlan', 'dec_vlan_qinq', 'dec_vntag', 'dec_vxlan',
'drop_delta', 'drop_percent', 'dropped', 'error_delta', 'error_percent', 'errors', 'f_icmpv4', 'f_icmpv6', 'f_memuse',
'f_tcp', 'f_udp', 'ftp_memuse', 'http_memuse', 'ifdrop_delta', 'ifdrop_percent', 'ifdropped', 'packet_delta', 'packets',
'tcp_memuse', 'tcp_reass_memuse', 'uptime',
];
// keys to add to the RRD field
$field_keys = [
'af_dcerpc_tcp', 'af_dcerpc_udp', 'af_dhcp', 'af_dns_tcp', 'af_dns_udp', 'af_failed_tcp', 'af_failed_udp', 'af_ftp',
'af_ftp_data', 'af_http', 'af_ikev2', 'af_imap', 'af_krb5_tcp', 'af_krb5_udp', 'af_mqtt', 'af_nfs_tcp', 'af_nfs_udp',
'af_ntp', 'af_rdp', 'af_rfb', 'af_sip', 'af_smb', 'af_smtp', 'af_snmp', 'af_ssh', 'af_tftp', 'af_tls', 'alert',
'at_dcerpc_tcp', 'at_dcerpc_udp', 'at_dhcp', 'at_dns_tcp', 'at_dns_udp', 'at_ftp', 'at_ftp_data', 'at_http', 'at_ikev2',
'at_imap', 'at_krb5_tcp', 'at_krb5_udp', 'at_mqtt', 'at_nfs_tcp', 'at_nfs_udp', 'at_ntp', 'at_rdp', 'at_rfb', 'at_sip',
'at_smb', 'at_smtp', 'at_snmp', 'at_ssh', 'at_tftp', 'at_tls', 'bytes', 'dec_avg_pkt_size', 'dec_chdlc', 'dec_ethernet',
'dec_geneve', 'dec_ieee8021ah', 'dec_invalid', 'dec_ipv4', 'dec_ipv4_in_ipv6', 'dec_ipv6', 'dec_max_pkt_size', 'dec_mpls',
'dec_mx_mac_addrs_d', 'dec_mx_mac_addrs_s', 'dec_packets', 'dec_ppp', 'dec_pppoe', 'dec_raw', 'dec_sctp', 'dec_sll',
'dec_tcp', 'dec_teredo', 'dec_too_many_layer', 'dec_udp', 'dec_vlan', 'dec_vlan_qinq', 'dec_vntag', 'dec_vxlan',
'drop_percent', 'dropped', 'error_percent', 'errors', 'f_icmpv4', 'f_icmpv6', 'f_memuse',
'f_tcp', 'f_udp', 'ftp_memuse', 'http_memuse', 'ifdrop_percent', 'ifdropped', 'packets',
'tcp_memuse', 'tcp_reass_memuse', 'uptime',
];
// process each instance
$instance_list = [];
foreach ($suricata['data'] as $instance => $stats) {
if ($instance == '.total') {
$rrd_name = ['app', $name, $app_id];
} else {
$rrd_name = ['app', $name, $app_id, $instance];
$instance_list[] = $instance;
}
foreach ($instance_keys as $metric_key) {
$metrics[$instance . '_' . $metric_key] = $stats[$metric_key];
}
$fields = [];
foreach ($field_keys as $field_key) {
$fields[$field_key] = $stats[$field_key];
}
$tags = ['name' => $name, 'app_id' => $app_id, 'rrd_def' => $rrd_def, 'rrd_name' => $rrd_name];
data_update($device, 'app', $tags, $fields);
}
//
// component processing for ZFS
//
$device_id = $device['device_id'];
$options = [
'filter' => [
'device_id' => ['=', $device_id],
'type' => ['=', 'suricata'],
],
];
$component = new LibreNMS\Component();
$components = $component->getComponents($device_id, $options);
// if no instances, delete the components
if (empty($instance_list)) {
if (isset($components[$device_id])) {
foreach ($components[$device_id] as $component_id => $_unused) {
$component->deleteComponent($component_id);
}
}
} else {
if (isset($components[$device_id])) {
$ourc = $components[$device_id];
} else {
$ourc = $component->createComponent($device_id, 'suricata');
}
// Make sure we don't readd it, just in a different order.
sort($instance_list);
$id = $component->getFirstComponentID($ourc);
$ourc[$id]['label'] = 'Suricata';
$ourc[$id]['instances'] = json_encode($instance_list);
$ourc[$id]['alert'] = $suricata['alert'];
$ourc[$id]['alertString'] = $suricata['alertString'];
$component->setComponentPrefs($device_id, $ourc);
}
//
// all done so update the app metrics
//
update_application($app, 'OK', $metrics);

View File

@ -482,5 +482,50 @@
{
"builder": {"condition":"AND","rules":[{"id":"ports.ifSpeed","field":"ports.ifSpeed","type":"string","input":"text","operator":"greater","value":"0"},{"id":"ports.ifSpeed","field":"ports.ifSpeed","type":"string","input":"text","operator":"less","value":"`ports.ifSpeed_prev`"},{"id":"eventlog.message","field":"eventlog.message","type":"string","input":"text","operator":"begins_with","value":"ifSpeed:"},{"id":"eventlog.datetime","field":"eventlog.datetime","type":"datetime","input":"text","operator":"greater_or_equal","value":"`macros.past_10m`"},{"id":"ports.port_id","field":"ports.port_id","type":"string","input":"text","operator":"equal","value":"`eventlog.reference`"},{"id":"ports.ifOperStatus","field":"ports.ifOperStatus","type":"string","input":"text","operator":"equal","value":"up"},{"id":"ports.disabled","field":"ports.disabled","type":"string","input":"text","operator":"equal","value":"0"}],"valid":true},
"name": "Port Speed Degraded"
},
{
"rule": "applications.app_type = \"suricata\" && application_metrics.metric = \"alert\" && application_metrics.value = \"1\"",
"name": "Suricata has a WARNING alert",
"severity": "warning"
},
{
"rule": "applications.app_type = \"suricata\" && application_metrics.metric = \"alert\" && application_metrics.value = \"2\"",
"name": "Suricata has a CRITICAL alert",
"severity": "critical"
},
{
"rule": "applications.app_type = \"suricata\" && application_metrics.metric = \"alert\" && application_metrics.value = \"3\"",
"name": "Suricata has a UNKNOWN alert",
"severity": "critical"
},
{
"rule": "applications.app_type = \"suricata\" && application_metrics.metric = \".total_drop_percent\" && application_metrics.value >= \"1\"",
"name": "Suricata Packet Drop > 1%",
"severity": "warning"
},
{
"rule": "applications.app_type = \"suricata\" && application_metrics.metric = \".total_drop_percent\" && application_metrics.value >= \"2\"",
"name": "Suricata Packet Drop > 2%",
"severity": "critical"
},
{
"rule": "applications.app_type = \"suricata\" && application_metrics.metric = \".total_ifdrop_percent\" && application_metrics.value >= \"1\"",
"name": "Suricata Packet If Drop > 1%",
"severity": "warning"
},
{
"rule": "applications.app_type = \"suricata\" && application_metrics.metric = \".total_ifdrop_percent\" && application_metrics.value >= \"2\"",
"name": "Suricata Packet If Drop > 2%",
"severity": "critical"
},
{
"rule": "applications.app_type = \"suricata\" && application_metrics.metric = \".total_error_delta\" && application_metrics.value >= \"1\"",
"name": "Suricata Packet Error >= 1%",
"severity": "warning"
},
{
"rule": "applications.app_type = \"suricata\" && application_metrics.metric = \".total_error_delta\" && application_metrics.value >= \"2\"",
"name": "Suricata Packet Error >= 2%",
"severity": "critical"
}
]

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long