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 响应,它们会记录类似如下的日志行:
SNMP response from host "gateway" does not contain all of the requested variable bindings
虽然这些日志不能涵盖所有有问题的情况,但它们有助于识别应禁用组合请求的个别 SNMP 设备。
对于 SNMP walk 和 get 监控项,Zabbix 服务器/proxy 最多会重试 5 次。
重试机制不适用于 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。
Zabbix 会缓存 SNMPv3 EngineID → IP 映射,并在后续检查中重用已缓存的 EngineID,而不是每次都发送探测,从而减少网络流量。 如果某个 EngineID 无法重用,则会通过带探测的重试来发现新的 EngineID。
配置 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 中的最后一个数字也是端口号。
一些最常用的 SNMP OID 会由 Zabbix 自动转换为数字表示形式。
在上面的最后一个示例中,值类型是“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 version。
- 根据所选的 SNMP 版本添加接口凭据:
- SNMPv1、v2 只需要 community(通常为 'public')。
- SNMPv3 需要更具体的选项(见下文)。
- 为 原生 SNMP bulk 请求(GetBulkRequest-PDUs)指定最大重复值(默认值:10);仅适用于 SNMPv2 和 v3 中的
discovery[]和walk[]监控项。 请注意,将此值设置得过高可能会导致 SNMP agent 检查超时。 - 勾选 Use combined requests 复选框,以允许对 SNMP 请求进行组合处理(与原生 SNMP bulk 请求 "walk" 和 "get" 无关)。
| SNMPv3 parameter | Description |
|---|---|
| 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 也发生更改,则所有参数都会立即更新。
您可以使用提供的某个 SNMP 模板,它会自动添加一组监控项。在使用模板之前,请确认它与主机兼容。
点击 Add 保存主机。
隐私协议支持
根据您的操作系统和 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,然后在重新编译 Zabbix 服务器时指定选项 --with-net-snmp=/home/user/yourcustomnetsnmp/bin/net-snmp-config。
第 3 步
创建一个用于监控的 监控项。
现在返回 Zabbix,点击你之前创建的 SNMP 主机的 Items。 根据你在创建主机时是否使用了模板,你会看到与你的主机关联的 SNMP 监控项列表,或者只是一个空列表。 这里我们假设你将根据刚刚使用 snmpwalk 和 snmpget 收集到的信息自行创建该监控项,因此请点击 Create item。
在新的监控项表单中填写必填参数:

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