[comment]: # translation:outdated

[comment]: # ({622befb9-622befb9})
# 3 SNMP陷阱

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

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

接收SNMP trap与查询支持SNMP的设备是相反的操作。

在这种情况下，信息从支持SNMP的设备发送，并由Zabbix收集或"捕获"。

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

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写入file
4.  Zabbix SNMP trapper读取并解析trap file
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]: # ({/4ddd974c-ff07904b})

[comment]: # ({5b0130a8-a8df124c})
#### 配置SNMP陷阱

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

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

-   在*配置 > 主机*中，create/编辑主机，并在*接口*字段中添加接口类型"SNMP"，指定IP或DNS地址。<br><br>每个接收到的陷阱地址将与所有SNMP接口的IP和DNS地址进行比较，以找到对应的主机。

2\. 配置监控项

-   在*配置 > 主机*中，create/编辑必要的监控项。
-   在*键*字段中，使用以下SNMP陷阱键之一：

| 键 | <   | <   |
|--|--|------|
| 描述 | 返回值 | 注释 |
| **snmptrap**\[regexp\] | <   | <   |
| 捕获与**regexp**中指定的[regular expression](/manual/regular_expressions)匹配的所有SNMP陷阱。如果未指定regexp，则捕获任何陷阱。 | SNMP陷阱 | 此监控项只能为SNMP接口设置。<br>此监控项键的参数支持用户宏和全局正则表达式。 |
| **snmptrap.fallback** | <   | <   |
| 捕获未被该接口的任何snmptrap\[\] 监控项捕获的所有SNMP陷阱。 | SNMP陷阱 | 此监控项只能为SNMP接口设置。 |

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

:::

-   将*信息类型*设置为"日志"以解析时间戳。其他格式如"数值"也可接受，但可能需要自定义陷阱处理程序。

[comment]: # ({/5b0130a8-a8df124c})

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

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

[comment]: # ({294acfc1-581aa946})
##### 配置 Zabbix server/proxy

