3 SNMP agent
概述
您可能希望在打印机、网络交换机、路由器或 UPS 等设备上使用 SNMP 监控,这些设备通常都启用了 SNMP,而在这些设备上尝试安装完整操作系统和 Zabbix agent 并不现实。
为了能够检索这些设备上的 SNMP agent 提供的数据,Zabbix 服务器必须通过指定 --with-net-snmp 标志进行 初始配置,以启用 SNMP 支持。
建议同时 安装 MIB 文件,以确保监控项值以正确的格式显示。
如果没有 MIB 文件,可能会出现格式问题,例如将值以 HEX 而不是 UTF-8 显示,反之亦然。
SNMP 检查仅通过 UDP 协议执行。
如果 Zabbix 服务器和 proxy 守护进程收到不正确的 SNMP 响应,它们会记录类似以下内容的日志行:
来自主机 "gateway" 的 SNMP 响应不包含所有请求的变量绑定
虽然这些日志不能覆盖所有有问题的情况,但它们有助于识别应禁用组合请求的单个 SNMP 设备。
对于 SNMP walk 和 get 监控项,Zabbix 服务器/proxy 将最多重试 5 次(自 Zabbix 7.0.14 起)。
重试机制不适用于 DNS 解析失败。
对于传统 SNMP 检查(单个 OID 编号或字符串),Zabbix 服务器/proxy 在查询失败后至少会重试一次:要么通过 SNMP 库的重试机制,要么通过内部的 组合处理 机制。
如果监控 SNMPv3 设备,请确保 msgAuthoritativeEngineID(也称为 snmpEngineID 或 "Engine ID")绝不能被两台设备共享。 根据 RFC 2571(第 3.1.1.1 节),它对每台设备都必须是唯一的。
RFC3414 要求 SNMPv3 设备持久保存其 engineBoots。 某些设备并未这样做,这会导致它们在重启后,其 SNMP 消息因被视为过期而被丢弃。 在这种情况下,需要在服务器/proxy 上手动清除 SNMP 缓存(使用 -R snmp_cache_reload),或者重启服务器/proxy。
配置SNMP监控
通过 SNMP 开始监控设备时,必须执行以下步骤:
第 1 步
找出你要监控的监控项的 SNMP 字符串(或 OID)。
要获取 SNMP 字符串列表,请使用 snmpwalk 命令(它是 net-snmp 软件的一部分,你应该已在安装 Zabbix 时一并安装)或等效工具:
snmpwalk -v 2c -c public <host IP> .
由于这里的 2c 表示 SNMP 版本,你也可以将其替换为 1,以表示设备上的 SNMP Version 1。
这应该会返回一个 SNMP 字符串及其最后一个值的列表。
如果没有返回结果,则可能是 SNMP 的“community”不同于标准的 public,这种情况下你需要先找出实际的 community。
然后你可以逐项查看列表,直到找到你要监控的字符串,例如:
如果你想监控交换机端口 3 的入站字节数,可以使用这一行中的 IF-MIB::ifHCInOctets.3 字符串:
IF-MIB::ifHCInOctets.3 = Counter64: 3409739121
现在你可以使用 snmpget 命令来查找 IF-MIB::ifHCInOctets.3 的数值 OID:
snmpget -v 2c -c public -On <host IP> IF-MIB::ifHCInOctets.3
请注意,字符串中的最后一个数字是你要监控的端口号。 另请参见:动态索引。
这应该会返回类似下面的结果:
.1.3.6.1.2.1.31.1.1.1.6.3 = Counter64: 3472126941
同样,OID 中最后一个数字就是端口号。
Zabbix 会将一些最常用的 SNMP OID 自动转换为数值表示。
在上面的最后一个示例中,值类型是 "Counter64",在内部对应于 ASN_COUNTER64 类型。 支持的完整类型列表为 ASN_COUNTER、ASN_COUNTER64、ASN_UINTEGER、ASN_UNSIGNED64、ASN_INTEGER、ASN_INTEGER64、ASN_FLOAT、ASN_DOUBLE、ASN_TIMETICKS、ASN_GAUGE、ASN_IPADDRESS、ASN_OCTET_STR 和 ASN_OBJECT_ID。 这些类型大致对应于 snmpget 输出中的 "Counter32"、"Counter64"、"UInteger32"、"INTEGER"、"Float"、"Double"、"Timeticks"、"Gauge32"、"IpAddress"、"OCTET STRING"、"OBJECT IDENTIFIER",但根据是否存在显示提示,也可能显示为 "STRING"、"Hex-STRING"、"OID" 等其他形式。
第 2 步
创建主机,使其对应于某个设备。

