SNMP-basierte Check-Plugin für Sophos Firewall IPSec Tunnel

CMK version: 2.3.0p10
OS version: Linux Debian

Hallo,

wir möchten ein SNMP-basiertes Check-Plugin schreiben um von einer Sophos Firewall die IPSec VPN Tunnels nach deren Namen und Status abzufragen.
Die Firewall ist als Host in CheckMK angelegt und auch per SNMP abfragbar (ein paar Informationen erhalten wir).

Das Skript was wir erstellt haben ist folgendes:

*#!/usr/bin/env python3*
*# -*- coding: utf-8 -*-*

*import time*
*from cmk.agent_based import (*
*    register,*
*    Result,*
*    SNMPTree,*
*    State,*
*    contains,*
*)*

*register.snmp_section(*
*    name="sophosxg_ipsec_vpn_tunnels",*
*    fetch=SNMPTree(*
*        base="1.3.6.1.4.1.2604.5.1.6",*
*        oids=["2", "9"],  # OID 2 Name, OID 9 Status*
*    ),*
*    detect=contains(".1.3.6.1.4.1.2604.5.1.1.2", "XGS"),*
*)*

*def discover_sophosxg_ipsec_vpn_tunnels(section):*
*    yield Service()*

*def check_sophosxg_ipsec_vpn_tunnels(section):*
*    tunnel_state = section[0][0]*
*    tunnel_name = section[0][1]  # Tunnel-Name aus SNMP-Daten extrahieren*
*    state_name = "Unknown"*

*    if tunnel_state == "0":*
*        state_name = "Inactive"*
*        state = State.CRIT*
*    elif tunnel_state == "1":*
*        state_name = "Active"*
*        state = State.OK*
*    elif tunnel_state == "2":*
*        state_name = "Partially Active"*
*        state = State.WARN*
*    else:*
*        state_name = "Unknown"*
*        state = State.UNKNOWN*

*    yield Result(*
*        state=state,*
*        summary=f"IPSec VPN Tunnel '{tunnel_name}' State: {state_name}",*
*    )*

*register.check_plugin(*
*    name="sophosxg_ipsec_vpn_tunnels",*
*    service_name="IPSec VPN Tunnel Status",*
*    discovery_function=discover_sophosxg_ipsec_vpn_tunnels,*
*    check_function=check_sophosxg_ipsec_vpn_tunnels,*
*)*

Das Skript liegt unter ~/local/lib/python3/cmk_addons/plugins/sophos/agent_based$ ab.

Starten wir mit dem Befehlt cmk-R den Monitoring-Dienst neu, erhalten wir folgende Fehlermeldung:

Error in agent based plugin: cmk_addons.plugins.sophos.agent_based.sophos_ipsec_tunnels: cannot import name ‘register’ from ‘cmk.agent_based’ (unknown location)Generating configuration for core (type nagios)…

Ein snmpwalk auf dem Host mit den OIDs ist erfolgreich und liefert auch die entsprechenden Werte zurück.

Leider kommen wir nicht weiter und erhoffen uns Hilfe durch das Forum :slight_smile:

@ThorstenITB euer Script ist noch mit der Check API für pre CMK 2.3 geschrieben. Damit gehört es nach

~/local/lib/check_mk/base/plugins/agent_based
1 Like

Vielen Dank für den Hinweis!
Mit einer weiteren Anpassung im Skript habe ich es hinbekommen keine Fehlermeldung nach cmk -R zu erhalten.

Jetzt habe ich das Problem, dass ich mit dem Check keine Daten bekomme. Dafür nutze ich aus den Docs diesen Befehl:

cmk -vI --detect-plugins=sophos_ipsec_tunnels.py myfw01

Was ich anschließend erhalte ist:

