-
Type:
New Feature Request
-
Resolution: Unresolved
-
Priority:
Medium
-
None
-
Affects Version/s: 7.0.26
-
Component/s: Agent2 (G)
-
None
Problem
On Debian-based (dpkg) systems, the Zabbix agent's built-in software inventory
items silently omit packages whose dpkg selection state is hold. A package
pinned with apt-mark hold remains installed and running, yet its version
cannot be collected through any built-in item. This produces version drift and
inventory blind spots for exactly the packages an operator has most deliberately
frozen.
Current behavior (root cause)
The filtering is identical across both agents (Zabbix agent / C and Zabbix
agent 2 / Go), in two separate code paths, and is consistent across release
branches.
Zabbix agent (C) – src/libs/zbxsysinfo/linux/software.c
- system.sw.packages runs dpkg --get-selections. Parser dpkg_list
(named dpkg_parser in 6.0) accepts a line only when the selection state is
exactly install (strcmp(tmp, "install")). Lines with state hold are
dropped. - system.sw.packages.get runs
LC_ALL=C dpkg-query -W -f='${Status},${Package},${Version},${Architecture},${Installed-Size}\n'.
Parser dpkg_details accepts a package only when the status is exactly
install ok installed (strcmp(status, "install ok installed")). A held
package reports hold ok installed and is excluded.
Zabbix agent 2 (Go) – src/go/plugins/system/sw/sw_linux.go
- dpkgList: split[len(split)-1] != "install" – same selection-state filter.
- dpkgDetails: split[0] != "install ok installed" – same status filter.
Verified on release/6.0, release/7.0 and master for the C agent, and
on release/7.0 and master for agent 2.
Note: the dpkg-query command used by .get already captures ${Status},
whose first token is the selection state (e.g. hold). The information needed
to report held packages is therefore already fetched – it is discarded at the
parser stage. No additional command or query is required.
Steps to reproduce
- Pick an installed package and hold it: apt-mark hold <package>
- Query the item in agent test mode:
zabbix_agentd -t system.sw.packages.get # or, for agent 2: zabbix_agent2 -t system.sw.packages.get - Observe: the held package is absent from the JSON output, while
dpkg -l <package> still lists it as installed (state hi).
Expected behavior
Version information for held-but-installed packages should be collectible through
a built-in agent item, without resorting to system.run or UserParameter.
Proposed solution (backward-compatible)
The proposal is intentionally scoped to system.sw.packages.get (the structured
JSON item). The legacy flat system.sw.packages is documented above only for
completeness; it has no structured field to carry state and is not the target.
Two additive changes, neither altering existing default output:
- Expose a per-package selection field in the JSON (suggested name selection:
install / hold / deinstall / ...), sourced from the ${Status}
token already captured, or from ${db:Status-Want}. selection is suggested
over status to avoid collision with dpkg's own "status" token (installed /
config-files / ...). - Include held (and, if desired, other non-install) packages only when
explicitly requested via a new opt-in parameter/flag. Default behavior stays
exactly as today.
Rationale for opt-in rather than default inclusion: adding held packages
unconditionally would change current output (new entries appear), which can break
users who diff or count the returned package set. Gating inclusion behind an
explicit flag preserves backward compatibility for every existing user.
Exact implementation (field name, flag syntax) is left to the Zabbix team;
several reasonable approaches exist.
Use case
apt-mark hold is a standard mechanism to prevent automatic upgrade or
replacement of a package from distribution repositories when a different source of
truth manages it. Such packages are installed and in production, so their versions
are precisely what an operator wants under monitoring – for example, to alert
when a held package drifts from an approved baseline version across a fleet.
Because these are the packages most deliberately frozen, the current blind spot
affects the highest-value inventory targets.
system.run and UserParameter are not viable in many environments (remote/
flexible keys disabled for security posture, plus the maintenance and
attack-surface cost of custom scripts at scale), which is why a built-in solution
is needed.
Affected versions
Behavior verified on release/6.0, release/7.0 and master.
Backward compatibility
The default output of both system.sw.packages and system.sw.packages.get
must remain unchanged. All new behavior – inclusion of held/non-install packages
and any new JSON field – must be opt-in only.