3 SNMP trap

概述

接收 SNMP trap 与查询启用 SNMP 的设备正好相反。

在这种情况下,信息由启用 SNMP 的设备发送到 snmptrapd,并由 Zabbix 服务器或 Zabbix proxy 从文件中收集或“捕获”。

通常,trap 会在某些条件发生变化时发送,agent 会通过 162 端口连接到服务器(与 agent 侧用于查询的 161 端口相对)。使用 trap 可以检测到一些发生在查询间隔期间的短暂问题,而这些问题可能会被查询数据遗漏。

Zabbix 中接收 SNMP trap 的设计是与 snmptrapd 以及将 trap 传递给 Zabbix 的一种机制配合使用—— 可以是 Bash 或 Perl 脚本,也可以是 SNMPTT。

在配置好 Zabbix 之后,设置 trap 监控的最简单方法 是使用 Bash 脚本方案,因为 Perl 和 SNMPTT 在现代发行版中通常 并未安装,而且需要更复杂的配置。 但是,此方案使用配置为 traphandle 的脚本。 为了在生产系统中获得更好的性能,请使用嵌入式 Perl 方案 (即带有 do perl 选项的脚本或 SNMPTT)。

接收 trap 的工作流程:

  1. snmptrapd 接收 trap
  2. snmptrapd 将 trap 传递给接收脚本(Bash、Perl) 或 SNMPTT
  3. 接收器解析、格式化并将 trap 写入 文件
  4. Zabbix SNMP trapper 读取并解析 trap 文件
  5. 对于每个 trap,Zabbix 会查找所有“SNMP trapper”监控项,这些监控项的主机 接口与接收到的 trap 地址相匹配。请注意,在匹配期间仅使用主机接口中 选定的“IP”或“DNS”。
  6. 对于找到的每个监控项,会将 trap 与 snmptrap[regexp] 中的正则表达式进行比较。trap 会被设置为所有 匹配监控项的值。如果未找到匹配的监控项,并且存在 snmptrap.fallback 监控项,则 trap 会被设置为该监控项的值。
  7. 如果 trap 未被设置为任何监控项的值,Zabbix 默认会 记录未匹配的 trap。(可通过 Administration > General > Other 中的“Log unmatched SNMP traps”进行配置。)
HA 故障转移注意事项

在高可用性(HA)节点切换期间,Zabbix 将在最后一个 ISO 8601 时间戳内的最后一条记录之后继续处理;如果未找到相同的记录,则仅使用时间戳来识别最后位置。

配置 SNMP trap

此监控项类型需要以下前端配置。

1. 为您的主机创建一个 SNMP 接口

  • Data collection > Hosts 中,创建/编辑主机,并在 Interfaces 字段中添加类型为 “SNMP” 的接口,指定 IP 或 DNS 地址。

    每个接收到的 trap 的地址都会与所有 SNMP 接口的 IP 和 DNS 地址进行比较,以找到对应的主机。

2. 配置监控项

  • Data collection > Hosts 中,创建/编辑所需的监控项。
  • Key 字段中,使用以下 SNMP trap 键之一:
Key
Description Return value Comments
snmptrap[regexp]
捕获所有与 regexp 中指定的正则表达式匹配的 SNMP trap。如果未指定 regexp,则捕获任意 trap。 SNMP trap 此监控项只能为 SNMP 接口设置。
此监控项键的参数支持用户宏和全局正则表达式。
snmptrap.fallback
捕获该接口上所有未被任何 snmptrap[] 监控项捕获的 SNMP trap。 SNMP trap 此监控项只能为 SNMP 接口设置。

当前暂不支持多行正则表达式匹配。

  • Type of information 设置为 “Log” 以解析时间戳。也可以接受 “Numeric” 等其他格式,但可能需要自定义 trap 处理程序。

设置SNMP trap监控

配置 Zabbix 服务器/proxy

要读取 trap,必须配置 Zabbix 服务器或 proxy 以启动 SNMP trapper 进程,并指向由 SNMPTT 或 Bash/Perl trap 接收器写入的 trap 文件。为此,请编辑配置文件 (zabbix_server.confzabbix_proxy.conf):

StartSNMPTrapper=1
SNMPTrapperFile=[TRAP FILE]

如果使用了 systemd 参数 PrivateTmp ,则此文件很可能无法在 /tmp 中正常工作。

配置 Bash trap 接收器

要求:仅 snmptrapd。

可以使用 Bash trap 接收器 脚本,通过 trapper 文件将 trap 从 snmptrapd 传递给 Zabbix 服务器。要进行配置,请将 traphandle 选项添加到 snmptrapd 配置文件 (snmptrapd.conf) 中, 请参见示例

snmptrapd 可能需要重启才能使其配置更改生效。

配置 Perl trap 接收器

要求:Perl,使用 --enable-embedded-perl 编译的 Net-SNMP(自 Net-SNMP 5.4 起默认完成)