Discovering services and host labels on: myfw01
myfw01:

  • FETCHING DATA
    No piggyback files for ‘myfw01’. Skip processing.
    No piggyback files for ‘ipaddress’. Skip processing.
    Get piggybacked data
  • ANALYSE DISCOVERED HOST LABELS
    SUCCESS - Found no new host labels
  • ANALYSE DISCOVERED SERVICES
  • EXECUTING DISCOVERY PLUGINS (0)
    SUCCESS - Found no new services

Laut den Docs sollte nun aber unter Executing Discovery Plugins nicht (0) sondern (1) sein.

Was können wir hier noch falsch machen?

  • Muss das Skript als MKP installiert werden? Mit mkp list ist dort nichts aufgeführt was zu unserem Skript passt.
  1. Remove the “.py” in the command line
  2. It may be a problem with your detect function. In generell it is best practice not to use a vendor specific oid to detect as this will require an additional snmp request to all devices. It is better to use a common oid like “.1.3.6.1.2.1.1.1.0” and check for sophos or whatever can be found there. You don’t need to be over specific. The detect function is for reducing the snmp requests when discovering many/all devices. If your detect matches, but you can’t fetch the defined oids afterwards this does not harm.

Thank you for your reply.

I removed the .py from the command but that didn’t help.

Then I used the general OID from you in the detect function and queried for several values that are contained there. With a snmpwalk I checked the query for the host and got the values.
But with the command cmk -vI --detect-plugins=sophos_ipsec_tunnels myfw01 I still get the response Executing Discovery Plugins (0).

I have also completely removed the detect function in my script and I still get Executing Discovery Plugins (0).

Please try this command and post the output:
cmk -vvI --debug --detect-plugins=sophos_ipsec_tunnels myfw01

This is the output of your command.
I have currently saved the query for your general OID in the script.

