diff --git a/README.md b/README.md
index 130d5391e2201c9451d1182994f81ffcdc2e4151..fd461b9eae194faab851d52e764ca882a80f752c 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[PACKAGE]: ../../raw/master/snmp_state-0.0.3-20230802.mkp "snmp_state-0.0.3-20230802.mkp"
+[PACKAGE]: ../../raw/master/snmp_configuration-0.0.5-20230804.mkp "snmp_configuration-0.0.5-20230804.mkp"
 # SNMP Configuration
 
 This plugin is intended to help you keep track of the SNMP configuration CheckMK is using to monitor your hosts.\
diff --git a/agent_based/snmp_configuration.py b/agent_based/snmp_configuration.py
new file mode 100644
index 0000000000000000000000000000000000000000..76c5543a76e694061865c5fdcaf492c9946dc3be
--- /dev/null
+++ b/agent_based/snmp_configuration.py
@@ -0,0 +1,279 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# License: GNU General Public License v2
+#
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2023-06-28
+# File  : snmp_configuration.py
+
+#
+# Monitor snmp version used by CMK for a host object
+#
+# 2023-06-28: initial release
+# 2023-07-09: added WATO parameters
+# 2023-07-11: added check key length, key complexity,  use of default keys
+# 2023-08-04: renamed from snmp_version to snmp_configuration
+#             streamlined function parameters
+#             added option to check for reversed keys in default keys list
+#             added report only option
+#             added top level _check_key function
+#             added check for duplicate char in key
+
+# ToDo
+#  maybe add number of repeated chars?
+
+
+import re
+from typing import List
+from cmk.base.check_api import host_name
+from cmk.base.config import get_config_cache
+from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
+    DiscoveryResult,
+    CheckResult,
+    StringTable,
+)
+
+from cmk.base.plugins.agent_based.agent_based_api.v1 import (
+    register,
+    Service,
+    SNMPTree,
+    Result,
+    State,
+    exists,
+)
+
+
+def _check_expected(value, message: str, state: int, report_only: bool, excepted: List):
+    if report_only:
+        state = 0
+
+    if value in excepted:
+        yield Result(state=State.OK, summary=f'{message}: {value}')
+    else:
+        yield Result(state=State(state), summary=f'{message} {value}')
+
+
+def _result(message: str, state: int, report_only: bool):
+    if report_only:
+        yield Result(state=State.OK, summary=message)
+    else:
+        yield Result(state=State(state), notice=message)
+
+
+def _check_key_length(key: str, message: str, state: int, report_only: bool, min_length: int):
+    if len(key) < min_length:
+        yield from _result(
+            state=state, report_only=report_only, message=f'{message} length below {min_length}'
+        )
+    else:
+        yield Result(state=State.OK, notice=f'{message} length is not below {min_length}')
+
+
+def _check_default_key(
+        key: str, message: str, state: int, report_only: bool, default_keys: List[str], reversed_key: bool
+):
+    if key.lower() in default_keys:
+        yield from _result(state=state, report_only=report_only, message=f'{message} uses default value')
+    elif reversed_key and key.lower()[::-1] in default_keys:
+        yield from _result(state=state, report_only=report_only, message=f'{message} uses default value (reverse)')
+    else:
+        yield Result(state=State.OK, notice=f'{message} is not using default keys')
+
+
+def _check_key_complexity(key: str, message: str, state: int, report_only: bool, regex: List[str]):
+    _regex = ''.join(regex)
+
+    if not re.search(_regex, key):
+        yield from _result(state=state, report_only=report_only, message=f'{message} complexity is not met')
+    else:
+        yield Result(state=State.OK, notice=f'{message} complexity is met.')
+
+
+def _check_repeated_chars(key: str, message: str, state: int, report_only: bool):
+    _regex = '(.)\\1{1}'  # {x} number of repetitions
+    if re.search(_regex, key):
+        # re.search(_regex, key).group() gives the repeated chars
+        yield from _result(
+            state=state, report_only=report_only,
+            message=f'{message} has repeated chars'
+        )
+    else:
+        yield Result(state=State.OK, notice=f'{message} has no repeated chars')
+
+
+def _check_key(
+        key: str,
+        message: str,
+        report_only: bool,
+        key_length_state: int,
+        key_length_min: int,
+        default_key_state: int,
+        default_key_list: List[str],
+        default_key_reversed: bool,
+        complexity_state: int,
+        complexity_regex: List[str],
+        complexity_repeated: bool,
+):
+    if key_length_min > 0:
+        yield from _check_key_length(key, message, key_length_state, report_only, key_length_min)
+    if default_key_list:
+        yield from _check_default_key(
+            key, message, default_key_state, report_only, default_key_list, default_key_reversed
+        )
+    if complexity_regex:
+        yield from _check_key_complexity(key, message, complexity_state, report_only, complexity_regex)
+    if complexity_repeated:
+        yield from _check_repeated_chars(key, message, complexity_state, report_only)
+
+
+def parse_snmp_configuration(string_table: StringTable):
+    return string_table
+
+
+def discovery_snmp_configuration(section) -> DiscoveryResult:
+    yield Service()
+
+
+def check_snmp_configuration(params, section) -> CheckResult:
+    config_cache = get_config_cache()
+    snmp_host = False
+    report_only = params['report_only']
+
+    try:
+        # test for CMK 2.2.x
+        snmp_host = config_cache.is_snmp_host(host_name())
+        snmp_credentials = config_cache._snmp_credentials(host_name())
+        snmp_backend = config_cache.get_snmp_backend(host_name()).value
+        snmp_version1 = config_cache._is_host_snmp_v1(host_name())
+    except AttributeError:
+        # try cmk 2.0.x - 2.1.x
+        host_config = config_cache.get_host_config(host_name())
+        snmp_config = host_config.snmp_config(None)
+        snmp_credentials = snmp_config.credentials
+        snmp_backend = snmp_config.snmp_backend.value
+        snmp_version1 = host_config._is_host_snmp_v1()
+        if snmp_credentials:
+            snmp_host = True
+
+    if snmp_host:
+        snmp_version = '1' if snmp_version1 else '2c' if type(snmp_credentials) is str else '3'
+
+        excepted, state = params['snmp_version']
+        yield from _check_expected(snmp_version, 'Version', state, report_only, excepted)
+
+        excepted, state = params['snmp_backend']
+        yield from _check_expected(snmp_backend.lower(), 'Backend', state, report_only, excepted)
+
+        if snmp_version == '3':
+            excepted, state = params['v3_level']
+            yield from _check_expected(snmp_credentials[0].lower(), 'Level', state, report_only, excepted)
+
+            if len(snmp_credentials) > 2:
+                excepted, state = params['v3_authentication']
+                excepted = list(map(str.upper, excepted))
+                yield from _check_expected(snmp_credentials[1].upper(), 'Authentication', state, report_only, excepted)
+
+            try:
+                snmp_encryption = snmp_credentials[4]
+            except IndexError:
+                pass
+            else:
+                excepted, state = params['v3_encryption']
+                excepted = list(map(str.upper, excepted))
+                yield from _check_expected(snmp_encryption.upper(), 'Encryption', state, report_only, excepted)
+
+        min_key_length, state_min_key = params['min_key_length']
+        default_keys, reversed_keys, state_default_key = params['default_keys']
+        default_keys = list(map(str.lower, default_keys))
+        key_complexity, repeated_chars, state_key_complexity = params['key_complexity']
+
+        if snmp_version != '3':
+            message = 'Community string'
+            yield from _check_key(
+                key=snmp_credentials,
+                message=message,
+                report_only=report_only,
+                key_length_state=state_min_key,
+                key_length_min=min_key_length,
+                default_key_state=state_default_key,
+                default_key_list=default_keys,
+                default_key_reversed=reversed_keys,
+                complexity_state=state_key_complexity,
+                complexity_regex=key_complexity,
+                complexity_repeated=repeated_chars,
+            )
+        else:
+            if len(snmp_credentials) > 2:
+                message = 'Authentication key'
+                yield from _check_key(
+                    key=snmp_credentials[3],
+                    message=message,
+                    report_only=report_only,
+                    key_length_state=state_min_key,
+                    key_length_min=min_key_length,
+                    default_key_state=state_default_key,
+                    default_key_list=default_keys,
+                    default_key_reversed=reversed_keys,
+                    complexity_state=state_key_complexity,
+                    complexity_regex=key_complexity,
+                    complexity_repeated=repeated_chars,
+                )
+            if len(snmp_credentials) == 6:
+                message = 'Encryption key'
+                yield from _check_key(
+                    key=snmp_credentials[5],
+                    message=message,
+                    report_only=report_only,
+                    key_length_state=state_min_key,
+                    key_length_min=min_key_length,
+                    default_key_state=state_default_key,
+                    default_key_list=default_keys,
+                    default_key_reversed=reversed_keys,
+                    complexity_state=state_key_complexity,
+                    complexity_regex=key_complexity,
+                    complexity_repeated=repeated_chars,
+                )
+                if snmp_credentials[3] != snmp_credentials[5]:
+                    yield Result(state=State.OK, notice=F'Authentication and Encryption key are different')
+                else:
+                    yield Result(
+                        state=State(params['auth_enc_key_identical']),
+                        notice=F'Authentication and Encryption key are identical'
+                    )
+
+    else:
+        yield Result(state=State.OK, summary='No SNMP host')
+
+
+register.snmp_section(
+    name='snmp_configuration',
+    parse_function=parse_snmp_configuration,
+    fetch=SNMPTree(
+        base='.1.3.6.1.2.1.1',  # 
+        oids=[
+            '1',  # sysDescr
+        ]),
+    detect=exists('.1.3.6.1.2.1.1.1.0', ),  # sysDescr
+)
+
+register.check_plugin(
+    name='snmp_configuration',
+    service_name='SNMP Configuration',
+    discovery_function=discovery_snmp_configuration,
+    check_function=check_snmp_configuration,
+    check_default_parameters={
+        'report_only': False,
+        'snmp_version': (['3', 1]),
+        'v3_level': (['authpriv'], 1),
+        'v3_authentication': (['sha', 'sha-224', 'sha-256', 'sha-384', 'sha-512'], 1),
+        'v3_encryption': (['aes'], 1),
+        'snmp_backend': (['inline', 'classic'], 1),
+        'default_keys': (['public', 'private'], True, 1),
+        'min_key_length': (10, 1),
+        'auth_enc_key_identical': 1,
+        'key_complexity': (['(?=.*\\d)', '(?=.*[a-z])', '(?=.*[A-Z])', '(?=.*\\W)', '(?=.{10,})'], True, 1),
+    },
+    check_ruleset_name='snmp_configuration',
+)
diff --git a/gui/wato/check_parameters/snmp_configuration.py b/gui/wato/check_parameters/snmp_configuration.py
new file mode 100644
index 0000000000000000000000000000000000000000..b218f1eb604c64489e4e7b254ec08b09c42190e6
--- /dev/null
+++ b/gui/wato/check_parameters/snmp_configuration.py
@@ -0,0 +1,236 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# License: GNU General Public License v2
+
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2023-07-09
+# File  : snmp_configuration.py
+#
+# WATO file for snmp_configuration check plugin
+#
+# 2023-07-09: initial release
+# 2023-08-04: renamed from snmp_version to snmp_configuration
+#             added options for report only, reversed keys, no repeated chars
+#             optimized layout
+#             moved rule set from Networking to Applications, Processes & Services
+
+
+from cmk.gui.i18n import _
+from cmk.gui.valuespec import (
+    Dictionary,
+    MonitoringState,
+    Tuple,
+    ListChoice,
+    Integer,
+    ListOfStrings,
+    FixedValue,
+    Checkbox,
+)
+
+from cmk.gui.plugins.wato.utils import (
+    CheckParameterRulespecWithoutItem,
+    rulespec_registry,
+    RulespecGroupCheckParametersApplications,
+)
+
+
+def _parameter_valuespec_snmp_configuration():
+    return Dictionary(
+        elements=[
+            ('report_only',
+             FixedValue(
+                 value=True,
+                 title=_('Report only'),
+                 totext=_(''),
+                 help=_('If enabled the check will not create any alerts (WAR/CRIT)'),
+             )),
+            ('snmp_version',
+             Tuple(
+                 title=_('SNMP Version'),
+                 elements=[
+                     ListChoice(
+                         choices=[
+                             ('1', 'Version 1'),
+                             ('2c', 'Version 2c'),
+                             ('3', 'Version 3')
+                         ],
+                         allow_empty=False,
+                         help=_('Select excepted SNMP versions. Default is "Version 3".'),
+                         default_value=['3'],
+                     ),
+                     MonitoringState(
+                         label=_('Monitoring state if version not in list'),
+                         default_value=1,
+                     )
+                 ])),
+            ('v3_level',
+             Tuple(
+                 title=_('SNMP v3 level'),
+                 elements=[
+                     ListChoice(
+                         choices=[
+                             ('authpriv', 'authentication and privacy'),
+                             ('authnopriv', 'authentication and no privacy'),
+                             ('noauthnopriv', 'no authentication and no privacy'),
+                         ],
+                         allow_empty=False,
+                         help=_('Select excepted SNMP v3 protocol level. Default is "authentication and privacy".'),
+                         default_value=['authpriv'],
+                     ),
+                     MonitoringState(
+                         label=_('Monitoring state if level is not list'),
+                         default_value=1,
+                     )
+                 ])),
+            ('v3_authentication',
+             Tuple(
+                 title=_('SNMP v3 authentication'),
+                 elements=[
+                     ListChoice(
+                         choices=[
+                             ('md5', 'MD5'),
+                             ('sha', 'SHA'),
+                             ('sha-224', 'SHA-224'),
+                             ('sha-256', 'SHA-256'),
+                             ('sha-384', 'SHA-384'),
+                             ('sha-512', 'SHA-512'),
+                         ],
+                         allow_empty=False,
+                         help=_('Select excepted SNMP v3 authentication. Default is "SHA*".'),
+                         default_value=['sha', 'sha-224', 'sha-256', 'sha-384', 'sha-512'],
+                     ),
+                     MonitoringState(
+                         label=_('Monitoring state if authentication is not in list'),
+                         default_value=1,
+                     )
+                 ])),
+            ('v3_encryption',
+             Tuple(
+                 title=_('SNMP v3 encryption'),
+                 elements=[
+                     ListChoice(
+                         choices=[
+                             ('des', 'DES'),
+                             ('aes', 'AES-128'),
+                         ],
+                         allow_empty=False,
+                         help=_('Select excepted encryption. Default is "AES-128".'),
+                         default_value=['aes'],
+                     ),
+                     MonitoringState(
+                         label=_('Monitoring state if encryption is not in list'),
+                         default_value=1,
+                     )
+                 ])),
+            ('snmp_backend',
+             Tuple(
+                 title=_('SNMP backend'),
+                 elements=[
+                     ListChoice(
+                         choices=[
+                             ('inline', 'Inline'),
+                             ('classic', 'Classic'),
+                             ('storedwalk', 'Stored walk')
+                         ],
+                         allow_empty=False,
+                         help=_('Select excepted SNMP backend. Default is "Inline/Classic".'),
+                         default_value=['inline', 'classic'],
+                     ),
+                     MonitoringState(
+                         label=_('Monitoring state if backend not in list'),
+                         default_value=1,
+                     )
+                 ])),
+            ('min_key_length',
+             Tuple(
+                 title=_('Minimal key length'),
+                 elements=[
+                     Integer(
+                         minvalue=0,
+                         help=_(
+                             'Minimal expected Community string/key length. '
+                             'Use "0" to disable this check. Default is "10".'
+                         ),
+                         default_value=10,
+                     ),
+                     MonitoringState(
+                         label=_('Monitoring state if key length below minimal key length'),
+                         help=_(
+                             'Set the monitoring state when the length of the Community string (SNMP v1/2c) '
+                             'or the authentication/encryption key (SNMP v3) is below min. length. Default is WARN'
+                         ),
+                         default_value=1,
+                     )
+                 ])),
+            ('auth_enc_key_identical',
+             MonitoringState(
+                 title=_('Monitoring state when authentication and encryption keys are identical'),
+                 help=_(
+                     'Set the monitoring state when authentication key and encryption key are identical. '
+                     'This setting is for SNMP v3 only. Default is WARN.'
+                 ),
+                 default_value=1,
+             )),
+            ('default_keys',
+             Tuple(
+                 title=_('Check default key values'),
+                 elements=[
+                     ListOfStrings(
+                         help=_(
+                             'List of default Community strings/keys to check against. Default is "public, private".'
+                         ),
+                         default_value=['public', 'private'],
+                     ),
+                     Checkbox(
+                         label=_('Check reversed keys'),
+                         help=_('This will also check for keys in reverse. So "cilbup" will match "public".'),
+                         default_value=True,
+                     ),
+                     MonitoringState(
+                         label=_('Monitoring state if key used is a default key'),
+                         help=_(
+                             'Set the monitoring state when the key used is in the list of default keys. '
+                             'Default is WARN'
+                         ),
+                         default_value=1,
+                     )
+                 ])),
+            ('key_complexity',
+             Tuple(
+                 title=_('Key complexity'),
+                 elements=[
+                     ListChoice(
+                         choices=[
+                             ('(?=.*\\d)', 'Digit'),
+                             ('(?=.*[a-z])', 'Lowercase'),
+                             ('(?=.*[A-Z])', 'Uppercase'),
+                             ('(?=.*\\W)', 'Special')
+                         ],
+                         help=_(
+                             'Select expected character types in the Community string or authentication/encryption key.'
+                             ' Default is "Number, Lower case, Upper case, Special".'),
+                         default_value=['(?=.*\\d)', '(?=.*[a-z])', '(?=.*[A-Z])', '(?=.*\\W)'],
+                     ),
+                     Checkbox(
+                         label=_('no repeated chars'),
+                         help=_('This will also check if the key contains repeated characters..'),
+                         default_value=True,
+                     ),
+                     MonitoringState(
+                         label=_('Monitoring state if key complexity not met'),
+                         default_value=1,
+                     )
+                 ])),
+        ])
+
+
+rulespec_registry.register(
+    CheckParameterRulespecWithoutItem(
+        check_group_name='snmp_configuration',
+        group=RulespecGroupCheckParametersApplications,
+        match_type='dict',
+        parameter_valuespec=_parameter_valuespec_snmp_configuration,
+        title=lambda: _('Checkmk SNMP Configuration'),
+    ))
diff --git a/packages/snmp_configuration b/packages/snmp_configuration
new file mode 100644
index 0000000000000000000000000000000000000000..fd08db58f9a2a585ee2c4e3ade96994cfa826267
--- /dev/null
+++ b/packages/snmp_configuration
@@ -0,0 +1,19 @@
+{'author': 'Th.L. (thl-cmk[at]outlook[dot]com)',
+ 'description': 'Monitors SNMP configuration used by CheckMK to access '
+                'monitored hosts.\n'
+                '\n'
+                'This check is intended to help keep track  on the SNMP '
+                'configuration used by CheckMK. \n'
+                '\n'
+                'It will create an alert if old SNMP versions (or bad '
+                'parameters) are in use.\n'
+                'All this can be configured via WATO.\n',
+ 'download_url': 'https://thl-cmk.hopto.org',
+ 'files': {'agent_based': ['snmp_configuration.py'],
+           'gui': ['wato/check_parameters/snmp_configuration.py']},
+ 'name': 'snmp_configuration',
+ 'title': 'SNMP Configuration',
+ 'version': '0.0.5-20230804',
+ 'version.min_required': '2.0.0b1',
+ 'version.packaged': '2.2.0p7',
+ 'version.usable_until': None}
diff --git a/snmp_configuration-0.0.5-20230804.mkp b/snmp_configuration-0.0.5-20230804.mkp
new file mode 100644
index 0000000000000000000000000000000000000000..edd4609bcac5b61a53eb101afe0fd32600569da8
Binary files /dev/null and b/snmp_configuration-0.0.5-20230804.mkp differ