YAMAHA vRXをDatadogのSNMPで監視しちゃおう

そもそもSNMPを活用した監視についてあまり記事がなかったので備忘録として。

##経緯
YAMAHA vRXの検証環境に触れる機会があったので、運用の観点から利用方法だけでなく監視ができないかを調査。
ネットワーク機器ではお馴染みのSNMPの機能を用いて、vRXが出力する値を監視する手段の考察

##必要なもの
- datadog-agentを稼働させるためのvRXに通信可能な別インスタンス
- vRX用MIBファイル
- MIBファイルをpython化するための作業環境（一度きり）
- 気合い

##諸々の概要
###Datadogについて
説明する気はありませんので、気になる方は以下なりインターネッツでお調べください。
https://www.datadoghq.com/ja/
このDatadogのエージェントがもつ標準のsnmp監視インテグレーションを利用します。
https://docs.datadoghq.com/ja/integrations/snmp/
###DatadogのSNMPインテグレーションについて
非常に難解。
というのも、そもそもSNMPをそこまで詳しく知らないため、yaml見てもピンとこなかったのが原因。
OIDの指定だけでも取得はできるが、せっかくなのでカスタムMIB使っちゃおうとしたのが間違いの始まり。
`Specify an additional folder for your custom mib files (python format).`
pythonフォーマットのMIBファイルが必要です。
辛い。
##YAMAHA vRXについて
詳しい情報はこちら
https://network.yamaha.com/products/software_service/vrx/index
注目される強みはここかな、と。
`IPsecのアグレッシブモードをサポートしており、固定IPアドレス環境を用意しなくても、動的IPアドレスを持つ端末やルーターからのVPN接続が可能です。`

##検証の環境
- YAMAHA vRX Rev.19.00.01
- Amazon Linux 2 Linux version 4.14.154-128.181.amzn2.x86_64 < datadog-agentを導入しvRXを監視するインスタンス
- datadog-agent v7.16.1

##下準備
面倒だったので作業はAmazonLinux2上で行なっています。
###カスタムMIBファイルの取得
適当なディレクトリにて

```
$ mkdir yamahamib
$ cd yamahamib
$ wget http://www.rtpro.yamaha.co.jp/RT/docs/mib/yamaha-private-mib.zip
$ unzip yamaha-private-mib.zip
$ rm yamaha-private-mib.zip
（ディレクトリに残ったzipは消すか移動させてください）
```

MIBの参照先はこちら
http://www.rtpro.yamaha.co.jp/RT/FAQ/SNMP/private-mib.html
###作業環境作成
・pipインストール

```
$ sudo yum install python3-pip
```

・pysnmp,pysnmp-mibsのインストール

```
$ sudo pip3 install pysnmp pysnmp-mibs
```
###pythonファイルへのコンバート
MIBファイルを展開したディレクトリにて

```
$ mibdump.py ./*
```
以下のディレクトリにpyファイルに変換されたMIBファイルが保管される（はず）
`/hogeuser/.pysnmp/mibs`

このファイルを
`/etc/datadog-agent/mibs`
など、適当なディレクトリを用意して移動させる
（datadog-agentで指定するので、アクセス権があればどこでも良い）

私の環境では念の為chownコマンドにてディレクトリとファイルのオーナーをdd-agentに変えましたが、必要かどうかは知りません。
検証環境のディレクトリの中身はこんな感じです。

```
-rw------- 1 dd-agent dd-agent  6007 Jan 23 09:30 YAMAHA-PRODUCTS-MIB.py
-rw------- 1 dd-agent dd-agent  8053 Jan 23 09:30 YAMAHA-RT-FIRMWARE.py
-rw------- 1 dd-agent dd-agent 14570 Jan 23 09:30 YAMAHA-RT-HARDWARE.py
-rw------- 1 dd-agent dd-agent 62248 Jan 23 09:30 YAMAHA-RT-INTERFACES.py
-rw------- 1 dd-agent dd-agent  7134 Jan 23 09:30 YAMAHA-RT-IP.py
-rw------- 1 dd-agent dd-agent  2117 Jan 23 09:30 YAMAHA-RT.py
-rw------- 1 dd-agent dd-agent 10571 Jan 23 09:30 YAMAHA-RT-SWITCH.py
-rw------- 1 dd-agent dd-agent  1904 Jan 23 09:30 YAMAHA-SMI.py
-rw------- 1 dd-agent dd-agent  4851 Jan 23 09:30 YAMAHA-SW-ERRDISABLE.py
-rw------- 1 dd-agent dd-agent  4571 Jan 23 09:30 YAMAHA-SW-FIRMWARE.py
-rw------- 1 dd-agent dd-agent 15584 Jan 23 09:30 YAMAHA-SW-HARDWARE.py
-rw------- 1 dd-agent dd-agent 11757 Jan 23 09:30 YAMAHA-SW-L2MS.py
-rw------- 1 dd-agent dd-agent  2214 Jan 23 09:30 YAMAHA-SW.py
-rw------- 1 dd-agent dd-agent  2313 Jan 23 09:30 YAMAHA-SW-RMON.py
-rw------- 1 dd-agent dd-agent  5595 Jan 23 09:30 YAMAHA-SW-TERMMON.py
```

