zabbix4系とCentOS 7系でSNMP Trap(拡張mibファイル利用)監視するまで

[1.やりたいこと](#やりたいこと)
[2.動作環境説明](#動作環境説明)
[3.環境の準備](#環境の準備)
[4.テスト](#テスト)
[5.一般・エンタープライズmib(拡張mib)のコンバート](#一般・エンタープライズmib(拡張mib)のコンバート)
[6.参考](#参考)

#やりたいこと
zabbixでネットワーク機器などzabbix agentがインストールできない機器、いわゆるエージェントレスな監視を行う際に、SNMP trapのOIDをmibファイルから解決してアラートと検知できるようにしたい。
本記事ではOIDをmib解決するまでを記載していきます。
また、拡張mib追加して、OIDを解決できるまでを記載しています。

#動作環境説明
zabbixに必要なコンポーネント(Webインターフェース、zabbix-server、Database)は事前に導入して、基本的にzabbixが利用できる状態からスタートします。

```bash:各種バージョン確認
# OSとバージョン確認
$ cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)

# Zabbix-serverのバージョン確認
$ zabbix_server -V
zabbix_server (Zabbix) 4.0.11

# Apacheのバージョン確認
$ httpd -v
Server version: Apache/2.4.6 (CentOS)

# PHPのバージョン確認
$ php -v
PHP 5.4.16 (cli)
```

#環境の準備
####zabbixのコンフィグ編集
zabbix serverのコンフィグファイルにSNMP trapを有効にする設定と、ログファイルの場所をしているす箇所があるので編集していきます。

```bash:/etc/zabbix/zabbix_server.conf
# 以下の行を追記
$ sudo vim /etc/zabbix/zabbix_server.conf

  #以下の行を追記
  SNMPTrapperFile=/var/log/snmptt/snmptt.log
  StartSNMPTrapper=1

# zabbix-serverプロセスの再起動
$ sudo systemctl restart zabbix-server 
```
これでSNMPプロセスの有効化と、ログファイルの場所を定義しました。

####snmptt, snmptrapdのセットアップ
パッケージをインストールしていきます。

```bash:SNMPTTインストール要件（主にperl環境）
$ sudo yum install net-snmp-utils
$ sudo yum install net-snmp-perl
$ sudo yum install perl
$ sudo yum install perl-Net-SNMP
$ sudo yum install perl-Config-IniFiles
$ sudo yum install perl-Module-Build
$ sudo yum install perl-Time-HiRes
```

SNMPTTユーザを追加します。

```bash:ユーザ追加
$ sudo useradd -s /sbin/nologin snmptt
```

SNMPTTパッケージをインストールします。

```bash:SNMPTTパッケージのインストール
$ sudo cd /usr/src/

# パッケージのダウンロード
$ sudo wget https://sourceforge.net/projects/snmptt/files/snmptt/snmptt_1.4/snmptt_1.4.tgz/download

# ダウンロードしたtarファイルの展開
$ sudo tar xvzf snmptt_1.4.tgz

# 必要ファイルのコピー
$ sudo cd snmptt_1.4
$ sudo cp snmptt /usr/sbin/
$ sudo cp snmptthamdler /usr/sbin/
$ sudo cp snmptt.ini /etc/snmp/
$ sudo cp snmpttconvertmib /etc/snmp/
  
# コピーしたファイルの権限(パーミッション)変更
$ sudo chmod 755 /usr/sbin/snmptt
$ sudo chmod 755 /usr/sbin/snmptthandler
$ sudo chmod 755 /usr/sbin/snmpttconvertmib
```

ログディレクトリとspoolディレクトリの追加して、所有者を変更します。

```bash:ディレクトリの追加と所有者の変更
# snmpttログディレクトリの追加と所有者の変更
$ sudo mkdir /var/log/snmptt/
$ sudo chown nmptt:snmptt /var/log/snmptt/

# spoolディレクトリの追加と所有者の変更
$ sudo mkdir /var/spool/snmptt/
$ sudo chown nmptt:snmptt /var/spool/snmptt/
```

ログローテとの設定をします。場合によってはかなりのログ量になるのでローテートしておきましょう。

```bash:ログローテートの設定追加
$ sudo cp snmptt.logrotate /etc/logrotate.d/snmptt
```

snmpt.confの設定を変更します。これはmibで解決できないOIDを受信した際に文字整形するための設定です。

```bash:/etc/snmp/snmptt.conf
$ sudo vim /etc/snmp/snmptt.conf
  # 下記を追記
  EVENT general .* "General Events" Normal
  FORMAT ZBXTRAP $aA Unknown
```
上記を設定しておくことで、解決できないOIDを受信した時に下記のように文字を整形することができます。$aAにはいろんな値が代入されます。

>08:00:45 2020/06/03 <未解決のOIDが記載される> Normal "General Events" <SNMP trap送信元のIPアドレス> - ZBXTRAP <SNMP trap送信元のIPアドレス> Unknown

snmptrapd.confを編集してサービス起動（または再起動）を行います。

```bash:/etc/snmp/snmptrapd.conf編集とプロセス起動
$ sudo vim /etc/snmp/snmptrapd.conf
  # 下記を追加します。
  traphandle default /usr/sbin/snmptthandler
  disableAuthorization yes

# プロセスの起動（既に動いている場合は停止してから起動）
$ sudo systemctl stop snmptrapd
$ sudo systemctl start snmptrapd
```

snmptt.iniを変更して、サービス起動を行います。

```bash:/etc/snmp/snmptt.ini編集とプロセス起動
$ sudo vim cat /etc/snmp/snmptt.ini
  # 下記を追記
  mode = daemon

  net_snmp_perl_enable = 1

  net_snmp_perl_best_guess = 2

  sleep = 5

  DEBUGGING = 0

  multiple_event = 0

  date_time_format = %H:%M:%S %Y/%m/%d

  DEBUGGING_FILE = /var/log/snmptt/snmptt.debug

  DEBUGGING_FILE_HANDLER = /var/log/snmptt/snmptthandler.debug

# サービスの起動
$ sudo systemctl start snmptt
```

ここまでで一度テストしてみましょう。

```bash:test
# 擬似TRAPファイルを自分自身に送信する。
$ sudo snmptrap -v 2c -c test 127.0.0.1 '' .1.1.1 .1.1.1 s "任意文字列"

# ログの確認
$ cat /var/log/snmptt/snmptt.log
09:52:54 2020/06/03 .1.1.1 Normal "General Events" localhost - ZBXTRAP 127.0.0.1 Unknown
```

自分自身(127.0.0.1)からOID(.1.1.1)が送信されてきたが、mib解決できない(知らないOID)であったため、`/etc/snmp/snmptt.conf`で記載したように`"General Event"`で整形されていることが確認できます。

ここまでで、SNMP trapを受信できるようになりました。
あとは監視対象マシンでサーバに向けてSNMP trapの送信の設定をすれば、zabbixでtrapを受けることができます。zabbixのトリガーやアイテムの設定をすればこの`/var/log/snmptt/snmptt.log`の文字列を監視することができますね。

#一般・エンタープライズmib(拡張mib)のコンバート
これまでのお話で、SNMP trapを受けるようになりましたが、ここからはmibを使ってOIDをわかりやすい文字列に変換していきます。
(例)
>09:52:54 2020/06/03 .1.3.6.1.4.1.9.9.41.2.0.1 Normal "General Events" localhost - ZBXTRAP 127.0.0.1 Unknown

を
>09:52:54 2020/06/03 .1.3.6.1.4.1.9.9.41.2.0.1 Normal "Status Events" Switch1 - When a syslog message is generated by the device a SW_MATM warning MACFLAP_NOTIF Host XXXX.xxxx.XxXx in vlan YYY is flapping between port GigabitEthernet1/0/24 and port GigabitEthernet1/0/23

のように表示させていきます。OIDの数字羅列よりも変換させた方がメッセージが具体的にわかりやすいですね。

#####Mibファイルの準備
未解決のOIDに関するMibファイルを準備してください。
Mibファイル取得は
>　・インターネット上で公開されている
>　・監視対象機器から直接ダウンロードする
>　・誰かにもらう（対象機器を管理している会社など）

などの方法があります。一般的なOIDを検索すればMibファイルも出てくるのでそれをダウンロードして使うことが多いです。CiscoとかAristaなどの拡張Mib（エンタープライズMib）は人からもらう場合が多いです。
取得したMibファイルは下記に保存します。

```bash:Mibファイルの保存
# ディレクトリを用意
$ sudo mkdir /usr/share/snmp/vendor-mibs/

# scpなり、wgetなりでサーバに転送します。
# データ本文を全コピーして貼り付けでもOKです。
$ ls -l /usr/share/snmp/vendor-mibs/<Mibファイル名>.my
-rwxr-xr-x 1 root root 11272 Jul 17  2019 /usr/share/snmp/vendor-mibs/<Mibファイル名>.my
```

#####Mibファイルのコンバート
Zabbixで扱えるようにMibファイルをコンバートします。

```bash:Mibファイルのコンバート
# コンバート後のデータ置き場作成
$ sudo mkdir /root/tmp/

# Mibファイルをコンバートして別の場所に保存する
$ sudo snmpttconvertmib --out=/root/tmp/<Mibファイル名>.conf.org --net_snmp_perl --in=/usr/share/snmp/vendor-mibs/<Mibファイル名>.my

...

Total translations:        114
Successful translations:   114
Failed translations:       0
```

コンバートが成功すれば、`Successful translations:`の値と`Total translations:`の値は同じになります。
Failedするよくある例として下記が考えれれます。
>Mibの依存関係が解決できてない

\<Mibファイル名>.myを見てみると、先頭の方に`IMPORTS`があるのですが、FromのMibファイルを同じディレクトリにおいていないと依存関係で怒られてFailedにカウントされます。下記の場合ですと、`SNMPv2-SMI`や`SNMPv2-CONF`などのMibファイルが必要ということです。

```
IMPORTS
    MODULE-IDENTITY, OBJECT-TYPE, Unsigned32, IpAddress, Gauge32
        FROM SNMPv2-SMI
    OBJECT-GROUP, MODULE-COMPLIANCE
        FROM SNMPv2-CONF
    DisplayString, DateAndTime, TruthValue
        FROM SNMPv2-TC
    TimeTicks
        FROM SNMPv2-SMI
    lumModules, lumMulticastMIB
        FROM LUM-REG
    MgmtNameString, CommandString, EnableDisable, PmReset
        FROM LUM-TC;
```

#####文言の整形

```bash:文言の整形
$ sudo sudo sed -e "s/^FORMAT\s/FORMAT ZBXTRAP \$aA /g" /root/tmp/<Mibファイル名>.conf.org > /etc/snmp/snmptt/vendor-mibs/<Mibファイル名>.conf
```

#####/etc/snmp/snmptt.iniの編集

```bash:/etc/snmp/snmptt.ini
$ sudo vim /etc/snmp/snmptt.ini

  # 下記を記載
　　/etc/snmp/snmptt/vendor-mibs/<Mibファイル名1>.conf
   /etc/snmp/snmptt/vendor-mibs/<Mibファイル名2>.conf
   /etc/snmp/snmptt/vendor-mibs/<Mibファイル名3>.conf
　　...
   # ＜追加したMibファイルを列挙＞
   ...

   # ファイルの最後は下記にする
   /etc/snmp/snmptt.conf
```

OIDを受信した時に、リストの上から順番にMibファイルをチェックしていきます。
どれにもマッチしない場合は`/etc/snmp/snmptt.conf`にマッチさせてGeneral Eventとして出すようにしています。
自分の`/etc/snmp/snmptt.ini`には60行くらいのMibファイルを記載してます。（Cisco系、Arista系、Fori系、OSPF系、JUNIPER系など）

#####SNMPTTサービス再起動
`/etc/snmp/snmptt.ini`ファイルを変更したので反映させるためにSNMPTTサービスを再起動します。

```bash:SNMPTTサービス再起動
$ sudo systemctl restart snmptt
```

これで以降のOIDはMibファイルによって解決できるようになります。
> Mibファイルで解決できないOIDを受信した
　→ Mibファイルの取得
　→ zabbix-serverでコンバート
　→ SNMPTT再起動

を繰り返すことになります。
#参考
[第5回 ZABBIX-JP 勉強会 に参加して発表してきました](https://log4hc.wordpress.com/2012/05/13/zabbix-jp/)