2 SNMP代理

概览

您可能希望在打印机、网络交换机、路由器或不间断电源(UPS)等设备上使用SNMP监控,这些设备通常都支持SNMP,而在其上尝试设置完整的操作系统和Zabbix 代理(agent)是不切实际的。

为了能够从这些设备上获取由SNMP 代理(agent)提供的数据,Zabbix server 必须通过指定 --with-net-snmp MIB文件(MIB files) 来启用SNMP支持。建议还应 启用MIB解析 以确保 监控项(items) 以正确的格式显示。没有MIB文件,可能会出现 格式化问题(formatting issues),例如以HEX而非UTF-8或反之显示值。

SNMP检查仅通过UDP协议执行。

如果 Zabbix serverZabbix proxy 收到不正确的SNMP响应,它们的日志中会记录类似以下的信息:

SNMP response from host "gateway" does not contain all of the requested variable bindings

虽然这些信息并不涵盖所有问题情况,但它们对于识别应禁用组合请求的单个SNMP设备很有用。

Zabbix server/Zabbix proxy 在不成功的 SNMP请求(SNMP request) 尝试后,至少会重试一次:要么通过SNMP库的重试机制,要么通过内部的 重试机制(retry mechanism)。

如果监控SNMPv3设备,请确保 msgAuthoritativeEngineID(也称为 snmpEngineID 或“Engine ID”)在两台设备之间不共享。根据 RFC3414(第3.1.1.1节)的要求,它必须对每台设备都是唯一的。

RFC3414要求SNMPv3设备持久化其 engineBoots。有些设备并不这样做,这导致它们在重启后,其SNMP消息被视为过时而被丢弃。在这种情况下,需要在 Zabbix server 上手动清除SNMP缓存(通过使用 清除SNMP缓存)或重启 Zabbix server

配置SNMP监控

要开始通过SNMP监控设备,必须执行以下步骤:

步骤 1

找出要监控项目的SNMP字符串(或OID)。

要获取SNMP字符串列表,使用 snmpwalk 命令(作为 net-snmp 软件的一部分,该软件应作为Zabbix安装的一部分已安装)或等效工具:

snmpwalk -v 2c -c public <主机IP> .

此处的 '2c' 代表SNMP版本,你也可以用 '1' 替换它,以表明设备上的SNMP版本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 <主机IP> IF-MIB::ifHCInOctets.3

请注意,字符串中的最后一个数字是你想要监控的端口号。另请参阅:动态索引

这应该会给你类似以下的结果:

.1.3.6.1.2.1.31.1.1.1.6.3 = Counter64: 3472126941

同样,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

Create a host 对应于一个设备。

为该主机添加一个SNMP接口:

  • 输入IP地址/DNS名称和端口号
  • 从下拉菜单中选择 SNMP版本
  • 根据所选的SNMP版本添加接口凭证:
    • SNMPv1, v2仅需要社区名(通常为'public')
    • SNMPv3需要更具体的选项(见下文)
  • 指定最大重复值(默认:10)用于 native SNMP bulk requests(GetBulkRequest-PDUs);仅适用于 discovery[]walk[] 监控项 在SNMPv2和v3中。请注意,将此值设置得过高可能会导致SNMP agent 检查超时。
  • 勾选 使用组合请求 选项框以允许 combined processing 的SNMP请求(与原生SNMP批量请求“walk”和“get”无关)
SNMPv3参数 描述
Context name 输入上下文名称以识别SNMP子网上的 监控项。
在此字段中解析用户宏。
Security name 输入安全名称。
在此字段中解析用户宏。
Security level 选择安全级别:
noAuthNoPriv - 不使用任何身份验证或隐私协议
AuthNoPriv - 使用身份验证协议,不使用隐私协议
AuthPriv - 同时使用身份验证和隐私协议
Authentication protocol 选择身份验证协议 - MD5, SHA1;使用net-snmp 5.8及更高版本时,可使用 SHA224, SHA256, SHA384SHA512
Authentication passphrase 输入身份验证密码短语。
在此字段中解析用户宏。
Privacy protocol 选择隐私协议 - DES, AES128, AES192, AES256, AES192C(Cisco)或 AES256C(Cisco)。
参阅关于 privacy protocol support 的注释
Privacy passphrase 输入隐私密码短语。
在此字段中解析用户宏。

在SNMPv3凭证错误(安全名称、身份验证协议/密码短语、隐私协议)的情况下:

  • Zabbix从net-snmp接收错误,除了 Privacy passphrase 错误,此时Zabbix从net-snmp接收超时错误;
  • SNMP接口可用性将切换为红色(不可用)。