为主机添加一个 SNMP 接口:
- 输入 IP 地址/DNS 名称和端口号。
- 从下拉列表中选择 SNMP 版本。
- 根据所选的 SNMP 版本添加接口凭据:
- SNMPv1、v2 只需要 community(通常为 'public')。
- SNMPv3 需要更具体的选项;请参见 SNMPv3。
- 为 原生 SNMP 批量请求(GetBulkRequest-PDU)指定最大重复值(默认值:10);仅适用于 SNMPv2 和 v3 中的
discovery[]和walk[]监控项。 请注意,将此值设置得过高可能会导致 SNMP agent 检查超时。 - 勾选 使用组合请求 复选框,以允许对 SNMP 请求进行组合处理(与原生 SNMP 批量请求 "walk" 和 "get" 无关)。
您可以使用提供的某个 SNMP 模板,它会自动添加一组监控项。在使用模板之前,请确认它与该主机兼容。
点击 添加 保存主机。
SNMPv3
SNMPv3 需要以下参数:
- Context name - 输入上下文名称,用于在 SNMP 子网上标识监控项。
此字段支持用户宏解析。 - Security name - 输入安全名称。
此字段支持用户宏解析。 - Security level - 选择安全级别:
- noAuthNoPriv - 不使用认证和隐私协议;
- AuthNoPriv - 使用认证协议,不使用隐私协议;
- AuthPriv - 同时使用认证和隐私协议。
- Authentication protocol - 选择认证协议:MD5、SHA1;在 net-snmp 5.8 及更新版本中,还可选择 SHA224、SHA256、SHA384 或 SHA512。
- Authentication passphrase - 输入认证口令。
此字段支持用户宏解析。 - Privacy protocol - 选择隐私协议:DES、AES128、AES192、AES256、AES192C(Cisco)或 AES256C(Cisco)。
请参阅隐私协议支持说明。 - Privacy passphrase - 输入隐私口令。
此字段支持用户宏解析。
如果 SNMPv3 凭据(安全名称、认证协议/口令、隐私协议)错误:
- Zabbix 会从 net-snmp 收到 ERROR,唯独 Privacy passphrase 错误时,Zabbix 会从 net-snmp 收到 TIMEOUT 错误。
- SNMP 接口可用性将变为红色(不可用)。
在不更改 Security name 的情况下,对 Authentication protocol、Authentication passphrase、Privacy protocol 或 Privacy passphrase 所做的更改,通常会在 Zabbix 中更新相应 SNMPv3 接口时自动应用。 如果 Security name 也发生更改,则所有参数都会立即更新。
隐私协议支持
根据您的操作系统和 net-snmp 配置,某些隐私协议可能不可用:
-
在某些较新的操作系统上(例如 RHEL9),
net-snmp包已不再支持 DES。 -
在 RHEL 8、CentOS 8、Oracle Linux 8、Debian 12、Ubuntu LTS 22.04、openSUSE Leap 15.5 之前的操作系统中,AES192 及更强的加密协议默认不受支持。
要检查 net-snmp 库是否支持 AES192+,请使用以下任一方法:
net-snmp-config:
net-snmp-config --configure-options
如果输出中包含 --enable-blumenthal-aes,则表示支持 AES192+。
请注意,net-snmp-config 是 SNMP 开发包的一部分(Debian/Ubuntu 为 libsnmp-dev,CentOS/RHEL/OL/SUSE 为 net-snmp-devel),默认情况下可能未安装。
snmpget:
snmpget -v 3 -x AES-256
如果输出中包含 Invalid privacy protocol specified after -3x flag: AES-256,则表示不支持 AES192+。
如果输出中包含 No hostname specified.,则表示不支持 AES192+。
如果您的 net-snmp 库不支持 AES192 及更高协议,请使用 --enable-blumenthal-aes 选项重新编译 net-snmp,然后使用 --with-net-snmp=/home/user/yourcustomnetsnmp/bin/net-snmp-config 选项重新编译 Zabbix 服务器。
第 3 步
创建监控项用于监控。
现在返回 Zabbix,点击你之前创建的 SNMP 主机的 监控项。 根据你在创建主机时是否使用了模板,你会看到与该主机关联的 SNMP 监控项列表,或者只是一个空列表。 我们假设你将根据刚刚使用 snmpwalk 和 snmpget 收集到的信息自行创建该监控项,因此请点击 创建监控项。
在新的监控项表单中填写必填参数:

