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。

配置 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,这种情况下你需要先找出实际的值。

然后你可以逐项查看列表,直到找到你想监控的字符串,例如: 如果你想监控交换机端口 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 接口:

  1. 输入 IP 地址/DNS 名称和端口号。
  2. 从下拉菜单中选择 SNMP 版本。
  3. 根据所选的 SNMP 版本添加接口凭据:
    • SNMPv1、v2 只需要 community(通常为 'public')。
    • SNMPv3 需要更具体的选项;请参见 SNMPv3。
  4. 为 原生 SNMP 批量请求(GetBulkRequest-PDUs)指定最大重复值(默认值:10);仅适用于 SNMPv2 和 v3 中的 discovery[] 和 walk[] 监控项。 请注意,将此值设置得过高可能会导致 SNMP agent 检查超时。
  5. 勾选 使用组合请求 复选框,以允许对 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 也发生更改,则所有参数都会立即更新。

您可以使用提供的某个 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+,请使用以下任一方法:

  1. 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),默认情况下可能未安装。

  1. 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 收集的信息自行创建监控项,因此请点击创建监控项。

在新的监控项表单中填写必填参数:

参数 描述
名称 输入监控项名称。
类型 在此选择 SNMP agent。
键值 输入具有明确含义的键值。
主机接口 确保选择 SNMP 接口,例如交换机或路由器的 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 次(例如,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 次(例如,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

通用示例:

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 监控项都会安排在同一时间进行查询。 前两种监控项由轮询器以每批最多 128 个监控项的方式获取,而低级别发现规则仍像以前一样单独处理。

在较低层级,查询值时会执行两种操作:获取多个指定对象,以及遍历 OID 树。

对于“获取”操作,会使用最多包含 128 个变量绑定的 GetRequest-PDU。 对于“遍历”操作,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 数据包丢失,而不是设备的限制。

但是,如果设备由于其他原因无法正确处理组合请求,并且上述启发式方法不起作用,则每个接口都有一个“使用组合请求”设置,可以通过该设置为设备禁用组合请求。

如果组合请求导致部分响应或格式错误的响应,从而造成每秒(增量)计算不正确(例如,接口计数器出现表面上的尖峰),请为受影响的接口禁用使用组合请求,以强制执行单独的逐监控项查询;这通常可以防止错误尖峰。 或者,可以考虑使用异步 get[] 或 walk[] 监控项。这些监控项会异步执行,不受每个接口的使用组合请求批处理限制约束,因此可以替代传统的同步 OID 检查,以避免与组合请求相关的问题。 请查找类似概述部分中所示内容的服务器/proxy 日志条目,以帮助识别受影响的设备。

此外,如果接口经常变为不可用,可能需要增加 Zabbix 服务器或 Zabbix proxy配置文件中的 UnavailableDelay 参数,以降低请求频率。 如果在发现或 OID 遍历期间接收到部分数据,监控项可能会变为不受支持。