在不更改 Security name 的情况下对 Authentication protocolAuthentication passphrasePrivacy protocolPrivacy passphrase 进行的更改, 只有在 server/proxy 上的手动清除缓存(通过使用 -R snmp_cache_reload)或重启 server/proxy 后才会生效。在 Security name 也更改的情况下, 所有参数将立即更新。

您可以使用提供的SNMP模板之一,它将自动添加一组 监控项。在使用模板之前, 请验证它与主机兼容。

点击 添加 以保存主机。

隐私协议支持

根据您的操作系统和net-snmp配置,某些隐私协议可能不可用:

  • 在某些较新的操作系统(例如,RHEL9)中,net-snmp包中已弃用DES支持。

  • 加密协议AES192及更高级别默认不支持在早于RHEL 8, CentOS 8, Oracle Linux 8, Debian 12, Ubuntu LTS 22.04, openSUSE Leap 15.5的操作系统上。

要检查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 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-PDUs)异步处理。
此监控项的超时设置可以在监控项配置表单中设置。
你可以将此用作主监控项,依赖监控项从中提取数据,使用预处理。
可以在单个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],则输出是连接的列表。
GetBulk请求用于SNMPv2和v3接口,GetNext用于SNMPv1接口;批量请求的最大重复次数在接口级别配置。
最大重复次数参数影响批量请求,确定单个批量响应中返回的OID的最大数量。
较高的值会导致较大的批量响应,减少所需的传输次数。然而,并非所有设备都支持非常高的值,这可能会导致问题。
此监控项返回snmpwalk实用程序使用-Oe -Ot -On参数的输出。
你可以将此监控项用作SNMP发现中的主监控项。

get[OID] - 异步检索单个值。
例如:get[1.3.6.1.2.1.31.1.1.1.6.3]
此监控项的超时设置可以在监控项配置表单中设置。

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轮询器的数量由StartSNMPPollers参数定义。

请注意,对于任何方法返回的网络流量统计,必须在预处理选项卡中添加每秒变化步骤;否则,你将从SNMP设备获得累积值,而不是最新变化。

所有必填输入字段都标有红色星号。

现在保存监控项,然后转到监控 > 最新数据查看你的SNMP数据。

示例 1

通用示例:

Parameter 描述
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

监控运行时间:

参数 描述
OID MIB::sysUpTime.0
键值 router.uptime
值类型 浮点数
单位 运行时间
预处理步骤: 自定义乘数 0.01

本地SNMP批量请求

walk[OID1,OID2,...] 监控项允许使用本地SNMP功能进行批量请求(GetBulkRequest-PDUs),在SNMP版本2/3中可用。

SNMP中的GetBulk请求执行多个GetNext请求,并在单个响应中返回结果。这可用于常规SNMP监控项以及SNMP发现,以最小化网络往返次数。

SNMP walk[OID1,OID2,...] 监控项可用作主监控项,它在单个请求中收集数据,依赖的监控项根据需要使用预处理解析响应。

请注意,使用本地SNMP批量请求与组合SNMP请求的选项无关,这是Zabbix自己的方式来组合多个SNMP请求(参见下一部分)。

如果其中一个数据包丢失,将为SNMP批量监控项进行重试,以避免失败。SNMP监控项的getwalk的超时时间设置为整个会话。如果达到超时时间,则将重试一次,超时时间将被重置,最后一个请求将被重新发送,允许在单个数据包丢失或到达太晚的情况下,从最后一个请求继续会话。

Zabbix内部处理机制

Zabbix server 和 proxy 可以在单次请求中向 SNMP 设备查询 多个值。这影响了以下几种类型的 SNMP 监控项:

所有在单一接口上参数相同的 SNMP 监控项都被 安排在同一时间查询。前两种类型的监控项由轮询器以最多 128 项的批次处理,而低级自动发现规则则像以前一样单独处理。

在较低级别,执行两种类型的查询值操作:获取多个指定对象和遍历 OID 树。

对于“获取”,使用带有最多 128 个变量绑定的 GetRequest-PDU。对于“遍历”,使用 GetNextRequest-PDU 用于 SNMPv1,而使用带有“max-repetitions”字段最多为 128 的 GetBulkRequest 用于 SNMPv2 和 SNMPv3。

因此,对于每种 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 数据包丢失,而不是设备的限制。

然而,如果设备由于其他原因无法正确处理组合请求,且上述启发式方法不起作用,每个接口都有一个“使用组合请求” 设置,允许禁用该设备的组合请求。

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