F5-Loadbalancer module to support an expiration check of the installed certificates (#16217)

* On branch f5-cert-expiration-check
Changes to be committed:
	modified:   app/Http/Controllers/Device/Tabs/LoadBalancerController.php
	modified:   includes/discovery/loadbalancers/f5-ltm.inc.php
	modified:   includes/html/pages/device/loadbalancer.inc.php
	new file:   includes/html/pages/device/loadbalancer/f5-cert.inc.php
	modified:   includes/polling/loadbalancers/f5-ltm.inc.php

These patches extend the F5-Loadbalancer module to support an expiration check of
the installed certificates.

* some minor corrections to (hopefully) pass the style-check

* a few more impovements to pass the style-chek

 On branch f5-cert-expiration-check
 Your branch is up to date with 'origin/f5-cert-expiration-check'.

 Changes to be committed:
	modified:   includes/discovery/loadbalancers/f5-ltm.inc.php
	modified:   includes/polling/loadbalancers/f5-ltm.inc.php

* more style-check adaptions...
This commit is contained in:
Ferris-0815
2024-07-29 21:57:37 +02:00
committed by GitHub
parent 903ed58fc3
commit 520e44b0ed
5 changed files with 186 additions and 4 deletions

View File

@@ -71,6 +71,9 @@ class LoadBalancerController implements DeviceTab
if (isset($component_count['f5-gtm-pool'])) {
$this->tabs[] = 'gtm_pool';
}
if (isset($component_count['f5-cert'])) {
$this->tabs[] = 'f5-cert';
}
}
}

View File

