Skip to content

Releases: nethesis/checkmk-tools

v1.7.7 - Remove excluded/legacy reference scripts from full/

Choose a tag to compare

@Coverup20 Coverup20 released this 20 Jul 15:32

What changed

  • Removed check_apk_packages.py, check_opkg_packages.py, check_martian_packets.py from script-check-nsec8/full/ - these were kept only as source reference despite never being part of the ns-checkmk-utils production set, which was confusing (a PR reviewer flagged them as apparently-installed-but-unused).
  • Updated full/README.md to drop the now-obsolete "Excluded / legacy checks" section.

What did NOT change

  • All 10 production checks are byte-identical to v1.7.6 (verified via sha256 diff, see below).
  • No test files existed for the 3 removed scripts (they were never covered by the pytest suite).

Testing

$ cd script-check-nsec8 && python3 -m pytest tests/ -q
........................................................................ [ 66%]
....................................                                     [100%]
108 passed in 0.34s
$ git ls-tree -r --name-only v1.7.7 -- script-check-nsec8/full/ | grep '\.py$'
check_dhcp_leases.py
check_dns_resolution.py
check_firewall_connections.py
check_firewall_rules.py
check_firewall_traffic.py
check_ovpn_host2net.py
check_root_access.py
check_vpn_tunnels.py
check_wan_status.py
check_wan_throughput.py

sha256 of all 10 production checks confirmed identical between v1.7.6 and v1.7.7 (no functional change, cleanup-only release).

v1.7.6 - NSEC8: nethsec library migration, WAN status/throughput fixes, pytest suite

Choose a tag to compare

@Coverup20 Coverup20 released this 20 Jul 13:54

NSEC8 checks: nethsec library migration + WAN status/throughput fixes