Perl 陷阱接收器(查找misc/snmptrap/zabbix_trap_receiver.pl) 可用于将陷阱直接从 snmptrapd 传递到 Zabbix 服务器。 配置它:

  • 将 Perl 脚本添加到 snmptrapd 配置文件(snmptrapd.conf)中,例如:
perl do "[FULL PATH TO PERL RECEIVER SCRIPT]";
  • 配置接收器,例如:
$SNMPTrapperFile = '[TRAP FILE]';
$DateTimeFormat = '[DATE TIME FORMAT]';

snmptrapd 可能需要重新启动才能使配置更改生效。

如果没有引用脚本名称,snmptrapd 将拒绝启动并显示消息,类似于这些:

Regexp modifiers "/l" and "/a" are mutually exclusive at (eval 2) line 1, at end of line
Regexp modifier "/l" may not appear twice at (eval 2) line 1, at end of line
配置 SNMPTT

首先,snmptrapd 应该配置为使用 SNMPTT。

为获得最佳性能,SNMPTT 应配置使用 snmptthandler-embedded 将陷阱传递给它的守护进程。请参阅 配置 SNMPTT 的说明。

当 SNMPTT 配置为接收陷阱时,配置 snmptt.ini

  1. 启用 NET-SNMP 包中的 Perl 模块:
net_snmp_perl_enable = 1
  1. 将陷阱记录到 Zabbix 将读取的陷阱文件中:
log_enable = 1
log_file = [TRAP FILE]
  1. 设置日期时间格式:
date_time_format = %Y-%m-%dT%H:%M:%S%z

“net-snmp-perl”包已在RHEL 8.0-8.2被移除;但在 RHEL 8.3 中重新添加。有关详细信息,请参阅已知问题

现在格式化陷阱以便 Zabbix 识别它们(编辑 snmptt.conf):

  1. 每个FORMAT格式化语句应以“ZBXTRAP [address]”开头,其中[address] 将与 Zabbix 上 SNMP 接口的 IP 和 DNS 地址进行比较。例如::
EVENT coldStart .1.3.6.1.6.3.1.1.5.1 "Status Events" Normal
FORMAT ZBXTRAP $aA Device reinitialized (coldStart)
  1. 在下面查看更多关于 SNMP 陷阱格式的信息

不要使用未知的陷阱 - Zabbix 将无法识别它们。 可以通过在 snmptt.conf 中定义一般事件来处理未知陷阱:

EVENT general .* "General event" Normal
SNMP 陷阱格式

所有自定义的 Perl 陷阱接收器和 SNMPTT 陷阱配置必须按以下方式格式化陷阱:

[timestamp] [the trap, part 1] ZBXTRAP [address] [the trap, part 2]

在哪里

  • [timestamp] - “%Y-%m-%dT%H:%M:%S%z”格式的时间戳
  • ZBXTRAP - 头表示一个新的陷阱从这一行开始
  • [address] - 用于查找此trap的主机的 IP 地址

请注意,“ZBXTRAP”和“[address]”将在处理过程中从消息中删除。 如果陷阱以其他方式格式化,Zabbix 可能会意外地解析陷阱。

trap示例:

2024-01-11T15:28:47+0200 .1.3.6.1.6.3.1.1.5.3 Normal "Status Events" localhost - ZBXTRAP 192.168.1.1 Link down on interface 2. Admin state: 1. Operational state: 2

这将导致 IP=192.168.1.1 的 SNMP 接口出现以下陷阱:

2024-01-11T15:28:47+0200 .1.3.6.1.6.3.1.1.5.3 Normal "Status Events"
localhost - Link down on interface 2. Admin state: 1. Operational state: 2

系统要求

建议安装 MIB 文件, 以确保监控项值以正确的格式显示。 如果没有 MIB 文件,可能会出现格式问题,例如以 HEX 而不是 UTF-8 显示值,或反之亦然。

大文件支持

Zabbix为SNMP trap文件提供了“大文件支持”。Zabbix可以读取的最大文件大小为2^63(8 EiB)。请注意,文件系统可能会对文件大小添加下限。

日志轮转

Zabbix 不提供任何日志轮转系统——这应由用户处理。日志轮转应先重命名旧文件,之后再删除它,以确保不会丢失任何 trap:\

  1. Zabbix 在最后已知位置打开 trap 文件,并转到步骤 3
  2. Zabbix 通过将当前已打开文件的 inode 编号与已定义 trap 文件的 inode 编号进行比较,检查该文件是否已被轮转。如果当前没有已打开的文件,Zabbix 会重置最后位置并转到步骤 1。
  3. Zabbix 从当前已打开的文件中读取数据,并设置新位置。
  4. 解析新数据。如果这是已轮转的文件,则关闭该文件并返回步骤 2。
  5. 如果没有新数据,Zabbix 将休眠 1 秒,然后返回步骤 2。
文件系统

由于 trap 文件的实现方式,Zabbix 需要文件系统支持 inode,以区分文件(该信息通过 stat() 调用获取)。

使用不同 SNMP 协议版本的设置示例

本示例使用 snmptrapd 和一个 Bash 接收脚本将 trap 传递给 Zabbix 服务器。