##YAMAHA vRX側の設定
ここで肝心のvRXの設定を忘れていたので、記載します。
SNMPを利用して取得を行いたいのが目的ですので、難しいことはしていません。
aws内部通信で完結するため、SNMP V3ほどの要件は想定せず、コミュニティ名で対応しています。

なお、前提として初期設定や通信接続設定は完了していることとなります。
aws前提ですので、vRX側のSGのインバウンドをdatadogを入れてsnmpを叩かせるインスタンスからの通信も許可しておいてください。
###SNMPの設定
以下の設定を追記

```
snmp host any
snmp community read-write hogecom
snmp syscontact hoge
snmp sysname VPC3_RT
snmp syslocation aws
snmp yriftunneldisplayatmib2 on
```

反映、保存を忘れずに。
詳しい方は知識に合わせて変更ください。
細かい説明はできませんので省略します。
なお、host anyは検証でやってるだけなので、アクセス元の制限が必要であれば指定ください。
##datadog-agentの設定
通常設定はされている前提です。
###snmp用yamlファイルの準備
datadog-agentのv7では以下の場所にyamlのサンプルファイルが保管されています。
`/etc/datadog-agent/conf.d/snmp.d`
コピーしてファイル名を変更し、読み込まれるように設定します。
記述が面倒なので、以下からはroot権限でやります。

```
# cd /etc/datadog-agent/conf.d/snmp.d
# cp conf.yaml.example conf.yaml
```

拡張子をyamlにすることでdatadog-agentの次回起動時から読み込みされます。
###snmpの取得設定
conf.yamlファイルをエディタなどで編集します。
とりあえずの設定箇所は

```
init_config:
.
.
   # mibs_folder: /path/to/your/mibs/folder
  ↓↓↓↓↓↓この検証だとこのディレクトリ。変更された方はそれに合わせて設定ください。
  mibs_folder: /etc/datadog-agent/mibs
.
.

instances:
.
.
     # ip_address: <IP_ADDRESS>
  ↓↓↓↓↓↓vRXのLAN側のIPアドレスを指定
     ip_address: xxx.xxx.xxx.xxx
.
.
     # community_string: public
  ↓↓↓↓↓↓この検証だとこのコミュニティ名。環境に合わせて指定ください。
     community_string: hogecom
.
.
     # snmp_version: 2
  ↓↓↓↓↓↓今回v1で手を抜いたので。環境に合わせて指定ください。
     snmp_version: 1
.
.
```

datadog-agentを再起動します。
その後、statusコマンドにてsnmpの取得がうまくいってることを確認します。

```
# systemctl restart datadog-agent
# datadog-agent status
.
.
    snmp (2.1.0)
    ------------
      Instance ID: snmp:9a97f28adcb05e32 [OK]
      Configuration Source: file:/etc/datadog-agent/conf.d/snmp.d/conf.yaml
      Total Runs: 1
      Metric Samples: Last Run: 4, Total: 4
      Events: Last Run: 0, Total: 0
      Service Checks: Last Run: 1, Total: 1
      Average Execution Time : 191ms
```
うまく動けばsnmpの項目がOKで返って来ることがわかります。
少しおいてからDatadogのコンソールにて、Insfastructureを探すと「snmp」が表示されるようになります。
merticsのグラフが参照できるので、そこでグラフが表示されれば取得完了となります。

画面は取っていませんが、おそらく黄色いsnmpマークとグラフは3つが出ていると思います。
これが初期設定で拾ってくる情報となります。
###MIBの設定から取得してみる
大詰めです。
せっかくプライベートMIBが使えるようになっているので、それを指定した取得も入れてみましょう。

conf.yamlファイルをエディタなどで編集します。