| Parameter | Description |
|---|---|
| Name | 输入监控项名称。 |
| Type | 在此选择 SNMP agent。 |
| Key | 输入一个有意义的键值。 |
| Host interface | 确保选择 SNMP 接口,例如交换机/路由器的接口。 |
| SNMP OID | 使用受支持的格式之一输入 OID 值: walk[OID1,OID2,...] - 获取一个值子树。 例如: walk[1.3.6.1.2.1.2.2.1.2,1.3.6.1.2.1.2.2.1.3]。此选项会异步使用 原生 SNMP 批量请求(GetBulkRequest-PDU)。 该监控项的超时设置可在 监控项配置 表单中设置。若设备不可达,建议设置较低的超时值,以避免长时间延迟,因为如果前面的请求超时或失败,最多会重试 5 次(自 Zabbix 7.0.14 起)(例如,3 秒超时可能导致 15 秒等待时间)。 你可以将其用作主监控项,并通过预处理从主监控项中提取数据的依赖监控项。 可以在一次 snmp walk 中指定多个 OID,例如 walk[OID1,OID2,...],以便一次异步处理一个 OID。如果批量请求没有返回结果,则会尝试在不使用批量请求的情况下获取单条记录。 支持将 MIB 名称作为参数;因此 walk[1.3.6.1.2.1.2.2.1.2] 和 walk[ifDescr] 将返回相同的输出。如果指定了多个 OID/MIB,即 walk[ifDescr,ifType,ifPhysAddress],则输出将是一个拼接列表。SNMPv2 和 v3 接口使用 GetBulk 请求,SNMPv1 接口使用 GetNext;批量请求的最大重复次数在接口级别配置。 最大重复次数参数通过决定单个批量响应中返回的 OID 数量来影响批量请求。 较高的值会产生更大的批量响应,从而减少所需的传输次数。不过,并非所有设备都支持非常高的值,这可能会引发问题。 此监控项返回带有 -Oe -Ot -On 参数的 snmpwalk 工具输出。 你可以将此监控项用作 SNMP 发现 中的主监控项。 get[OID] - 异步获取单个值。 例如: get[1.3.6.1.2.1.31.1.1.1.6.3]该监控项的超时设置可在 监控项配置 表单中设置。若设备不可达,建议设置较低的超时值,以避免长时间延迟,因为如果前面的请求超时或失败,最多会重试 5 次(自 Zabbix 7.0.14 起)(例如,3 秒超时可能导致 15 秒等待时间)。 OID -(旧式)输入单个文本或数字 OID,以同步方式获取单个值,也可与其他值组合使用。 例如: 1.3.6.1.2.1.31.1.1.1.6.3。对于此选项,监控项检查超时时间将等于服务器 配置文件 中设置的值。 建议使用 walk[OID] 和 get[OID] 监控项以获得更好的性能。所有 walk[OID] 和 get[OID] 监控项均以异步方式执行 - 无需等待一个请求的响应后再开始其他检查。DNS 解析同样是异步的。异步检查的最大并发数为 1000(由 MaxConcurrentChecksPerPoller 定义)。异步 SNMP poller 的数量由 StartSNMPPollers 参数定义。 请注意,对于任一方法返回的网络流量统计,必须在 预处理 选项卡中添加 每秒变化 步骤;否则你得到的将是 SNMP 设备的累计值,而不是最新变化值。 |
所有必填输入字段都用红色星号标记。
现在保存该监控项,然后转到 监测 > 最新数据 查看你的 SNMP 数据。
示例1
通用示例:
| 参数 | 描述 |
|---|---|
| OID | 1.2.3.45.6.7.8.0(或.1.2.3.45.6.7.8.0) |
| Key | <用作触发器引用的唯一string> 例如:"my_param"。 |
注意:OID可以以数字或string形式给出。 但在某些情况下,string形式的OID必须转换为数字表示。 为此可以使用snmpget工具:
snmpget -On localhost public enterprises.ucdavis.memory.memTotalSwap.0
示例2
运行时间监控:
| 参数 | 描述 |
|---|---|
| OID | MIB::sysUpTime.0 |
| Key | router.uptime |
| Value type | float |
| Units | uptime |
| Preprocessing step: Custom multiplier | 0.01 |
原生SNMP批量请求
walk[OID1,OID2,...] 监控项语法允许使用SNMP 2/3版本中原生的批量请求功能(GetBulkRequest-PDU)。
SNMP中的GetBulk请求会执行多个GetNext请求并将结果合并返回。该功能既可用于常规SNMP 监控项采集,也可用于SNMP自动发现,从而减少网络往返次数。
SNMP walk[OID1,OID2,...] 监控项可作为主监控项,通过预处理让依赖的监控项按需解析批量请求的响应数据。
注意:原生SNMP批量请求与Zabbix自有的SNMP请求合并功能(参见下一节)无关。
为防止数据包丢失导致失败,SNMP批量监控项最多会重试5次(自Zabbix 7.0.14起)。使用get和walk的SNMP 监控项超时时间(在配置表单中设置)作用于整个会话。无论数据是否完整获取都会触发超时;若仅获取部分数据(例如仅成功采集多个OID中的一个),则监控项会变为"不受支持"状态并显示"Only partial data received"消息。超时后将自动重试并重置超时计时器,从最后一个请求继续会话(适用于单数据包丢失或延迟场景)。建议设置较低超时值以避免设备不可达时的长时间等待(例如3秒超时可能导致15秒等待,因为最多会进行5次重试)。
组合处理的内部机制
Zabbix server和proxy可以在单个请求中query SNMP设备的多个值。 这会影响以下几种SNMP 监控项类型:
- 常规SNMP 监控项
- 带动态索引的SNMP 监控项 with dynamic indexes
- SNMP low-level discovery rules
具有相同参数的单个接口上的所有SNMP 监控项会被安排在同一时间进行查询。 前两种类型的监控项由轮询器以最多128个监控项为一批次获取,而底层发现规则则像之前一样单独处理。
在底层,查询值时会执行两种操作:获取多个指定的objects和遍历OID树。
对于"获取"操作,使用最多包含128个变量绑定的GetRequest-PDU。 对于"遍历"操作,SNMPv1使用GetNextRequest-PDU,而SNMPv2和SNMPv3则使用带有"max-repetitions"字段(最多128)的GetBulkRequest。
因此,每种SNMP 监控项类型从组合处理中获得的好处如下所述:
- 常规SNMP 监控项受益于"获取"改进;
- 带动态索引的SNMP 监控项同时受益于"获取"和"遍历"改进:"获取"用于索引验证,"遍历"用于构建缓存;
- SNMP底层发现规则受益于"遍历"改进。
然而,存在一个技术问题:并非所有设备都能在每个请求中返回128个值。 有些设备总是返回正确的响应,但其他设备要么返回"tooBig(1)"错误,要么在潜在响应超过某个限制时根本不响应。
为了找到给定设备要query的objects的最佳数量,Zabbix采用以下策略。 它谨慎地从每个请求查询1个值开始。 如果成功,则在下一个请求中queries2个值。 如果再次成功,则在下一个请求中queries3个值,并类似地继续将查询的objects数量乘以1.5,产生以下请求大小序列:1, 2, 3, 4, 6, 9, 13, 19, 28, 42, 63, 94, 128。
然而,一旦设备拒绝提供正确的响应(例如,对于42个变量),Zabbix会做两件事。
首先,对于当前的监控项批次,它将单个请求中的objects数量减半,并queries21个变量。 如果设备正常运行,那么query在绝大多数情况下应该有效,因为已知28个变量可以工作,而21个明显少于这个数字。 然而,如果仍然失败,Zabbix会回退到逐个查询值。 如果此时仍然失败,则设备肯定没有响应,请求大小不是问题。
Zabbix对后续监控项批次做的第二件事是,从最后一个成功的变量数量(在我们的例子中是28)开始,并继续将请求大小递增1,直到达到限制。 例如,假设最大响应大小为32个变量,则后续请求的大小将为29、30、31、32和33。 最后一个请求将失败,Zabbix将永远不会再次问题大小为33的请求。 从那时起,Zabbix将为此设备query最多32个变量。
如果大量queries在这个变量数量下失败,可能意味着两种情况之一。 设备用于限制响应大小的确切标准无法得知,但我们尝试使用变量数量来近似。 因此,第一种可能性是,这个变量数量大约处于设备实际响应大小限制的一般情况下:有时响应小于限制,有时大于限制。 第二种可能性是,任一方向的UDP数据包丢失。 出于这些原因,如果Zabbix获得一个失败的query,它会减少最大变量数量,以尝试get进入设备更舒适的范围,但最多减少两次。
在上面的例子中,如果带有32个变量的query失败,Zabbix会将数量减少到31。 如果这也失败,Zabbix会将数量减少到30。 然而,Zabbix不会将数量减少到30以下,因为它会假设进一步的失败是由于UDP数据包丢失,而不是设备的限制。
然而,如果设备由于其他原因无法正确处理组合请求,并且上述启发式方法不起作用,每个接口都有一个"使用组合请求"设置,可以禁用该设备的组合请求。
如果组合请求导致部分或格式错误的响应,从而导致不正确的每秒(增量)计算(例如,接口计数器中的明显峰值),请为受影响的接口禁用使用组合请求,以强制每个监控项单独queries;这通常可以防止虚假峰值。
或者,考虑使用异步get[]或walk[] 监控项,它们是异步执行的,不受每个接口使用组合请求批处理的限制——它们可以用来替代传统的同步OID检查,以避免与组合请求相关的问题。
查找类似于概述部分中显示的server/proxy日志条目,以帮助识别受影响的设备。
此外,如果接口频繁变得不可用,可能需要增加unavailabledelay或unavailabledelay配置文件中的UnavailableDelay参数以减少请求频率。
如果在发现或OID遍历期间接收到部分数据,监控项可能会变得不受支持。