设置:

  1. 配置 Zabbix 启动 SNMP trapper,并 设置 trap 文件。添加到 zabbix_server.conf
StartSNMPTrapper=1
SNMPTrapperFile=/var/lib/zabbix/snmptraps/snmptraps.log
  1. 将 Bash 脚本下载到 /usr/sbin/zabbix_trap_handler.sh
curl -o /usr/sbin/zabbix_trap_handler.sh https://raw.githubusercontent.com/zabbix/zabbix-docker/trunk/Dockerfiles/snmptraps/alpine/conf/usr/sbin/zabbix_trap_handler.sh

如有必要,请调整脚本中的 ZABBIX_TRAPS_FILE 变量。若要使用默认值, 请先创建父目录:

mkdir -p /var/lib/zabbix/snmptraps
  1. 将以下内容添加到 snmtrapd.conf(请参考可用的示例
traphandle default /bin/bash /usr/sbin/zabbix_trap_handler.sh

snmptrapd 可能需要重启才能使其配置更改生效。

  1. 创建一个 SNMP 监控项 TEST(请注意初始配置要求):\

    类型:SNMP trap
    信息类型:日志 主机接口:SNMP 127.0.0.1
    键值:snmptrap["linkUp"]
    日志时间格式:yyyyMMdd.hhmmss

请注意,这里使用的是 ISO 8601 日期和时间格式。

  1. 接下来,我们将为所选的 SNMP 协议版本配置 snmptrapd, 并使用 snmptrap 工具发送测试 trap。
SNMPv1、SNMPv2

SNMPv1 和 SNMPv2 协议依赖“community string”认证。在下面的示例中, 我们将使用 "secret" 作为 community string。必须在 SNMP trap 发送端上将其设置为相同的值。

请注意,尽管 SNMPv2 仍广泛用于生产环境,但它不提供 任何加密和真正的发送方认证。数据以纯文本形式发送,因此 这些协议版本只能用于私有网络等安全环境中, 绝不能通过任何公共网络或第三方网络使用。

如今 SNMP version 1 实际上已很少使用,因为它不支持 64 位计数器, 并且被视为遗留协议。

要启用接收 SNMPv1 或 SNMPv2 trap,应将以下行添加到 snmptrapd.conf。 请将 "secret" 替换为在 SNMP trap 发送端上配置的 SNMP community string:

authCommunity log,execute,net secret

接下来,我们可以使用 snmptrap 发送一个测试 trap。在本示例中,我们将使用常见的 “link up” OID:

snmptrap -v 2c -c secret localhost '' linkUp.0
SNMPv3

SNMPv3 解决了 SNMPv1/v2 的安全问题,并提供认证和加密。 您可以使用 MD5 或多种 SHA 认证方法,以及 DES/多种 AES 作为加密算法。

要启用接收 SNMPv3,请将以下内容添加到 snmptrapd.conf

createUser -e 0x8000000001020304 traptest SHA mypassword AES
authuser log,execute traptest

请注意 "execute" 关键字,它允许对此用户安全模型执行脚本。

snmptrap -v 3 -n "" -a SHA -A mypassword -x AES -X mypassword -l authPriv -u traptest -e 0x8000000001020304 localhost 0 linkUp.0

如果您希望使用 AES192 或 AES256 等强加密方法,请使用 5.8 及以上版本的 net-snmp。您可能需要使用 configure 选项重新编译它:--enable-blumenthal-aes。 较旧版本的 net-snmp 不支持 AES192/AES256。 另请参见:Strong Authentication or Encryption

验证

在这两个示例中,您都会在 /var/lib/zabbix/snmptraps/snmptraps.log 中看到类似的内容:

2024-01-30T10:04:23+0200 ZBXTRAP 127.0.0.1
UDP: [127.0.0.1]:56585->[127.0.0.1]:162
DISMAN-EVENT-MIB::sysUpTimeInstance = 2538834
SNMPv2-MIB::snmpTrapOID.0 = IF-MIB::linkUp.0

Zabbix 中的监控项值将为:

2024-01-30 10:04:23 2024-01-30 10:04:21 

2024-01-30T10:04:21+0200 UDP: [127.0.0.1]:56585->[127.0.0.1]:162
DISMAN-EVENT-MIB::sysUpTimeInstance = 2538834
SNMPv2-MIB::snmpTrapOID.0 = IF-MIB::linkUp.0

Perl 示例:

2024-01-30T11:42:54+0200 ZBXTRAP 127.0.0.1
PDU INFO:
  receivedfrom                   UDP: [127.0.0.1]:58649->[127.0.0.1]:162
  notificationtype               TRAP
  version                        1
  community                      public
  errorstatus                    0
  transactionid                  1
  requestid                      2101882550
  messageid                      0
  errorindex                     0
VARBINDS:
  DISMAN-EVENT-MIB::sysUpTimeInstance type=67 value=Timeticks: (457671) 1:16:16.71
  SNMPv2-MIB::snmpTrapOID.0      type=6  value=OID: IF-MIB::linkUp.0

请参阅