有时,从网络监控系统 (NMS) 到设备的加密 SNMPv3 请求会突然失败。对于这种行为没有合理的解释。在本文中,我将描述我在Zabbix中遇到的问题,推测原因,并提出解决方法(或解决方案,如果您愿意)。它对我有用,但我不确定我是否真的发现了真正的问题。至少它解决了Zabbix服务器和受监视设备显示一些真正奇怪行为的问题。但问题不仅发生在Zabbix NMS中,而且我也注意到它在CA的Spectrum系统中。
SNMPv3
在10年多的时间里,SNMPv3是唯一有效的SNMP标准。SNMPv1 和 v2c 等较旧版本被认为已过时,尽管这些版本仍用于管理网络中的大多数设备。
SNMPv3 为基于用户的安全模型 (usm) 和 View 访问控制模型 (vacm) 提供了一个完整的框架,以限制经过身份验证的用户有权查看的信息。当然,从管理器到代理的所有请求都可以进行身份验证,并在需要时进行加密。在大多数设计中,对内部网络内部的监控流量进行身份验证就足够了,但如果流量通过外部网络(即互联网),则也应该对其进行加密。SNMPv3提供了所有这些选项。
引擎标识
每个 SNMPv3 实体都有自己的 ID,即所谓的 engineID。对于代理在其中操作的每个上下文,它都是一个唯一的数字。但在大多数设备上,只有一个 SNMP 代理运行,因此每个设备都有一个唯一的 engineID。RFC 3411 在 snmpModules.10 一节(第 40 页)中描述了引擎 ID 应如何组成。如果流量已加密,则 engineID 是算法的一部分,因此所有设备的数据加密方式都不同。
由于管理器最初不知道受管设备上代理的引擎 ID,因此 RFC 5343 描述了一种初始发现引擎 ID 的方法。
重放保护
SNMPv3 标准还保护通信免受重放攻击,当攻击者记录数据包并在以后再次将其发送到目标站以引发某种反应时。为了实现该目标,管理器首先询问代理它已经重新启动了多少次(snmpEngineBoots)以及上次重新启动的时间(snmpEngineTime)是多久以前的。管理中心使用引导次数和自上次引导代理以来的时间对数据进行加密。仅当程序包的时间适合传入请求的时间时,代理才能正确解密包。请注意,SNMPv3 中没有使用绝对时间参考,而是使用相对时间范围。因此,经理也可以从监视设备检索信息,即使时间在两个系统上不一致。
通信
在该行中,加密的 SNMPv3 通信如下所示:
manager -> agent: What is your engineID?
agent -> manager: My engineID is ..... My SNMP Agent restarted x times and the last time y seconds ago.
manager -> agent: What is your processor load, encrypted with the engineID, snmpEngineBoots, and snmpEngineTime.
agent -> manager: The processor load was x, encrypted with the engineID, snmpEngineBoots, and snmpEngineTime.
如您所见,有关引擎ID,snmpEngineBoots或snmpEngineTime的解释的任何问题对于加密通信都是致命的。
扎比克斯
Zabbix是一个利用SNMP协议的监控系统。当然,您可以使用协议的版本3。在Zabbix中,您只需要配置SNMP用户,身份验证密码和加密密码即可。用户名和密码短语可以在主机定义中配置为宏。使用这些宏可以更轻松地为可能具有不同参数的主机重用模板。
症状
当您意识到突然一个设备没有从Zabbix系统重新发送到加密的SNMPv3请求时,问题就开始了。从监视主机的命令行使用 snmpget 或 snmpwalk 检查 SNMP 配置不会显示任何问题。命令行中的所有请求都会产生正确的答案。
在下一步中,您将启动 tcpdump 以检查线路上的通信。在第一个数据包中,管理器要求代理提供其引擎 ID:
07.406643 IP (tos 0x0, ttl 53, id 0, offset 0, flags [DF], proto UDP (17), length 92)
manager.37780 > agent.161: [udp sum ok] { SNMPv3 { F=r } { USM B=0 T=0 U= }
{ ScopedPDU E= C= { GetRequest(14) R=537447614 } } }
如您所见,没有包含用户名 (U=),引导次数为零 (B=0),以及自上次引导以来的时间 (T=0)。在下一个数据包中,代理向管理器提供必要的信息:
07.408916 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 143)
agent.161 > manager.37780: [udp sum ok] { SNMPv3 { F= } { USM B=28 T=27 U= }
{ ScopedPDU E= 0x800x000x1F0x880x800x8E0xE50xD80x7B0x120x0C0x330x520x000x000x000x00
C= { Report(31) R=537447614 .1.3.6.1.6.3.15.1.1.4.0=1 } } }
它告诉 te manager 它的引擎 ID,它已经启动了 28 次,最后一次启动是 27 秒前。现在经理的行为完全奇怪。在该行上,您可以看到如下数据包:
07.427289 IP (tos 0x0, ttl 53, id 0, offset 0, flags [DF], proto UDP (17), length 177)
manager.37780 > agent.161: [udp sum ok] { SNMPv3 { F=apr } { USM B=27 T=178 U=user }
{ ScopedPDU [!scoped PDU] (encrypted data) } }
您会看到管理器要求27次启动和178秒正弦最后一次重新启动,这完全是无稽之谈。该代理报告了28次启动,不到半秒前的27秒。当然,代理商的回答是:
07.429382 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 163)
agent.161 > manager.37780: [udp sum ok] { SNMPv3 { F=a } { USM B=28 T=27 U=user }
{ ScopedPDU E= 0x800x000x1F0x880x800x8E0xE50xD80x7B0x120x0C0x330x520x000x000x000x00
C= { Report(28) R=0 .1.3.6.1.6.3.15.1.1.2.0=1 } } }
使用此 OID,代理会告诉管理中心,请求的 PDU 无法解密,因为它超出了访问的时间窗口。
正如我之前所写的,来自命令行的相同 snmp 请求可以完美地工作。此外,仅经过身份验证但未加密的 SNMP 请求也有效。我在Linux服务器上安装了Zabbix,在Windows环境中安装了Spectrum Server,看到了这种行为。在代理方面,我有一台Cisco IOS,Cisco Nexus或一台安装了net-snmp的Linux机器。
原因
似乎Zabbix服务器没有正确解释snmpEngineBoots和snmpEngineTime。但是Zabbix的开发人员向高天发誓,他们使用net-snmp的snmp库。命令行工具使用的库也相同。因此,调查似乎在这里走向了死胡同。
另一方面,Zabbix站点上有一些错误报告指向代理端的非唯一引擎ID。有关详细信息,另请参阅 ZBX-2152 错误。
治愈
Sine没有合理的解释,我试图在代理端更改引擎ID。一个
engineIDType 3
在代理的 snmpd.conf 配置文件中,将 ID 从 net-snmp random 更改为 eth0 的 MAC 地址,这确实应该以某种方式是唯一的。当然,只有在下次重新启动之后。实际上,Zabbix恢复了与代理商的沟通并收集了数据。问题解决了。
网友评论