diff --git a/agent_based/checkpoint_fw_connections.py b/agent_based/checkpoint_fw_connections.py new file mode 100644 index 0000000000000000000000000000000000000000..ff812b3f308141779c5ae2809a0b903abc4764d1 --- /dev/null +++ b/agent_based/checkpoint_fw_connections.py @@ -0,0 +1,215 @@ +#!/usr/bin/python +# -*- encoding: utf-8; py-indent-offset: 4 -*- +# +# License: GNU General Public License v2 +# +# Author: thl-cmk[at]outlook[dot]com +# URL : https://thl-cmk.hopto.org +# Date : 2018-03-17 +# # +# rewrite of the original checkpoint_connections check from check_mk +# +# added connection statistic details for tcp/udp/icmp/other ..... +# +# 2018-05-29: added connection limit (fwConnTableLimit) +# 2020-05-31: changed form checkpoint_connections to checkpoint_fw_connections +# changed to checkpoint_fw_connections_default_levels to +# factory_settings['checkpoint_fw_connections_defaults'] +# 2020-06-07: code cleanup, added wato, added warn/crit for connection rate +# 2020-06-08: changed snmp-scan function, code cleanup +# 2021-08-24: rewritten for CMK 2.0, +# added relative thresholds (idea and code based on cmk PR #312 by https://github.com/gradecke) +# added lower levels and admin_table_limit +# +# +# sample info +# [[[u'559684419', u'203840211', u'51093794', u'786231', u'815404655', u'0']], [[u'11172', u'27598', u'0']]] +# +# no firewall +# [[], []] +# + +import time +from dataclasses import dataclass +from typing import List, Dict, Any, Optional + +from cmk.base.plugins.agent_based.agent_based_api.v1 import ( + register, + Service, + Result, + check_levels, + State, + SNMPTree, + all_of, + startswith, + any_of, + equals, + Metric, + get_rate, + GetRateError, + get_value_store, + IgnoreResultsError, + render, +) +from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( + DiscoveryResult, + CheckResult, + StringTable, +) + + +@dataclass +class CheckpointFwConnections: + fwConnectionsTcp: int + fwConnectionsUdp: int + fwConnectionsIcmp: int + fwConnectionsOther: int + fwConnectionsSum: int + fwConnectionRate: int + fwCurrnetNumConn: int + fwPeakNumConn: int + fwConnTableLimit: int + + +def parse_checkpoint_fw_connections(string_table: List[StringTable]) -> Optional[CheckpointFwConnections]: + fwConnectionsStat, fwpolicystat = string_table + try: + fwConnectionsTcp, fwConnectionsUdp, fwConnectionsIcmp, fwConnectionsOther, fwConnectionsSum, \ + fwConnectionRate = fwConnectionsStat[0] + except(IndexError, ValueError): + return + + fwCurrnetNumConn, fwPeakNumConn, fwConnTableLimit = fwpolicystat[0] + + return CheckpointFwConnections( + fwConnectionsTcp=int(fwConnectionsTcp), + fwConnectionsUdp=int(fwConnectionsUdp), + fwConnectionsIcmp=int(fwConnectionsIcmp), + fwConnectionsOther=int(fwConnectionsOther), + fwConnectionsSum=int(fwConnectionsSum), + fwConnectionRate=int(fwConnectionRate), + fwCurrnetNumConn=int(fwCurrnetNumConn), + fwPeakNumConn=int(fwPeakNumConn), + fwConnTableLimit=int(fwConnTableLimit), + ) + + +def discovery_checkpoint_fw_connections(section: CheckpointFwConnections) -> DiscoveryResult: + yield Service() + + +def check_checkpoint_fw_connections(params, section: CheckpointFwConnections) -> CheckResult: + fwConnTableLimit = params.get('admin_table_limit', section.fwConnTableLimit) + + if fwConnTableLimit > 0: + yield from check_levels( + value=section.fwCurrnetNumConn * 100 / fwConnTableLimit, + levels_upper=params.get('levels_upper_relative'), + levels_lower=params.get('levels_lower_relative'), + boundaries=(0, 100), + label='Connections relative', + render_func=render.percent, + metric_name='checkpoint_fw_connections_relative' + ) + + if fwConnTableLimit > 0 and 'levels_upper_relative' in params: + warn_pct, crit_pct = params['levels_upper_relative'] + warn = fwConnTableLimit * warn_pct / 100 + crit = fwConnTableLimit * crit_pct / 100 + levels_upper = (warn, crit) + else: + # use absolute levels if no relative levels provided or no maximum set on CP + levels_upper = params.get('levels_upper_absolute', (None, None)) + + if section.fwConnTableLimit > 0 and 'levels_lower_relative' in params: + warn_pct, crit_pct = params['levels_lower_relative'] + warn = fwConnTableLimit * warn_pct / 100 + crit = fwConnTableLimit * crit_pct / 100 + levels_lower = (warn, crit) + else: + # use absolute levels if no relative levels provided or no maximum set on CP + levels_lower = params.get('levels_lower_absolute', (None, None)) + + for label, unit, metric, value, levels_upper, levels_lower in [ + ('Current', '', 'fwcurrentnumconn', section.fwCurrnetNumConn, levels_upper, levels_lower), + ('Peak', '', 'fwpeaknumconn', section.fwPeakNumConn, (None, None), (None, None)), + ('Rate', '/s', 'fwconnectionrate', section.fwConnectionRate, (None, None), (None, None)), + ]: + yield from check_levels( + value=value, + label=label, + metric_name=f'checkpoint_fw_connections_{metric}', + render_func=lambda v: f'{v:.0f}{unit}', + levels_upper=levels_upper, + levels_lower=levels_lower, + boundaries=(0, None), + ) + + if fwConnTableLimit == 0: + yield Result(state=State.OK, summary=f'Table limit: automatically adjusted') + elif section.fwConnTableLimit == fwConnTableLimit: + yield Result(state=State.OK, summary=f'Table limit: {section.fwConnTableLimit}') + else: + yield Result(state=State.OK, summary=f'Table limit: {section.fwConnTableLimit} (CMK admin limit') + + now_time = time.time() + value_store = get_value_store() + + for key, value in [ + ('fwconnectionstcp', section.fwConnectionsTcp), + ('fwconnectionsudp', section.fwConnectionsUdp), + ('fwconnectionsicmp', section.fwConnectionsIcmp), + ('fwconnectionsother', section.fwConnectionsOther), + ('fwconnectionssum', section.fwConnectionsSum), + ]: + try: + value = get_rate(value_store, f'checkpoint_fw_connections_{key}', now_time, value, raise_overflow=True) + except GetRateError: + value = 0 + yield Metric(name=f'checkpoint_fw_connections_{key}', value=value, boundaries=(0, None)) + + +register.snmp_section( + name='checkpoint_fw_connections', + parse_function=parse_checkpoint_fw_connections, + fetch=[ + SNMPTree( + base='.1.3.6.1.4.1.2620.1.1.26.11', # CHECKPOINT-MIB::fwConnectionsStat + oids=[ + '1', # fwConnectionsStatConnectionsTcp + '2', # fwConnectionsStatConnectionsUdp + '3', # fwConnectionsStatConnectionsIcmp + '4', # fwConnectionsStatConnectionsOther + '5', # fwConnectionsStatConnections + '6', # fwConnectionsStatConnectionRate + ] + ), + SNMPTree( + base='.1.3.6.1.4.1.2620.1.1.25', # CHECKPOINT-MIB::fwPolicyStat + oids=[ + '3', # fwNumConn + '4', # fwPeakNumConn + '10', # fwConnTableLimit + ] + ), + ], + detect=any_of( + startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.2620'), + all_of( + equals('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.8072.3.2.10'), + equals('.1.3.6.1.4.1.2620.1.6.1.0', 'SVN Foundation'), + ) + ) +) + +register.check_plugin( + name='checkpoint_fw_connections', + service_name='Firewall connections', + discovery_function=discovery_checkpoint_fw_connections, + check_function=check_checkpoint_fw_connections, + check_ruleset_name='checkpoint_fw_connections', + check_default_parameters={ + # 'levels_upper_absolute': (10000, 20000), + # 'levels_upper_relative': (75, 85) + } +) diff --git a/checkpoint_fw_connections.mkp b/checkpoint_fw_connections.mkp index 0c78645faa44ac4e6309f9ecd9ca13573fad631b..b8cceab3eb6d87c2dd5ff7cc4ad7244e68f4aa5b 100644 Binary files a/checkpoint_fw_connections.mkp and b/checkpoint_fw_connections.mkp differ diff --git a/packages/checkpoint_fw_connections b/packages/checkpoint_fw_connections index 5493ab4d6b5792efd41f2cce348ef810490c2f90..435d04f69614b62cb2474323df5397b8bb48de9b 100644 --- a/packages/checkpoint_fw_connections +++ b/packages/checkpoint_fw_connections @@ -1,12 +1,17 @@ -{'author': u'Th.L. (thl-cmk[at]outlook[dot]com)', - 'description': u'Monitor Check Point Firewall connection statistics.\n\nRewrite of the original check.\nAdded perfdata for peak connections and TCP, UDP, ICMP, other and total connection rate\n', +{'author': 'Th.L. (thl-cmk[at]outlook[dot]com)', + 'description': 'Monitor Check Point Firewall connection statistics.\n' + '\n' + 'Rewrite of the original check.\n' + 'Added perfdata for peak connections and TCP, UDP, ICMP, other ' + 'and total connection rate\n', 'download_url': 'https://thl-cmk.hopto.org', - 'files': {'checks': ['checkpoint_fw_connections'], + 'files': {'agent_based': ['checkpoint_fw_connections.py'], 'web': ['plugins/metrics/checkpoint_fw_connections.py', 'plugins/wato/checkpoint_fw_connections.py']}, 'name': 'checkpoint_fw_connections', 'num_files': 3, - 'title': u'Check Point Connections', - 'version': '20200608.v.0.0.2a', - 'version.min_required': '1.2.8b8', - 'version.packaged': '1.4.0p38'} \ No newline at end of file + 'title': 'Check Point Connections', + 'version': '20210824.v.0.0.3', + 'version.min_required': '2.0.0', + 'version.packaged': '2021.07.14', + 'version.usable_until': None} \ No newline at end of file diff --git a/web/plugins/metrics/checkpoint_fw_connections.py b/web/plugins/metrics/checkpoint_fw_connections.py index 18d1627167792dfed4dd94a875fdfc2d3547964f..686768e2e4ce856e19907acbbfb5732f0068a4f6 100644 --- a/web/plugins/metrics/checkpoint_fw_connections.py +++ b/web/plugins/metrics/checkpoint_fw_connections.py @@ -1,5 +1,5 @@ -#!/usr/bin/python -# -*- encoding: utf-8; py-indent-offset: 4 -*- +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- # # License: GNU General Public License v2 # @@ -11,17 +11,13 @@ # checkpoint_fw_connections # -############################################################################## -# -# define units for perfdata -# -############################################################################## +from cmk.gui.i18n import _ -############################################################################## -# -# define metrics for perfdata -# -############################################################################## +from cmk.gui.plugins.metrics import ( + metric_info, + graph_info, + perfometer_info, +) metric_info['checkpoint_fw_connections_fwconnectionstcp'] = { 'title': _('TCP connections'), @@ -31,17 +27,17 @@ metric_info['checkpoint_fw_connections_fwconnectionstcp'] = { metric_info['checkpoint_fw_connections_fwconnectionsudp'] = { 'title': _('UDP connections'), 'unit': '1/s', - 'color': '12/a', + 'color': '25/a', } metric_info['checkpoint_fw_connections_fwconnectionsicmp'] = { 'title': _('ICMP connections'), 'unit': '1/s', - 'color': '13/a', + 'color': '31/a', } metric_info['checkpoint_fw_connections_fwconnectionsother'] = { 'title': _('Other connections'), 'unit': '1/s', - 'color': '14/a', + 'color': '41/a', } metric_info['checkpoint_fw_connections_fwconnectionssum'] = { 'title': _('Total connections'), @@ -65,32 +61,37 @@ metric_info['checkpoint_fw_connections_fwpeaknumconn'] = { 'color': '16/a', } +metric_info['checkpoint_fw_connections_relative'] = { + 'title': _('Connections relative'), + 'unit': '%', + 'color': '36/a', +} -############################################################################## -# -# map perfdata to metric -# -############################################################################## - - -check_metrics['check_mk-checkpoint_fw_connections'] = { - 'fwconnectionstcp': {'name': 'checkpoint_fw_connections_fwconnectionstcp', }, - 'fwconnectionsudp': {'name': 'checkpoint_fw_connections_fwconnectionsudp', }, - 'fwconnectionsicmp': {'name': 'checkpoint_fw_connections_fwconnectionsicmp', }, - 'fwconnectionsother': {'name': 'checkpoint_fw_connections_fwconnectionsother', }, - 'fwconnectionssum': {'name': 'checkpoint_fw_connections_fwconnectionssum', }, - 'fwconnectionrate': {'name': 'checkpoint_fw_connections_fwconnectionrate', }, - 'fwcurrentnumconn': {'name': 'checkpoint_fw_connections_fwcurrentnumconn', }, - 'fwpeaknumconn': {'name': 'checkpoint_fw_connections_fwpeaknumconn', }, +graph_info['checkpoint_fw_connections_fwpeaknumconn'] = { + 'title': _('Check Point Firewall Connections absolute'), + 'metrics': [ + ('checkpoint_fw_connections_fwpeaknumconn', 'line'), + ('checkpoint_fw_connections_fwcurrentnumconn', 'area'), + ], + 'scalars': [ + ('checkpoint_fw_connections_fwcurrentnumconn:crit', _('crit')), + ('checkpoint_fw_connections_fwcurrentnumconn:warn', _('warn')), + ], } -############################################################################## -# -# how to graph perdata -# -############################################################################## +graph_info['checkpoint_fw_connections_relative'] = { + 'title': _('Check Point Firewall Connections relative to connection table limit'), + 'metrics': [ + ('checkpoint_fw_connections_relative', 'area'), + ], + 'scalars': [ + ('checkpoint_fw_connections_relative:crit', _('crit')), + ('checkpoint_fw_connections_relative:warn', _('warn')), + ], + 'range': (0, 110), +} -graph_info.append({ +graph_info['checkpoint_fw_connections_fwconnectionstcp'] = { 'title': _('Check Point Firewall Connections per second'), 'metrics': [ ('checkpoint_fw_connections_fwconnectionstcp', 'stack'), @@ -100,27 +101,21 @@ graph_info.append({ ('checkpoint_fw_connections_fwconnectionssum', 'line'), ('checkpoint_fw_connections_fwconnectionrate', 'line'), ], -}) - -graph_info.append({ - 'title': _('Check Point Firewall Connections count'), - 'metrics': [ - ('checkpoint_fw_connections_fwpeaknumconn', 'line'), - ('checkpoint_fw_connections_fwcurrentnumconn', 'area'), - ], - 'scalars': [ - ('checkpoint_fw_connections_fwcurrentnumconn:crit', _('crit')), - ('checkpoint_fw_connections_fwcurrentnumconn:warn', _('warn')), - ], -}) - - -############################################################################## -# -# define perf-o-meter -# -############################################################################## +} +perfometer_info.append(('stacked', [ + { + 'type': 'linear', + 'segments': ['checkpoint_fw_connections_relative'], + 'total': 100, + }, + { + 'type': 'logarithmic', + 'metric': 'checkpoint_fw_connections_fwconnectionrate', + 'half_value': 1000.0, + 'exponent': 2, + }, +])) perfometer_info.append(('stacked', [ { @@ -135,4 +130,4 @@ perfometer_info.append(('stacked', [ 'half_value': 1000.0, 'exponent': 2, }, -])) \ No newline at end of file +])) diff --git a/web/plugins/wato/checkpoint_fw_connections.py b/web/plugins/wato/checkpoint_fw_connections.py index 5fd7be04d5284195a5d113a59c96ed601095d03b..85dcb50c2d9f68186b7345695714bbdbd3da5184 100644 --- a/web/plugins/wato/checkpoint_fw_connections.py +++ b/web/plugins/wato/checkpoint_fw_connections.py @@ -1,5 +1,5 @@ -#!/usr/bin/python -# -*- encoding: utf-8; py-indent-offset: 4 -*- +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- # # License: GNU General Public License v2 # @@ -7,28 +7,93 @@ # URL : https://thl-cmk.hopto.org # Date : 2020-06-07 # -register_check_parameters( - subgroup_applications, - 'checkpoint_fw_connections', - _('Check Point Firewall Connections'), - Dictionary( + +from cmk.gui.i18n import _ +from cmk.gui.valuespec import ( + Dictionary, + Tuple, + Integer, + Percentage, +) +from cmk.gui.plugins.wato import ( + CheckParameterRulespecWithItem, + rulespec_registry, + RulespecGroupCheckParametersNetworking, +) + + +def _parameter_valuespec_checkpoint_fw_connections(): + return Dictionary( elements=[ - ('warncritcurrent', + ('levels_upper_absolute', Tuple( - title=_('Levels for number of current active connections'), + title=_('Maximum number of firewall connections'), + help=_('This rule sets upper limits to the current number of connections through ' + 'a Checkpoint firewall.'), elements=[ - Integer(title=_('Warning at'), default_value=1000, unit=_('Count'), allow_empty=False), - Integer(title=_('Critical at'), default_value=2000, unit=_('Count'), allow_empty=False), + Integer(title=_('Warning at'), default_value=1000, unit=_('connections')), + Integer(title=_('Critical at'), default_value=2000, unit=_('connections')), ])), - ('warncritrate', + ('levels_lower_absolute', Tuple( - title=_('Levels for number of new connections/s'), + title=_('Minimum number of firewall connections'), + help=_('This rule sets lower limits to the current number of connections through ' + 'a Checkpoint firewall.'), elements=[ - Integer(title=_('Warning at'), default_value=100, unit=_('Count'), allow_empty=False), - Integer(title=_('Critical at'), default_value=200, unit=_('Count'), allow_empty=False), + Integer(title=_('Warning blow'), default_value=100, unit=_('connections')), + Integer(title=_('Critical below'), default_value=50, unit=_('connections')), + ])), + ('admin_table_limit', + Integer( + title=_('Admin connection table limit'), + help=_('This rule sets the maximum number of connections through the firewall. This is use full ' + 'if your firewall is set to automatic connection table limit and you still want ' + 'relative metrics. This setting takes precedence over the the fwConnTableLimit ' + 'configured on the firewall (only for monitoring purposes of curse). This value should match' + 'the real values of your firewall, if not you might get relative values above 100%.'), + minvalue=0, + unit=_('connections'), + )), + ('levels_upper_relative', + Tuple( + title=_('Percentage of maximum connections (only used if a limit is defined on ' + 'the Check Point device)'), + help=_('This relative threshold can only be used if a maximum number is defined on ' + 'the firewall side and then read from fwConnTableLimit. By default, this ' + 'limit is not set in Check Point devices and this check than falls back to ' + 'the absolute defaults or the ones defined above'), + elements=[ + Percentage( + title=_('Warning at'), unit='%', minvalue=0.0, default_value=80.0, + ), + Percentage( + title=_('Critical at'), unit='%', minvalue=0.0, default_value=90.0), + ])), + ('levels_lower_relative', + Tuple( + title=_('Percentage of minimum connections (only used if a limit is defined on ' + 'the Check Point device)'), + help=_('This relative threshold can only be used if a maximum number is defined on ' + 'the firewall side and then read from fwConnTableLimit. By default, this ' + 'limit is not set in Check Point devices and this check than falls back to ' + 'the absolute defaults or the ones defined above'), + elements=[ + Percentage( + title=_('Warning below'), unit='%', minvalue=0.0, default_value=20.0, + ), + Percentage( + title=_('Critical below'), unit='%', minvalue=0.0, default_value=10.0), ])), ], - ), - None, - match_type='dict', -) \ No newline at end of file + # optional_keys=['levels_upper_relative'], + ) + + +rulespec_registry.register( + CheckParameterRulespecWithItem( + check_group_name='checkpoint_fw_connections', + group=RulespecGroupCheckParametersNetworking, + match_type='dict', + parameter_valuespec=_parameter_valuespec_checkpoint_fw_connections, + title=lambda: _('Check Point Firewall Connections'), + ))