Changes, per script

  • check_wan_status.py: interface discovery via nethsec.inventory.get_networks()
    (role=="red") + nethsec.utils.get_all_by_type() for UCI section lookup, falling
    back to /proc/net/route only if the library is unavailable. Up/down state and
    gateway now come from ubus call network.interface.<label> status (PPPoE runtime
    device resolved via its l3_device field) instead of /sys/class/net/*/operstate.
    Split output into WAN.Interface.<label> (raw interface state) and
    WAN.Status.<label> (adds internet reachability via ping -I <device> against the
    same host list as NethSecurity's own dashboard check_internet()). Gateway
    TCP-probe port-80 failure no longer forces WARNING. Added WAN.Metrics perfdata.
  • check_wan_throughput.py: same nethsec.inventory.get_networks() +
    nethsec.utils.get_all_by_type() + ubus-based PPPoE device resolution as above.
    Counter-reset now re-baselines instead of fabricating a bogus throughput spike;
    unknown link speed no longer defaults to 1000Mbps (was masking real saturation);
    fixed a /proc/net/dev column-padding bug that silently skipped short interface
    names (eth0/eth1/eth2); service name order corrected to WAN.Throughput.<label>.
  • check_root_access.py: fixed a "PPID:" vs actual "PPid:" case-sensitivity
    bug in the /proc/<pid>/status scan that made the main dropbear daemon always
    count as a phantom session. Removed unverified glibc utmp struct parsing (the
    file doesn't exist on this platform). Login detection now matches 3 real sources
    (SSH via dropbear, local console via busybox login, web UI via
    nethsecurity-api's authentication success/failed log lines — deliberately
    not authorization success/failed, which logs on every authenticated API call)
    across the full log, not just the last 500 lines.
  • check_firewall_rules.py: replaced fragile nft text-scraping with
    nft -j list ruleset (structured JSON), with nethsec.utils.get_all_by_type()
    as a UCI-level fallback if nft is unavailable — fixes a systematic rule
    undercount (79 vs real 97) caused by lines like ct state vmap {...} not being
    recognized as rules by the old text heuristic.
  • check_dhcp_leases.py: fixed a euci nested-dict bug that made DHCP pool
    detection always fail; pools now enumerated via nethsec.utils.get_all_by_type().
    Added WARNING/CRITICAL lease-usage thresholds (previously none).
  • check_firewall_traffic.py: restricted to real WAN/LAN zone devices via
    nethsec.utils.get_all_wan_devices() / get_all_lan_devices() (previously
    scanned arbitrary devices). Added rx/tx error alerting (previously hardcoded
    OK always). Fixed the same /proc/net/dev padding bug as wan_throughput.
  • check_vpn_tunnels.py: OpenVPN client count via
    nethsec.ovpn.list_connected_clients() (replacing a broken CSV heuristic that
    miscounted the openvpn-status header line as a connected client). WireGuard
    total/active counts now both peer-level via nethsec.inventory.fact_wireguard()
    plus handshake-freshness for "active".
  • check_ovpn_host2net.py: same nethsec.ovpn.list_connected_clients() fix as
    check_vpn_tunnels.py, scoped to host2net instances via
    nethsec.utils.get_all_by_type().
  • check_apk_packages.py: updates_available was a dead constant — now calls
    nethsec.inventory.info_package_updates_available(). Installed-package count via
    stable apk info instead of raw package-index-file parsing.
  • check_dns_resolution.py: now sends a raw UDP DNS query directly to
    127.0.0.1:53 (the local resolver) instead of going through the system resolver
    via socket.getaddrinfo(). Added the documented 500ms WARNING tier.
  • check_firewall_connections.py: sysctl reads wrapped in try/except
    (previously could crash with a raw traceback on an unreadable/malformed value).

Behavior change: check_dns_resolution.py, check_dhcp_leases.py, and
check_firewall_traffic.py can now alert where they previously never did
(dead/hardcoded-OK thresholds replaced with real ones).

Testing

Unit tests

$ cd script-check-nsec8 && python3 -m pytest tests/ -q
........................................................................ [ 66%]
....................................                                     [100%]
108 passed in 0.29s

Live-verify — nsec8-test (NethSecurity 8.8.0-dev, dual-WAN: tim_fibra/eth1 + vodafone_adsl/eth2)

All 11 modified full/ checks run clean (exit 0), one full pass:

$ python3 check_apk_packages.py
0 APK.Packages - OK - ~602 packages | installed=602 updates_available=0 overlay_free_kb=178952 overlay_used_pct=21 last_update_age_days=0 recent_installs=1 recent_removes=0

$ python3 check_dhcp_leases.py
0 DHCP.Leases - No active DHCP pool found          # correct: no LAN DHCP pool configured on this lab host

$ python3 check_dns_resolution.py
0 DNS.Resolution response_time=18ms;500;1000|successful=3|failed=0|total=3 Test: 3/3 OK, avg time: 18ms - OK

$ python3 check_firewall_connections.py
0 Firewall.Connections connections=86;52428;58982;0;65536|percent=0;80;90;0;100 Active connections: 86/65536 (0%) - OK

$ python3 check_firewall_rules.py
0 Firewall.Rules tables=3|chains=48|rules=95 OK - 3 tables, 48 chains, 95 rules (nft)

$ python3 check_firewall_traffic.py
0 eth0.Traffic rx_bytes=153796572|tx_bytes=20043769|... - OK
0 eth1.Traffic rx_bytes=138735658|tx_bytes=10716849|... - OK
0 eth2.Traffic rx_bytes=127717031|tx_bytes=3440040|... - OK

$ python3 check_ovpn_host2net.py
0 OVPN.HostToNet - OpenVPN not configured or not running   # correct: no host2net instances on this host

$ python3 check_root_access.py
0 Root.Access sessions=1;5;10;0|logins=8|failed=0;5;10;0|unique_ips=3 login_state=passed - OK - login_state=passed, Logins: 8, Sessions: 1

$ python3 check_vpn_tunnels.py
0 VPN.Tunnels total=0|active=0|inactive=0 No VPN configured   # correct: no OpenVPN/WireGuard on this host

check_root_access.py's 8 detected logins were verified against the raw log to
confirm the fix actually covers all 3 sources it claims to (not just SSH):

root login on 'ttyS0'                                            # local console
authentication success for user root from 192.168.10.189         # web UI (nethsecurity-api)
Password auth succeeded for 'root' from 192.168.10.189:56025      # SSH (dropbear)
Pubkey auth succeeded for 'root' with ssh-ed25519 key ... from 192.168.10.119   # SSH (dropbear, key auth)

WAN status/throughput (baseline, fault-injection, recovery):

$ python3 check_wan_status.py
0 WAN.Interface.tim_fibra - UP
0 WAN.Status.tim_fibra - tim_fibra: UP
0 WAN.Interface.vodafone_adsl - UP
0 WAN.Status.vodafone_adsl - vodafone_adsl: UP
0 WAN.Metrics total=2|up=2|down=0|degraded=0 Total=2 Up=2 Down=0 Degraded=0

$ python3 check_wan_throughput.py   # run 1
0 WAN.Throughput.tim_fibra if_in_octets=541.47|if_out_octets=41.70 [eth1] Speed: unknown, In: 541.5 B/s, Out: 41.7 B/s
0 WAN.Throughput.vodafone_adsl if_in_octets=500.34|if_out_octets=13.77 [eth2] Speed: unknown, In: 500.3 B/s, Out: 13.8 B/s

$ sleep 3 && python3 check_wan_throughput.py   # run 2, delta confirmed over ~3s
0 WAN.Throughput.tim_fibra if_in_octets=634.38|if_out_octets=21.44 [eth1] Speed: unknown, In: 634.4 B/s, Out: 21.4 B/s
0 WAN.Throughput.vodafone_adsl if_in_octets=625.70|if_out_octets=11.61 [eth2] Speed: unknown, In: 625.7 B/s, Out: 11.6 B/s

ethtool eth1/eth2 confirms Speed: Unknown! on this virtual lab NIC — the
"unknown speed, no %-threshold" fallback path is exercised as designed.

$ ubus call network.interface.vodafone_adsl down
$ python3 check_wan_status.py
0 WAN.Interface.tim_fibra - UP
0 WAN.Status.tim_fibra - tim_fibra: UP
2 WAN.Interface.vodafone_adsl - DOWN
2 WAN.Status.vodafone_adsl - vodafone_adsl: DOWN
0 WAN.Metrics total=2|up=1|down=1|degraded=0 Total=2 Up=1 Down=1 Degraded=0

$ python3 check_wan_throughput.py
0 WAN.Throughput.tim_fibra if_in_octets=408.26|if_out_octets=44.48 [eth1] Speed: unknown, In: 408.3 B/s, Out: 44.5 B/s
0 WAN.Throughput.vodafone_adsl if_in_octets=364.21|if_out_octets=22.87 [eth2] Speed: unknown, In: 364.2 B/s, Out: 22.9 B/s

$ ubus call network.interface.vodafone_adsl up   # restored

Note: throughput counters for eth2 stay non-zero while the interface is
administratively down (residual L2 traffic) — expected, since this script
measures raw device byte counters, not WAN link state.

v1.7.5

Choose a tag to compare

@Coverup20 Coverup20 released this 17 Jul 14:57

Full Changelog: v1.7.4...v1.7.5

v1.7.4 - NethSecurity 8.8 APK local checks production fix

Choose a tag to compare

@Coverup20 Coverup20 released this 09 Jul 15:44

Production Fix for NethSecurity 8.8 CheckMK Local Checks

This is a bugfix release for v1.7.3. The previous v1.7.3 tag contained an incomplete refactor.

What's Fixed

v1.7.4 contains the production-ready promotion of NethSecurity 8.8 CheckMK local checks from beta to full production set:

  • ✅ Replace OPKG package monitoring with APK package monitoring
  • ✅ Remove [beta] markers from production local check output
  • ✅ Remove obsolete beta differences documentation
  • ✅ Fix Firewall.Rules nft/fw4/UCI detection and parsing
  • ✅ Review and adjust Root.Access thresholds and behavior
  • ✅ Update README with production packaging expectations

Validation

Manually validated on NethSecurity 8.8.0-dev.139 with CheckMK Agent 2.5.0-r1. All 12 production scripts execute without errors.

Next Steps

Users running v1.7.3 should upgrade to v1.7.4 for the correct implementation.

v1.7.3

Choose a tag to compare

@Coverup20 Coverup20 released this 08 Jul 12:27

Summary

This release refines the NethSecurity Checkmk local-check source layout.

Changes

  • Move non-packaged checks out of script-check-nsec8/full/.
  • Move check_martian_packets.py to script-check-nsec8/beta/.
  • Move check_opkg_packages.py to script-check-nsec8/beta/.
  • Move review_compare_outputs.py to script-check-nsec8/beta/.
  • Keep script-check-nsec8/full/ limited to checks intended for the NethSecurity ns-checkmk-utils package.

NethSecurity impact

NethSecurity should update ns-checkmk-utils to v1.7.3 and align packages/ns-checkmk-utils/Makefile with the new script-check-nsec8/full/ inventory.

Expected Makefile changes:

  • set PKG_VERSION:=1.7.3
  • add check_apk_packages.py
  • remove check_martian_packets.py
  • remove check_opkg_packages.py
  • refresh all HASH values against tag v1.7.3.

v1.7.1 - promote pyuci beta checks to full

Choose a tag to compare

@Coverup20 Coverup20 released this 07 Jul 14:55

Promoted:

• 14 pyuci-based NethSecurity 8.8 checks promoted from beta/ to full/ (zero subprocess, zero shell=True, UCI read-only via pyuci)
• All scripts validated: syntax OK, no unsafe command execution, proper failure handling

Removed:

• script-check-nsec8/full/beta/ directory (scripts promoted, directory removed)

Added:

• review_compare_outputs.py: tool to compare original vs beta check outputs
• REVIEW-BETA-DIFFERENCES.md: full review documentation
• README.md: beta documentation

v1.7.0 - Checkmk agent sync tool and systemd templates

Choose a tag to compare

@Coverup20 Coverup20 released this 07 Jul 14:55

v1.7.0

Added

  • Added checkmk-agent-sync.py, a dedicated Checkmk agent synchronization tool.
  • Added optional systemd service and timer templates for future controlled agent synchronization.
  • Added environment configuration example for the agent-sync service.
  • Added docs/PENDING_RELEASE.md to track pushed but unreleased work.

Agent sync tool

The new tool is available at:

  • script-tools/full/agent_maintenance/checkmk-agent-sync.py

It is designed to compare the locally installed Checkmk agent version with the agent package exposed by a configured Checkmk site.

Supported behavior includes:

  • verify-only mode by default;
  • dry-run mode with no system modifications;
  • target detection for Debian/Ubuntu, RHEL-like systems, NethSecurity 8, and NS8 container scenarios;
  • structured status reporting;
  • package version comparison;
  • optional install mode for controlled future use.

Systemd templates

The release includes templates only:

  • script-tools/full/agent_maintenance/checkmk-agent-sync.service
  • script-tools/full/agent_maintenance/checkmk-agent-sync.timer
  • script-tools/full/agent_maintenance/checkmk-agent-sync.env.example

These templates are not installed or enabled automatically.

Validation

Validation already performed before release:

  • syntax validation passed;
  • help output validation passed;
  • dry-run validation passed;
  • verify-only default behavior confirmed;
  • download-only test passed;
  • autosync verified on reachable Checkmk servers;
  • dry-run executed from /opt/checkmk-tools on staging;
  • no package installation occurred;
  • no systemd service or timer was enabled;
  • production was checked read-only only.

Reachable server sync status before release:

  • checkmk-vps-02: synced and staging dry-run tested;
  • srv-monitoring-us: synced, read-only verification only;
  • srv-monitoring-sp: synced, read-only verification only;
  • checkmk-z1-00: not verified because unreachable from the current environment.

Operational note

This release makes the tool available in the repository.

It does not activate automatic agent synchronization on any server.

Installing/enabling the service and timer remains a separate manual operation requiring explicit approval.

v1.2.9 - notification-limiter-report time-of-day recurrence insights

Choose a tag to compare

@Coverup20 Coverup20 released this 07 Jul 14:55

Added:

• notification-limiter-report.py v1.2.9: --pattern-history-days N (default 7, range 1-30) — read-only historical log lookback for time-of-day recurrence analysis in section 9.6
• Section 9.6 rewritten as "Time-of-Day Recurrence Insights" with confirmed recurring patterns, candidate observations, confidence levels (high/medium/low), and cautious interpretation language
• No persistent state, no HistoryStore, no --history-file, no Section 11

Changed:

• ReportEngine accepts pattern_engine parameter for cross-period execution comparison
• Pattern history period computed as report_end - pattern_history_days to report_end

auto-git-sync v1.2.8

Choose a tag to compare

@Coverup20 Coverup20 released this 07 Jul 14:55

fix(sync): persist release tag fetching in installer templates

notification-limiter-report v1.2.7

Choose a tag to compare

@Coverup20 Coverup20 released this 07 Jul 14:54

feat(notifications): report v1.2.7 - add recurring pattern analysis