@@ -31,7 +31,7 @@ $components = $components[$device['device_id']] ?? [];
// We extracted all the components for this device, now lets only get the LTM ones.
$keep = [];
$types = [$module, 'bigip', 'f5-ltm-bwc', 'f5-ltm-vs', 'f5-ltm-pool', 'f5-ltm-poolmember'];
$types = [$module, 'bigip', 'f5-ltm-bwc', 'f5-ltm-vs', 'f5-ltm-pool', 'f5-ltm-poolmember', 'f5-cert'];
foreach ($components as $k => $v) {
foreach ($types as $type) {
if ($v['type'] == $type) {
@@ -44,6 +44,18 @@ $components = $keep;
// Begin our master array, all other values will be processed into this array.
$tblBigIP = [];
// Cert OIDs
$f5CertOID = '.1.3.6.1.4.1.3375.2.1.15.1.2.1.5';
//$f5CertEntry = [];
// check for installed certs
$f5CertEntry = snmpwalk_group($device, $f5CertOID, 'F5-BIGIP-SYSTEM-MIB');
//If no Certs are found skip this part
if (! empty($f5CertEntry)) {
d_echo('Found Certificates!');
} else {
d_echo('No Certificates found\n');
}
// Virtual Server Data
$ltmVirtualServOID = [
'ip' => '1.3.6.1.4.1.3375.2.2.10.1.2.1.3',
@@ -125,10 +137,58 @@ if (! empty($ltmBwcEntry['name'])) {
* False == no object found - this is not an error, OID doesn't exist.
* null == timeout or something else that caused an error, OID may exist but we couldn't get it.
*/
if (! empty($ltmBwcEntry) || ! empty($ltmVirtualServEntry) || ! empty($ltmPoolEntry) || ! empty($ltmPoolMemberEntry)) {
if (! empty($f5CertEntry) || ! empty($ltmBwcEntry) || ! empty($ltmVirtualServEntry) || ! empty($ltmPoolEntry) || ! empty($ltmPoolMemberEntry)) {
// No Nulls, lets go....
d_echo("Objects Found:\n");
// Process Certificates
$CERT_BASE_OID_NAME = 'sysCertificateFileObjectExpirationDate';
$CERT_THRESHOLD_WARNING = 30; // If Cert expires in less than this value (in days) => status = warning
$CERT_THRESHOLD_CRITICAL = 10; // If Cert expires in less than this value (in days) => status = critical
if (is_array($f5CertEntry)) {
foreach ($f5CertEntry as $cert => $array) {
$result = [];
$result['type'] = 'f5-cert';
$result['UID'] = $cert;
$result['label'] = $cert;
$result['raw'] = $array[$CERT_BASE_OID_NAME];
// expiration value from snmpwalk is in seconds since 01.01.1970
// we substract the current time, to get the time left until expiration
// and convert it into days, for better human readability
$result['daysLeft'] = intval(($array[$CERT_BASE_OID_NAME] - getdate()[0]) / (3600 * 24));
// UID might be to long for use in a RRD filename, use a hash instead
$result['hash'] = hash('crc32', $result['UID']);
//let's check when the cert expires
if ($result['daysLeft'] <= 0) {
$result['status'] = 2;
$result['error'] = 'CRITICAL: Certificate is expired!';
} elseif ($result['daysLeft'] <= $CERT_THRESHOLD_CRITICAL) {
$result['status'] = 2;
$result['error'] = 'CRITICAL: Certificate is about to expire in ' . $result['daysLeft'] . ' days!';
} elseif ($result['daysLeft'] <= $CERT_THRESHOLD_WARNING) {
$result['status'] = 1;
$result['error'] = 'WARNING: Certificate is about to expire in ' . $result['daysLeft'] . ' days!';
} else {
$result['status'] = 0;
$result['error'] = '';
}
// Do we have any results
if (count($result) > 0) {
// Let's log some debugging
d_echo('\n\n' . $result['type'] . ' - ' . $result['label'] . ': ' . $result['daysLeft'] . '\n');
d_echo(' Status: ' . $result['status'] . '\n');
d_echo(' Message: ' . $result['error'] . '\n');
// Add this result to the master array.
$tblBigIP[] = $result;
}
}
}
// Process the Virtual Servers
if (is_array($ltmVirtualServEntry['name'])) {
foreach ($ltmVirtualServEntry['name'] as $oid => $value) {
@@ -314,6 +374,7 @@ if (! empty($ltmBwcEntry) || ! empty($ltmVirtualServEntry) || ! empty($ltmPoolEn
*
* Let's loop over the SNMP data to see if we need to ADD or UPDATE any components.
*/
foreach ($tblBigIP as $key => $array) {
$component_key = false;

View File

@@ -14,6 +14,7 @@ $type_text['ltm_pool'] = 'LTM Pools'; // F5 BigIP
$type_text['ltm_bwc'] = 'LTM Bandwidth Controller'; // F5 BigIP
$type_text['gtm_wide'] = 'GTM Wide IPs'; // F5 BigIP
$type_text['gtm_pool'] = 'GTM Pools'; // F5 BigIP
$type_text['f5-cert'] = 'Certificates'; // F5 BigIP
print_optionbar_start();

View File

@@ -0,0 +1,83 @@
<?php
/*
* LibreNMS module to Display data from F5 BigIP LTM Devices
*
* Copyright (c) 2016 Aaron Daniels <aaron@daniels.id.au>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
$component = new LibreNMS\Component();
$components = $component->getComponents($device['device_id'], ['filter' => ['ignore' => ['=', 0]]]);
// We only care about our device id.
$components = $components[$device['device_id']];
// We extracted all the components for this device, now lets only get the LTM ones.
$keep = [];
$types = [$module, 'f5-cert'];
foreach ($components as $k => $v) {
foreach ($types as $type) {
if ($v['type'] == $type) {
$keep[$k] = $v;
}
}
}
$components = $keep;
/*
* if (is_file('includes/html/pages/device/loadbalancer/' . $vars['subtype'] . '.inc.php')) {
* include 'includes/html/pages/device/loadbalancer/' . $vars['subtype'] . '.inc.php';
* } else {
* include 'includes/html/pages/device/loadbalancer/ltm_pool_all.inc.php';
* }//end if
*/
//echo '<script>console.log("' . $type . '");</script>';
?>
<table id='grid' data-toggle='bootgrid' class='table table-condensed table-responsive table-striped'>
<thead>
<tr>
<th data-column-id="cert">Certificate</th>
<th data-column-id="daysleft" data-type="numeric">Days left until expiration</th>
<th data-column-id="status" data-visible="false">Status</th>
<th data-column-id="message">Status</th>
</tr>
</thead>
<tbody>
<?php
foreach ($components as $cert => $array) {
if ($array['type'] != 'f5-cert') {
continue;
}
if ($array['status'] != 0) {
$message = $array['error'];
$status = 2;
} else {
$message = 'Ok';
$status = '';
} ?>
<tr <?php echo $error; ?>>
<td><?php echo $array['label']; ?></td>
<td><?php echo $array['daysLeft']; ?></td>
<td><?php echo $status; ?></td>
<td><?php echo $message; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
<script type="text/javascript">
$("#grid").bootgrid({
caseSensitive: false,
statusMappings: {
2: "danger"
},
})
</script>

View File

@@ -33,7 +33,7 @@ $components = $components[$device['device_id']] ?? [];
// We extracted all the components for this device, now lets only get the LTM ones.
$keep = [];
$types = ['f5-ltm-vs', 'f5-ltm-bwc', 'f5-ltm-pool', 'f5-ltm-poolmember'];
$types = ['f5-ltm-vs', 'f5-ltm-bwc', 'f5-ltm-pool', 'f5-ltm-poolmember', 'f5-cert'];
foreach ($components as $k => $v) {
foreach ($types as $type) {
if ($v['type'] == $type) {
@@ -46,6 +46,8 @@ $components = $keep;
// Only collect SNMP data if we have enabled components
if (! empty($components)) {
// Let's gather the stats..
$f5_stats['f5-cert'] = snmpwalk_group($device, '.1.3.6.1.4.1.3375.2.1.15.1.2.1.5', 'F5-BIGIP-SYSTEM-MIB');
$f5_stats['ltmVirtualServStatEntryPktsin'] = snmpwalk_array_num($device, '.1.3.6.1.4.1.3375.2.2.10.2.3.1.6', 0);
$f5_stats['ltmVirtualServStatEntryPktsout'] = snmpwalk_array_num($device, '.1.3.6.1.4.1.3375.2.2.10.2.3.1.8', 0);
$f5_stats['ltmVirtualServStatEntryBytesin'] = snmpwalk_array_num($device, '.1.3.6.1.4.1.3375.2.2.10.2.3.1.7', 0);
@@ -84,7 +86,39 @@ if (! empty($components)) {
$hash = $array['hash'];
$rrd_name = [$type, $label, $hash];
if ($type == 'f5-ltm-bwc') {
if ($type == 'f5-cert') {
$CERT_BASE_OID_NAME = 'sysCertificateFileObjectExpirationDate';
$CERT_THRESHOLD_WARNING = 30; // If Cert expires in less than this value (in days) => status = warning
$CERT_THRESHOLD_CRITICAL = 10; // If Cert expires in less than this value (in days) => status = critical
// expiration value from snmpwalk is in seconds since 01.01.1970
// we substract the current time, to get the time left until expiration
// and convert it into days, for better human readability
$array['daysLeft'] = intval(($f5_stats['f5-cert'][$UID][$CERT_BASE_OID_NAME] - getdate()[0]) / (3600 * 24));
$array['raw'] = $f5_stats['f5-cert'][$UID][$CERT_BASE_OID_NAME];
// Let's log some debugging
d_echo("\n\nComponent: " . $key . "\n");
d_echo(' Type: ' . $type . "\n");
d_echo(' Label: ' . $label . "\n");
d_echo(' Days until expiration: ' . $array['daysLeft'] . "\n");
d_echo(' RAW: ' . $array['raw'] . "\n");
//let's check when the cert expires
if ($array['daysLeft'] <= 0) {
$array['status'] = 2;
$array['error'] = 'CRITICAL: Certificate is expired!';
} elseif ($array['daysLeft'] <= $CERT_THRESHOLD_CRITICAL) {
$array['status'] = 2;
$array['error'] = 'CRITICAL: Certificate is about to expire in ' . $array['daysLeft'] . ' days!';
} elseif ($array['daysLeft'] <= $CERT_THRESHOLD_WARNING) {
$array['status'] = 1;
$array['error'] = 'WARNING: Certificate is about to expire in ' . $array['daysLeft'] . ' days!';
} else {
$array['status'] = 0;
$array['error'] = '';
}
} elseif ($type == 'f5-ltm-bwc') {
$rrd_def = RrdDefinition::make()
->addDataset('pktsin', 'COUNTER', 0)
->addDataset('bytesin', 'COUNTER', 0)