OMD[MYSITE]:~/local/lib/check_mk/base/plugins/agent_based$ cmk -vvI --debug --detect-plugins=sophos_ipsec_tunnels myfw01
Trying to acquire lock on /omd/sites/MYSITE/var/check_mk/crashes/base/e79e4b74-dfb1-11ef-b144-005056a0eed9/crash.info
Got lock on /omd/sites/MYSITE/var/check_mk/crashes/base/e79e4b74-dfb1-11ef-b144-005056a0eed9/crash.info
Releasing lock on /omd/sites/MYSITE/var/check_mk/crashes/base/e79e4b74-dfb1-11ef-b144-005056a0eed9/crash.info
Released lock on /omd/sites/MYSITE/var/check_mk/crashes/base/e79e4b74-dfb1-11ef-b144-005056a0eed9/crash.info
Traceback (most recent call last):
  File "/omd/sites/MYSITE/bin/cmk", line 97, in <module>
    errors = config.load_all_plugins(
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/omd/sites/MYSITE/lib/python3/cmk/base/config.py", line 1395, in load_all_plugins
    errors = agent_based_register.load_all_plugins()
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/omd/sites/MYSITE/lib/python3/cmk/base/api/agent_based/register/_discover.py", line 48, in load_all_plugins
    raise exception
  File "/omd/sites/MYSITE/lib/python3/cmk/utils/plugin_loader.py", line 51, in load_plugins
    yield name, importlib.import_module(full_name)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/omd/sites/MYSITE/lib/python3.12/importlib/__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "/omd/sites/MYSITE/local/lib/python3/cmk/base/plugins/agent_based/sophos_ipsec_tunnels.py", line 16, in <module>
    register.snmp_section(
  File "/omd/sites/MYSITE/lib/python3/cmk/base/api/agent_based/register/export.py", line 257, in snmp_section
    return register_snmp_section(
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/omd/sites/MYSITE/lib/python3/cmk/base/api/agent_based/register/_discover.py", line 109, in register_snmp_section
    section_plugin = create_snmp_section_plugin(
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/omd/sites/MYSITE/lib/python3/cmk/base/api/agent_based/register/section_plugins.py", line 288, in create_snmp_section_plugin
    _validate_fetch_spec(snmp_section_spec.fetch)
  File "/omd/sites/MYSITE/lib/python3/cmk/base/api/agent_based/register/section_plugins.py", line 190, in _validate_fetch_spec
    tree.validate()
  File "/omd/sites/MYSITE/lib/python3.12/site-packages/cmk/agent_based/v1/_snmp.py", line 124, in validate
    self._validate_base(self.base)
  File "/omd/sites/MYSITE/lib/python3.12/site-packages/cmk/agent_based/v1/_snmp.py", line 142, in _validate_base
    raise ValueError(f"{base!r} must start with '.'")
ValueError: '1.3.6.1.4.1.2604.5.1.6' must start with '.'

I have seen the error and just fixed it in the script.

The new output with your command is here:

OMD[MYSITE]:~/local/lib/check_mk/base/plugins/agent_based$ cmk -vvI --debug --detect-plugins=sophos_ipsec_tunnels myfw01
Discovering services and host labels on: myfw01
myfw01:
+ FETCHING DATA
  Source: SourceInfo(hostname='myfw01', ipaddress='10.10.10.5', ident='snmp', fetcher_type=<FetcherType.SNMP: 7>, source_type=<SourceType.HOST: 1>)
[cpu_tracking] Start [7ff7c82cac00]
Read from cache: SNMPFileCache(myfw01, path_template=/omd/sites/MYSITE/tmp/check_mk/data_source_cache/snmp/{mode}/{hostname}, max_age=MaxAge(checking=0, discovery=90.0, inventory=90.0), simulation=False, use_only_cache=False, file_cache_mode=1)
[cpu_tracking] Stop [7ff7c82cac00 - Snapshot(process=posix.times_result(user=0.0, system=0.0, children_user=0.0, children_system=0.0, elapsed=0.010000001639127731))]
  Source: SourceInfo(hostname='myfw01', ipaddress='10.10.10.5', ident='piggyback', fetcher_type=<FetcherType.PIGGYBACK: 4>, source_type=<SourceType.HOST: 1>)
[cpu_tracking] Start [7ff7c7f6ce60]
Read from cache: NoCache(myfw01, path_template=/dev/null, max_age=MaxAge(checking=0.0, discovery=0.0, inventory=0.0), simulation=False, use_only_cache=False, file_cache_mode=1)
No piggyback files for 'myfw01'. Skip processing.
No piggyback files for '10.10.10.5'. Skip processing.
Get piggybacked data
[cpu_tracking] Stop [7ff7c7f6ce60 - Snapshot(process=posix.times_result(user=0.0, system=0.0, children_user=0.0, children_system=0.0, elapsed=0.0))]
+ PARSE FETCHER RESULTS
  HostKey(hostname='myfw01', source_type=<SourceType.HOST: 1>)  -> Add sections: []
  HostKey(hostname='myfw01', source_type=<SourceType.HOST: 1>)  -> Add sections: []
Received no piggyback data
+ ANALYSE DISCOVERED HOST LABELS
Trying host label discovery with:
Trying host label discovery with:
SUCCESS - Found no new host labels
+ ANALYSE DISCOVERED SERVICES
+ EXECUTING DISCOVERY PLUGINS (0)
  Trying discovery with:
SUCCESS - Found no new services

So change your base as mention to:

base=".1.3.6.1.4.1.2604.5.1.6",

Sorry, I was too quick with my first post. Below I have already informed you that I have corrected this error. I have the requested output here again:

OMD[MYSITE]:~/local/lib/check_mk/base/plugins/agent_based$ cmk -vvI --debug --detect-plugins=sophos_ipsec_tunnels myfw01
Discovering services and host labels on: myfw01
myfw01:
+ FETCHING DATA
  Source: SourceInfo(hostname='myfw01', ipaddress='10.10.10.5', ident='snmp', fetcher_type=<FetcherType.SNMP: 7>, source_type=<SourceType.HOST: 1>)
[cpu_tracking] Start [7ff7c82cac00]
Read from cache: SNMPFileCache(myfw01, path_template=/omd/sites/MYSITE/tmp/check_mk/data_source_cache/snmp/{mode}/{hostname}, max_age=MaxAge(checking=0, discovery=90.0, inventory=90.0), simulation=False, use_only_cache=False, file_cache_mode=1)
[cpu_tracking] Stop [7ff7c82cac00 - Snapshot(process=posix.times_result(user=0.0, system=0.0, children_user=0.0, children_system=0.0, elapsed=0.010000001639127731))]
  Source: SourceInfo(hostname='myfw01', ipaddress='10.10.10.5', ident='piggyback', fetcher_type=<FetcherType.PIGGYBACK: 4>, source_type=<SourceType.HOST: 1>)
[cpu_tracking] Start [7ff7c7f6ce60]
Read from cache: NoCache(myfw01, path_template=/dev/null, max_age=MaxAge(checking=0.0, discovery=0.0, inventory=0.0), simulation=False, use_only_cache=False, file_cache_mode=1)
No piggyback files for 'myfw01'. Skip processing.
No piggyback files for '10.10.10.5'. Skip processing.
Get piggybacked data
[cpu_tracking] Stop [7ff7c7f6ce60 - Snapshot(process=posix.times_result(user=0.0, system=0.0, children_user=0.0, children_system=0.0, elapsed=0.0))]
+ PARSE FETCHER RESULTS
  HostKey(hostname='myfw01', source_type=<SourceType.HOST: 1>)  -> Add sections: []
  HostKey(hostname='myfw01', source_type=<SourceType.HOST: 1>)  -> Add sections: []
Received no piggyback data
+ ANALYSE DISCOVERED HOST LABELS
Trying host label discovery with:
Trying host label discovery with:
SUCCESS - Found no new host labels
+ ANALYSE DISCOVERED SERVICES
+ EXECUTING DISCOVERY PLUGINS (0)
  Trying discovery with:
SUCCESS - Found no new services

Hello, does anyone else have an idea? I still need help, even if it’s a bit older.

If i want to see if a plugin is really working i would not use the “–detect-plugins” option. This option will overwrite the detect function. Second problem i see - your last output uses the cache for this device. Please add the option “–no-cache” to the command line to force CheckMK to retrieve data from the device.

If you use the “–detect-plugins” option you should see as a minimum the fetching of the data for this plugin in the output.

@ThorstenITB: Have you managed to make it work?
I have the same issue.

I am trying to create a SNMP plugin in 2.3.0p33.cee (actually adjust an existing one that was working on 1.6-2.2). I put the file under local/lib/python3/cmk/base/plugins/agent_based/zzz_debug_memory.py. If I run an inventory, no new services are found. If I add a syntax error to the file and run the service discovery again, there is an exceptions due to the syntax error in the file.

If I add print(“DEBUG”) on the very top of the plugin (right after the first line), I can see the output. But no debug output from any of the print debug lines in any of the functions like parse_zzz_debug_memory or discovery_zzz_debug_memory, nothing.

image

and

image

this is the whole output w/o debug output
image

any hints?

In this output i see already the problem, you use the “–usewalk” option but in the output i see nowhere that it uses any walk file.
The raw output without any removed data would be needed to really say something.

thanks Andreas!
Adding the fresh output here below

OMD[site2]:~$ cmk --debug -vvII --detect-plugins=zzz_debug_memory switch1 
Discovering services and host labels on: switch1 
switch1: 
+ FETCHING DATA 
  Source: SourceInfo(hostname='switch1', ipaddress='10.230.165.34', ident='snmp', fetcher_type=<FetcherType.SNMP: 7>, source_type=<SourceType.HOST: 1>) 
[cpu_tracking] Start [7f06c5f266f0] 
Read from cache: SNMPFileCache(switch1, path_template=/omd/sites/site2/tmp/check_mk/data_source_cache/snmp/{mode}/{hostname}, max_age=MaxAge(checking=0, discovery=270.0, inventory=270.0), simulation=False, use_only_cache=False, file_cache_mode=1) 
[cpu_tracking] Stop [7f06c5f266f0 - Snapshot(process=posix.times_result(user=0.0, system=0.0, children_user=0.0, children_system=0.0, elapsed=0.0))] 
  Source: SourceInfo(hostname='switch1', ipaddress='10.230.165.34', ident='piggyback', fetcher_type=<FetcherType.PIGGYBACK: 4>, source_type=<SourceType.HOST: 1>) 
[cpu_tracking] Start [7f06c5f42240] 
Read from cache: NoCache(switch1, path_template=/dev/null, max_age=MaxAge(checking=0.0, discovery=0.0, inventory=0.0), simulation=False, use_only_cache=False, file_cache_mode=1) 
No piggyback files for 'switch1'. Skip processing. 
No piggyback files for '10.230.165.34'. Skip processing. 
Get piggybacked data 
[cpu_tracking] Stop [7f06c5f42240 - Snapshot(process=posix.times_result(user=0.0, system=0.0, children_user=0.0, children_system=0.0, elapsed=0.009999997913837433))] 
+ PARSE FETCHER RESULTS 
  HostKey(hostname='switch1', source_type=<SourceType.HOST: 1>)  -> Add sections: [] 
  HostKey(hostname='switch1', source_type=<SourceType.HOST: 1>)  -> Add sections: [] 
Received no piggyback data 
+ ANALYSE DISCOVERED HOST LABELS 
Trying host label discovery with: 
Trying host label discovery with: 
SUCCESS - Found no host labels 
+ ANALYSE DISCOVERED SERVICES 
+ EXECUTING DISCOVERY PLUGINS (0) 
  Trying discovery with: 
SUCCESS - Found no services 

and the plugin itself

from cmk.agent_based.v2 import ( 
    SNMPSection, 
    CheckPlugin, 
    Result, 
    Service, 
    State, 
) 

# Dummy parser that just returns a fixed dictionary 
def parse_zzz_debug_memory(string_table): 
    print("DEBUG: Parsing SNMP data:", string_table) 
    return {"memfree": 1000, "memtotal": 4000} 

# Always discover a service 
def discover_zzz_debug_memory(section): 
    print("DEBUG: Discovery function called with section:", section) 
    yield Service() 

# Always run a check and return OK 
def check_zzz_debug_memory(params, section): 
    print("DEBUG: Check function called with section:", section) 
    usage = 100 - (section["memfree"] / section["memtotal"] * 100) 
    yield Result(state=State.OK, summary=f"Dummy memory usage: {usage:.1f}%") 

# Register SNMP section 
snmp_section = SNMPSection( 
    name="zzz_debug_memory", 
    detect=lambda oid: True,  # Always detect 
    fetch=(".1.3.6.1.2.1.1", ["1"]),  # Dummy OID for testing 
    parse_function=parse_zzz_debug_memory, 
) 

# Register check plugin 
check_plugin = CheckPlugin( 
    name="zzz_debug_memory", 
    service_name="Debug Memory Check", 
    sections=["zzz_debug_memory"], 
    discovery_function=discover_zzz_debug_memory, 
    check_function=check_zzz_debug_memory, 
) 

@hnmr: No unfortunately i didn’t get it to work. At the moment i have stopped this.
However, i have to say that i’m not a python specialist at all and asked ChatGPT to help me with this script.
If you have the script for ipsec monitoring of a sophos firewall, would you share it?

I would share it, but I don’t have sophos firewalls :slight_smile: I am working on a plugin for DELL switches actually, but the behavior with the SNMP plugin I have faced is the same you had faced before. Therefore I added my comments here.

Ok, looks like I have resolved it. Some names must have the plugin name as part of them:
check_plugin → check_plugin_zzz_debug_memory
snmp_section → snmp_section_zzz_debug_memory

Without this the plugin was not registred and so not used for the inventory.

Cheers,
Hermann M.