要读取SNMP陷阱，必须配置Zabbix server或proxy以启动SNMP trapper进程，并指向由SNMPTT或Bash/Perl陷阱接收器写入的陷阱file。为此，请编辑配置文件file
([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=)**
，此file在*/tmp*目录下可能无法正常工作。

:::

##### 配置Bash陷阱接收器

要求：仅需snmptrapd。

可以使用Bash陷阱接收器[script](https://raw.githubusercontent.com/zabbix/zabbix-docker/6.0/Dockerfiles/snmptraps/alpine/conf/usr/sbin/zabbix_trap_handler.sh)
将陷阱直接从snmptrapd传递给Zabbix server。要配置它，请将`traphandle`选项添加到snmptrapd配置文件file中（`snmptrapd.conf`），
参见[example](https://raw.githubusercontent.com/zabbix/zabbix-docker/6.0/Dockerfiles/snmptraps/alpine/conf/etc/snmp/snmptrapd.conf)。

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

[comment]: # ({0f22aff6-0aa82990})
##### 配置 Perl trap 接收器

需求: Perl, 已编译启用--enable-embedded-perl的Net-SNMP (自Net-SNMP 5.4起默认启用)

可通过Perl trap接收器(参考misc/snmptrap/zabbix\_trap\_receiver.pl)将陷阱直接从snmptrapd传递给Zabbix server。配置步骤如下:

-   将Perl脚本添加至snmptrapd的file配置项

    (snmptrapd.conf), e.g.:

```perl
perl do "[FULL PATH TO PERL RECEIVER SCRIPT]";
```
-   配置接收器，例如:

```ini
$SNMPTrapperFile = '[TRAP FILE]';
$DateTimeFormat = '[DATE TIME FORMAT]';
```
::: 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]: # ({/0f22aff6-0aa82990})

[comment]: # ({30bbd05c-af1e38f9})
##### 配置 SNMPTT

首先，需要配置snmptrapd以使用SNMPTT。

::: notetip
为获得最佳性能，应将SNMPTT配置为守护进程，使用**snmptthandler-embedded**来传递陷阱。具体配置方法参见[configuring SNMPTT](http://snmptt.sourceforge.net/docs/snmptt.shtml)。

:::

当SNMPTT配置为接收陷阱后，需配置`snmptt.ini`：

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

```ini
net_snmp_perl_enable = 1
```
2.  将陷阱日志记录到file函数中，该日志将由Zabbix读取：

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

```ini
date_time_format = %H:%M:%S %Y/%m/%d
```
::: notewarning
注意："net-snmp-perl"包在RHEL 8.0-8.2版本中已被移除，在RHEL 8.3中重新加入。更多信息请参阅[known
issues](/manual/installation/known_issues#snmp_traps)。

:::

现在为Zabbix识别格式化陷阱（编辑snmptt.conf文件）：

1.  每个FORMAT语句应以"ZBXTRAP [address]"开头，其中

    \[address\] will be compared to IP and DNS addresses of SNMP
    interfaces on Zabbix. E.g.:

```ini
EVENT coldStart .1.3.6.1.6.3.1.1.5.1 "Status Events" Normal
FORMAT ZBXTRAP $aA Device reinitialized (coldStart)
```
2.  更多关于SNMP陷阱格式的信息请见下文。

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

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

[comment]: # ({/30bbd05c-af1e38f9})

[comment]: # ({ca0d29ba-cd001892})
##### SNMP trap 格式

所有自定义的Perl trap接收器和SNMPTT trap配置必须
按照以下格式处理trap信息:

```yaml
[timestamp] [the trap, part 1] ZBXTRAP [address] [the trap, part 2]
```
其中

-   [timestamp] - 用于日志记录的时间戳 监控项
-   ZBXTRAP - 表示新trap开始的头部标识
-   [address] - 用于查找该trap对应主机的IP地址

请注意"ZBXTRAP"和"[address]"会在处理过程中从消息中移除。
如果trap采用其他格式，Zabbix可能会以非预期方式解析这些trap。

示例trap:

```bash
11:30:15 2011/07/27 .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接口生成如下trap:

```bash
11:30:15 2011/07/27 .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]: # ({/ca0d29ba-cd001892})

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

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

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

Zabbix对SNMP trapper文件具有较大的file支持。Zabbix可读取的最大file大小为2^63（8 EiB）。需注意文件系统可能对file大小施加更低的限制。

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

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

Zabbix不提供任何日志轮转系统 - 这应由用户自行处理。日志轮转应首先重命名旧的file文件，
然后才delete它，以确保不会丢失任何陷阱:\

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

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

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

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

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

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

本示例使用snmptrapd和Bash接收器脚本将陷阱传递给Zabbix server.

设置步骤:

1.  配置Zabbix启动SNMP trapper并

    set the trap file. Add to `zabbix_server.conf`:

`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/6.0/Dockerfiles/snmptraps/alpine/conf/usr/sbin/zabbix_trap_handler.sh
```
如需使用默认值，请先create父目录:

```bash
mkdir -p /var/lib/zabbix/snmptraps
```
3. 将以下内容添加到`snmtrapd.conf`(参考[example](https://raw.githubusercontent.com/zabbix/zabbix-docker/6.0/Dockerfiles/snmptraps/alpine/conf/etc/snmp/snmptrapd.conf))

```ini
traphandle default /bin/bash /usr/sbin/zabbix_trap_handler.sh
```
4.  [Create](manual/config/items/item)一个SNMP 监控项测试(注意初始[configuration requirements](/manual/config/items/itemtypes/snmptrap#configuring-snmp-traps)):\

    Type: SNMP trap\
    Type of information: Log
    Host interface: SNMP 127.0.0.1\
    Key: `snmptrap["linkUp"]`\
    Log time format: yyyyMMdd.hhmmss

`snmptrap["linkUp"]`\
    日志时间格式: yyyyMMdd.hhmmss

5.  接下来我们将为选定的SNMP协议version配置`snmptrapd`，并使用

    send test traps using the `snmptrap` utility.

`snmptrap`工具.

##### SNMPv1, SNMPv2

SNMPv1和SNMPv2协议依赖"community string"认证. 以下示例中
我们将使用"secret"作为community string. 该值必须在SNMP trap发送端设置相同.

请注意，虽然SNMPv2在生产环境中仍广泛使用，但它不提供
任何加密和真正的发送方认证. 数据以明文发送，因此
这些协议版本应仅在私有网络等安全环境中使用，
切勿在任何公共或第三方网络中使用.

SNMP version 1现在基本不再使用，因为它不支持64位计数器且
被视为遗留协议.

要启用接收SNMPv1或SNMPv2陷阱，请将以下行添加到`snmptrapd.conf`.
将"secret"替换为SNMP trap发送端配置的community string:

```ini
authCommunity log,execute,net secret
```
接下来我们可以使用`snmptrap`发送测试陷阱. 本例中使用常见的"link up" OID:

```bash
snmptrap -v 2c -c secret localhost 0 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"关键字，允许为该用户安全模型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等强加密方法，请使用
version 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).

:::

##### Verification 

在两个示例中，您都将在`/var/lib/zabbix/snmptraps/snmptraps.log`中看到类似行:

```bash
20220805.102235 ZBXTRAP 127.0.0.1
UDP: [127.0.0.1]:35736->[127.0.0.1]:162
DISMAN-EVENT-MIB::sysUpTimeInstance = 0:0:00:00.00
SNMPv2-MIB::snmpTrapOID.0 = IF-MIB::linkUp.0
```
Zabbix中的监控项值将为:

```bash
2022-08-05 10:22:35	2022-08-05 10:22:33	

20220805.102233 UDP: [127.0.0.1]:35736->[127.0.0.1]:162
DISMAN-EVENT-MIB::sysUpTimeInstance = 0:0:00:00.00
SNMPv2-MIB::snmpTrapOID.0 = IF-MIB::linkUp.0
```

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

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

-   [Zabbix blog article on SNMP
    traps](https://blog.zabbix.com/snmp-traps-in-zabbix)
-   [Configuring snmptrapd (official net-snmp documentation)](https://net-snmp.sourceforge.io/wiki/index.php/TUT:Configuring_snmptrapd)
-   [Configuring snmptrapd to receive SNMPv3 notifications (official net-snmp documentation)](https://net-snmp.sourceforge.io/wiki/index.php/TUT:Configuring_snmptrapd_to_receive_SNMPv3_notifications)

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