[comment]: # translation:outdated

[comment]: # ({f40368a0-622befb9})
# 4 SNMP trap

[comment]: # ({/f40368a0-622befb9})

[comment]: # ({d14ae1e6-ff07904b})
#### 概述

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

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

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

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

::: noteclassic
在配置好 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”进行配置。）

[comment]: # ({/d14ae1e6-ff07904b})

[comment]: # ({3b1ff1a9-657fb528})
#####HA 故障转移注意事项

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

[comment]: # ({/3b1ff1a9-657fb528})

[comment]: # ({4c8b1bcc-a8df124c})
#### 配置 SNMP trap

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

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

-   在 *Data collection > Hosts* 中，创建/编辑主机，并在 *Interfaces* 字段中添加类型为 “SNMP” 的接口，指定 IP 或 DNS 地址。<br><br>每个接收到的 trap 的地址都会与所有 SNMP 接口的 IP 和 DNS 地址进行比较，以找到对应的主机。

2\. 配置监控项

-   在 *Data collection > Hosts* 中，创建/编辑所需的监控项。
-   在 *Key* 字段中，使用以下 SNMP trap 键之一：

|Key|<|<|
|--|--|------|
|Description|Return value|Comments|
|**snmptrap**\[regexp\]|<|<|
|捕获所有与 **regexp** 中指定的[正则表达式](/manual/regular_expressions)匹配的 SNMP trap。如果未指定 regexp，则捕获任意 trap。|SNMP trap|此监控项只能为 SNMP 接口设置。<br>此监控项键的参数支持用户宏和全局正则表达式。|
|**snmptrap.fallback**|<|<|
|捕获该接口上所有未被任何 snmptrap\[\] 监控项捕获的 SNMP trap。|SNMP trap|此监控项只能为 SNMP 接口设置。|

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

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

[comment]: # ({/4c8b1bcc-a8df124c})

[comment]: # ({56d22f70-a08bce2a})
#### 设置SNMP trap监控

[comment]: # ({/56d22f70-a08bce2a})

[comment]: # ({c50351de-581aa946})
##### 配置 Zabbix 服务器/proxy

要读取 trap，必须配置 Zabbix 服务器或 proxy 以启动 SNMP trapper 进程，并指向由 SNMPTT 或 Bash/Perl trap 接收器写入的 trap 文件。为此，请编辑配置文件
([zabbix\_server.conf](/manual/appendix/config/zabbix_server) 或
[zabbix\_proxy.conf](/manual/appendix/config/zabbix_proxy))：

```ini
StartSNMPTrapper=1
SNMPTrapperFile=[TRAP FILE]
```