```
instances:
.
.
    metrics:
.
.
      - MIB: YAMAHA-RT-HARDWARE
        symbol: yrhMemoryUtil
```

これでdatadog-agentを再起動すると、メモリの使用率が取得できるようになります。
なお、MIBとかsymbolって？って話ですが、指定する情報は以下の通りです。

```
MIB＝mibs_folder: /etc/datadog-agent/mibsに保管したpyのファイル名（.pyは不要）
symbol＝対象pythonファイル内の定義情報です。
```

上記の設定では、YAMAHA-RT-HARDWARE.pyのyrhMemoryUtilの値を返してね。
ちなみにOIDは「1.3.6.1.4.1.1182.2.1.4」なので、このOID指定＋nameでも同じ値は返ります。
が、せっかくなので。

なお、vRXはRTのカテゴリ扱いなので、SWファイル（OID:1.3.6.1.4.1.1182.3）には対応していないようです。
詳しいことはmib.txtの内部に書かれているので、それを参照してください。

例）YAMAHA-RT-HARDWARE
http://www.rtpro.yamaha.co.jp/RT/docs/mib/yamaha-rt-hardware.mib.txt

```
yrhMemoryUtil OBJECT-TYPE
	SYNTAX	Gauge (0..100)
	ACCESS	read-only
	STATUS	mandatory
	DESCRIPTION
		"The utilization in percentage of main memory."
	::= { yamahaRTHardware 4 }
```

あと、Datadog側のyamlに標準で書かれている以下の項目はエラーになって取得ができない可能性が高いので、いっそのこと消してしまいましょう。
（活用できる方はぜひ使っていただければ）

```
      - OID: 1.3.6.1.2.1.6.5
        name: tcpPassiveOpens
        metric_tags:
          - TCP
```

MIBでの取得情報追加、上記の設定削除後にdatadog-agentを再起動し、statusで問題がなければ、
以下のようにDatadogのコンソール側で「yrhMemoryUtil」が取れるようになったことが確認できます。
<img width="1708" alt="datadog.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208312/0e8d56b6-e012-e2ee-9ace-84609b5bf93e.png">

SNMPV2c情報が欲しい場合は、vRX側でV2cのコミュニティ、受け入れhost設定の追加、
Datadog側ではV1からV2利用の宣言に変更すれば取得可能でした。

##付録
トンネルのリンクupdownはOID「1.3.6.1.4.1.1182.2.3.16.1.2系」にて確認できるようです。
SNMP V2cが前提であることにご注意ください。

どれがリンクするかは、configのtunnelの設定番号を確認し、snmpwalkでインターフェースのディスクリプション番号と関連を確認

```
$ snmpwalk -v 1 -c hogecom xxx.xxx.xxx.xxx | grep ifDescr
IF-MIB::ifDescr.1 = STRING: LAN1
IF-MIB::ifDescr.2 = STRING: LAN2
IF-MIB::ifDescr.3 = STRING: LAN3
IF-MIB::ifDescr.4 = STRING: LAN4
IF-MIB::ifDescr.1195 = STRING: TUNNEL[1]
IF-MIB::ifDescr.1196 = STRING: TUNNEL[2]
.
.
```

tunnel 1が1195と確認できるので、

```
$ snmpwalk -v 1 -c hogecom xxx.xxx.xxx.xxx 1.3.6.1.4.1.1182.2.3.16.1.2.1195
SNMPv2-SMI::enterprises.1182.2.3.16.1.2.1195 = INTEGER: 1
```

で値を取得。
1はUp、2はDownなので、2を取得した場合にアラートとすることで対応できそう。

私の検証環境では

```
SNMPv2-SMI::enterprises.1182.2.3.16.1.2.1195 = INTEGER: 1
SNMPv2-SMI::enterprises.1182.2.3.16.1.2.1196 = INTEGER: 1
SNMPv2-SMI::enterprises.1182.2.3.16.1.2.1197 = INTEGER: 2
SNMPv2-SMI::enterprises.1182.2.3.16.1.2.1198 = INTEGER: 2
```

となっており、tunnel1,2がup(1)、3以降は存在しないためdown(2) が取得されました。


##まとめ
まとめというほどじゃないですが、python化とMIBの指定さえわかれば、なんとかなるかなという印象。
OID指定の方が楽な場合もあるので、そこは臨機応変にお願いします。
（取れると思って試してる値が取れずに悩んでますが、諦めも肝心です）
snmpwalkなどで取れるものは、普通に取れる印象です。