Releases: nethesis/checkmk-tools
Release list
v1.7.7 - Remove excluded/legacy reference scripts from full/
What changed
- Removed
check_apk_packages.py,check_opkg_packages.py,check_martian_packets.pyfromscript-check-nsec8/full/- these were kept only as source reference despite never being part of thens-checkmk-utilsproduction set, which was confusing (a PR reviewer flagged them as apparently-installed-but-unused). - Updated
full/README.mdto 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
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/routeonly if the library is unavailable. Up/down state and
gateway now come fromubus call network.interface.<label> status(PPPoE runtime
device resolved via itsl3_devicefield) instead of/sys/class/net/*/operstate.
Split output intoWAN.Interface.<label>(raw interface state) and
WAN.Status.<label>(adds internet reachability viaping -I <device>against the
same host list as NethSecurity's own dashboardcheck_internet()). Gateway
TCP-probe port-80 failure no longer forces WARNING. AddedWAN.Metricsperfdata. - 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/devcolumn-padding bug that silently skipped short interface
names (eth0/eth1/eth2); service name order corrected toWAN.Throughput.<label>. - check_root_access.py: fixed a
"PPID:"vs actual"PPid:"case-sensitivity
bug in the/proc/<pid>/statusscan that made the main dropbear daemon always
count as a phantom session. Removed unverified glibcutmpstruct parsing (the
file doesn't exist on this platform). Login detection now matches 3 real sources
(SSH via dropbear, local console via busyboxlogin, web UI via
nethsecurity-api'sauthentication success/failedlog lines — deliberately
notauthorization 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
nfttext-scraping with
nft -j list ruleset(structured JSON), withnethsec.utils.get_all_by_type()
as a UCI-level fallback ifnftis unavailable — fixes a systematic rule
undercount (79 vs real 97) caused by lines likect state vmap {...}not being
recognized as rules by the old text heuristic. - check_dhcp_leases.py: fixed a
eucinested-dict bug that made DHCP pool
detection always fail; pools now enumerated vianethsec.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/devpadding bug as wan_throughput. - check_vpn_tunnels.py: OpenVPN client count via
nethsec.ovpn.list_connected_clients()(replacing a broken CSV heuristic that
miscounted theopenvpn-statusheader line as a connected client). WireGuard
total/active counts now both peer-level vianethsec.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_availablewas a dead constant — now calls
nethsec.inventory.info_package_updates_available(). Installed-package count via
stableapk infoinstead 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
viasocket.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
v1.7.4 - NethSecurity 8.8 APK local checks production fix
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
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
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
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.mdto 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.servicescript-tools/full/agent_maintenance/checkmk-agent-sync.timerscript-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-toolson 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
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
fix(sync): persist release tag fetching in installer templates
notification-limiter-report v1.2.7
feat(notifications): report v1.2.7 - add recurring pattern analysis