::: notewarning
如果使用了 systemd 参数
**[PrivateTmp](http://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateTmp=)**
，则此文件很可能无法在 */tmp* 中正常工作。
:::

##### 配置 Bash trap 接收器

要求：仅需 snmptrapd。

可以使用 Bash trap 接收器 [脚本](https://raw.githubusercontent.com/zabbix/zabbix-docker/trunk/templates/scripts/snmptraps/zabbix_trap_handler.sh)，通过 trapper 文件将 trap 从 snmptrapd 传递给 Zabbix 服务器。要进行配置，请将 `traphandle` 选项添加到 snmptrapd 配置文件 (`snmptrapd.conf`) 中，参见[示例](https://raw.githubusercontent.com/zabbix/zabbix-docker/trunk/templates/config/snmptraps/snmp/snmptrapd.conf)。

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

[comment]: # ({/c50351de-581aa946})

[comment]: # ({7db2f34b-0aa82990})
##### 配置 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
perl do "[FULL PATH TO PERL RECEIVER SCRIPT]";
```

-   配置接收器，例如:

```ini
$SNMPTrapperFile = '[TRAP FILE]';
$DateTimeFormat = '[DATE TIME FORMAT]';
```

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

::: notetip
如果没有引用脚本名称，snmptrapd 将拒绝启动并显示消息，类似于这些：<br><br>

```yaml
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
```

:::

[comment]: # ({/7db2f34b-0aa82990})

[comment]: # ({0cbbed23-af1e38f9})
##### 配置 SNMPTT

首先，应配置 snmptrapd 以使用 SNMPTT。

::: notetip
为获得最佳性能，应将 SNMPTT 配置为守护进程，并使用 **snmptthandler-embedded** 将 trap 传递给它。请参阅[配置 SNMPTT](http://snmptt.sourceforge.net/docs/snmptt.shtml)的说明。
:::

当 SNMPTT 配置为接收 trap 后，配置 `snmptt.ini`：

1. 启用 NET-SNMP 软件包中的 Perl 模块：

```ini
net_snmp_perl_enable = 1
```

2. 将 trap 记录到 Zabbix 将读取的 trap 文件中：

```ini
log_enable = 1
log_file = [TRAP FILE]
```
    
3. 设置日期时间格式：

```ini
date_time_format = %Y-%m-%dT%H:%M:%S%z
```

::: notewarning
在 RHEL 8.0-8.2 中，"net-snmp-perl" 软件包已被移除；在 RHEL 8.3 中重新加入。更多信息请参见[已知问题](/manual/installation/known_issues#snmp-traps)。
:::

现在将 trap 格式化为 Zabbix 可识别的形式（编辑 snmptt.conf）：

1. 每个 FORMAT 语句都应以 "ZBXTRAP \[address\]" 开头，其中 \[address\] 将与 Zabbix 中 SNMP 接口的 IP 和 DNS 地址进行比较。例如：

```ini
EVENT coldStart .1.3.6.1.6.3.1.1.5.1 "Status Events" Normal
FORMAT ZBXTRAP $aA Device reinitialized (coldStart)
```

2. 有关 SNMP trap 格式的更多信息，请参见下文。

::: noteimportant
请勿使用未知 trap——Zabbix 将无法识别它们。可以通过在 snmptt.conf 中定义一个通用事件来处理未知 trap：<br><br>

```ini
EVENT general .* "General event" Normal
```

:::

[comment]: # ({/0cbbed23-af1e38f9})

[comment]: # ({599e4c33-cd001892})
##### SNMP 陷阱格式

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

```yaml
[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示例：

```bash
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 接口出现以下陷阱：

```bash
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
```

[comment]: # ({/599e4c33-cd001892})

[comment]: # ({40179940-357f1824})
#### 系统要求

::: noteclassic
建议[安装 MIB 文件](/manual/config/items/itemtypes/snmp/mibs)，
以确保监控项值以正确的格式显示。
如果没有 MIB 文件，可能会出现格式问题，例如以 HEX 而不是 UTF-8 显示值，或反之亦然。
:::

[comment]: # ({/40179940-357f1824})

[comment]: # ({3866234a-6245c6ae})
##### 大文件支持

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

[comment]: # ({/3866234a-6245c6ae})

[comment]: # ({17427a66-0f27a9bb})
##### 日志轮转

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

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

[comment]: # ({/17427a66-0f27a9bb})

[comment]: # ({608a14bd-608a14bd})
##### 文件系统

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

[comment]: # ({/608a14bd-608a14bd})

[comment]: # ({cc0a20fd-ee69482d})
#### 使用不同 SNMP 协议版本的设置示例

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

设置：

1. 配置 Zabbix 以启动 SNMP trapper，并设置 trap 文件。添加到 `zabbix_server.conf`：

```ini
StartSNMPTrapper=1
SNMPTrapperFile=/var/lib/zabbix/snmptraps/snmptraps.log
```

2. 将 Bash 脚本下载到 `/usr/sbin/zabbix_trap_handler.sh`：

```bash
curl -o /usr/sbin/zabbix_trap_handler.sh https://raw.githubusercontent.com/zabbix/zabbix-docker/trunk/templates/scripts/snmptraps/zabbix_trap_handler.sh
```

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

```bash
mkdir -p /var/lib/zabbix/snmptraps
```

3. 将以下内容添加到 `snmtrapd.conf`（请参考可用的[示例](https://raw.githubusercontent.com/zabbix/zabbix-docker/trunk/templates/config/snmptraps/snmp/snmptrapd.conf)）

```ini
traphandle default /bin/bash /usr/sbin/zabbix_trap_handler.sh
```

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

4. [创建](/manual/config/items/item)一个 SNMP 监控项 TEST（请注意初始[配置要求](/manual/config/items/itemtypes/snmptrap#configuring-snmp-traps)）：

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

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

5. 接下来，我们将为所选的 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：

```ini
authCommunity log,execute,net secret
```

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

```bash
snmptrap -v 2c -c secret localhost '' linkUp.0
```

##### SNMPv3

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

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

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

:::noteimportant
请注意 `execute` 关键字，它允许对此用户安全模型执行脚本。
:::

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

::: notewarning
如果您希望使用 AES192 或 AES256 等强加密方法，请使用 5.8 及以上版本的
net-snmp。您可能需要使用 `configure`
选项重新编译它：`--enable-blumenthal-aes`。
较旧版本的 net-snmp 不支持 AES192/AES256。
另请参见：[Strong Authentication or Encryption](http://www.net-snmp.org/wiki/index.php/Strong_Authentication_or_Encryption)。
:::

##### 验证

在这两个示例中，您都会在 `/var/lib/zabbix/snmptraps/snmptraps.log` 中看到类似的行：

```bash
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 中的监控项值将为：

```bash
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 示例：

```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
```

[comment]: # ({/cc0a20fd-ee69482d})

[comment]: # ({91956d23-75026475})
#### 请参阅

- · [关于SNMP traps的Zabbix博客文章](https://blog.zabbix.com/snmp-traps-in-zabbix)
- · [配置snmptrapd（net-snmp官方文档）](https://net-snmp.sourceforge.io/wiki/index.php/TUT:Configuring_snmptrapd)
- · [配置snmptrapd接收SNMPv3通知（net-snmp官方文档）](https://net-snmp.sourceforge.io/wiki/index.php/TUT:Configuring_snmptrapd_to_receive_SNMPv3_notifications)

[comment]: # ({/91956d23-75026475})
