はじめに
前回記事までは、3つの記事に分けて、ZabbixとSNMPによる監視の勉強をしてきた。
よくわからないままsnmptrap
コマンドを使っていたので、ここでいったんsnmptrap
に絞って勉強する。
ここまでの前提の話
DockerでUbuntuコンテナを立てて使ってきたので、今回も継続してUbuntuで勉強する。
(経緯については前回記事を参照)
apt install snmp
により、snmptrap
コマンドは使える状態。
また、UbuntuのIPアドレスは172.20.240.7
であり、監視サーバのIPアドレスは172.20.240.2
である。
SNMPトラップの送信先ポート番号は1162
である。
SNMPトラップの受信ポートは一般的には162
である。
今回はZabbix公式が出しているDockerコンテナのパラメータに従って1162
としている。
snmptrap
コマンド
snmptrap -h
を打つと、こちらのサイトのURLが表示される。
注意:リンク先はHTTPS非対応です
ここ数日はSNMPバージョン2を使ってきたので、SNMPv2 Trapsの項目を読む
以下、DeepLによる翻訳
SNMPv2は通知リクエストのフォーマットを単純化し、Trapリクエストのためだけに別々のヘッダーフィールドを持つのではなく、すべてをvarbindリスト内に統合した。そのため、SNMPv2通知の最初の2つのvarbindは、sysUpTime.0に続いてsnmpTrapOID.0となる。この2番目のvarbindの値は、送信されるトラップを識別するOIDである。
よく分からない。とりあえず同じページに例示されているコマンドを打ってみる。
Ubuntuで試したところ、下記のコマンドが通った。
snmptrap -v 2c -c public 172.20.240.2:1162 "" NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatNotification SNMPv2-MIB::sysLocation.0 s "Just here"
トラップを受信したZabbixサーバのログでは、下記のように表示される。
UDP: [172.20.240.7]:47356->[172.20.240.2]:1162
DISMAN-EVENT-MIB::sysUpTimeInstance = 6251834
SNMPv2-MIB::snmpTrapOID.0 = NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatNotification
SNMPv2-MIB::sysLocation.0 = Just here
1行目は送信元と送信先が->
で表現されているだけだとして、2行目以降についてみていく。
一つ目の引数:sysUpTime.0
-
snmptrap
送信時は""
で空白としていた。 - Zabbixサーバの受信ログによると、
6251834
の値が入っている。 - 実際の値を
snmpwalk
で取得した結果はTimeticks: (1713670) 4:45:36.70
であった。
root@snmp-cl2:/usr/share/snmp/mibs# snmpwalk -v 2c -c public 172.20.240.7 DISMAN-EVENT-MIB::sysUpTimeInstance
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (1713670) 4:45:36.70
あらためてSNMPv2 Trapsの説明を読むと、下記の通り。
snmptrapコマンドは、sysUpTime varbindには気の利いた値を挿入するので、実際には、トラップOID(およびOBJECTS句からの追加のvarbind)だけを提供すればよい
sysUpTime
は空白にしておけば、受信側で適当に価を入れてくれるようなので、これ以上深追いはしない。
普段は、第一引数として""
を書いておけばよい。それだけ。
二つ目の引数:snmpTrapOID.0
- 送信時は
NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatNotification
とした。 - 受信側は
SNMPv2-MIB::snmpTrapOID.0 = NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatNotification
となっている。
こちらは第一引数と違って、送信したものがそのまま受信側に反映されているので直感通りの動き。
なお、第二引数を省いてsnmptrap
を打った結果、「変数の型/値がありません」というエラーが出た。
もちろんサーバ側のログにも残らなかった。
root@snmp-cl2:/usr/share/snmp/mibs# snmptrap -v 2c -c public 172.20.240.2:1162 "" SNMPv2-MIB::sysLocation.0 s "Just here"
s: Missing type/value for variable
snmpTrapOID.0
とは?
今回はNET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatNotification
としたが、前回まではよく分からないままcoldstart
としていた。
試しにsnmptrap -v 2c -c public 172.20.240.2:1162 "" "test" SNMPv2-MIB::sysLocation.0 s "thisistest"
を送ってみる。
snmpTrapOID.0
の箇所を"test"
としてみた。
すると、受信側のサーバのログではIF-MIB::ifTestGroup
という文字列になっていた。
UDP: [172.20.240.7]:51141->[172.20.240.2]:1162
DISMAN-EVENT-MIB::sysUpTimeInstance = 6514663
SNMPv2-MIB::snmpTrapOID.0 = IF-MIB::ifTestGroup
SNMPv2-MIB::sysLocation.0 = thisistest
coldstart
とした場合はSNMPv2-MIB::coldStart
という値になる。
UDP: [172.20.240.7]:40061->[172.20.240.2]:1162
DISMAN-EVENT-MIB::sysUpTimeInstance = 6591700
SNMPv2-MIB::snmpTrapOID.0 = SNMPv2-MIB::coldStart
SNMPv2-MIB::sysLocation.0 = america
"a"
にするとSNMPv2-MIB::authenticationFailure
になった。
UDP: [172.20.240.7]:41152->[172.20.240.2]:1162
DISMAN-EVENT-MIB::sysUpTimeInstance = 6673876
SNMPv2-MIB::snmpTrapOID.0 = SNMPv2-MIB::authenticationFailure
SNMPv2-MIB::sysLocation.0 = japan
RFC 3416「4.2.6. SNMPv2-Trap-PDU」とRFC 3418に「よく知られたトラップ」が書かれている。
つまりは、トラップを発出した時点で、そのホストが起動中だったのか、起動した直後だったのか、インターフェイスがUP/DOWNだったのかを知らせるものなのかもしれない。
こちら富士通の記事から引用させていただく
cold start
SNMPエージェントが初期化され起動しました。
warm start
SNMPエージェントが初期化されず(オブジェクト状態は変更なく)再起動しました。
link down
ネットワークとのインタフェースがUPからDOWN状態になりました。
link up
ネットワークとのインタフェースがDOWNからUP状態になりました。
このトラップがテストであることを明示するときは、NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatNotification
を使うのだろうか。
コメントでご指摘いただけると幸いです。
三つ目の引数は自由(トラップしたいOID)
SNMPv2-MIB::sysLocation.0 s "Just here"
の意味は
sysLocation.0
というOIDの値を「Just here」にしてトラップ送信するという意味
s
は文字列のstring
の意味
ここをi
(整数を意味する integer)にすると、SNMPv2-MIB::sysLocation.0: Bad variable type (Type of attribute is OCTET STRING, not INTEGER)
というエラーが吐かれる
変更したい値の型はsnmpwalk
で調べられる
たとえば次の1行目は整数Integerで、2行目は文字列Stringの型
HOST-RESOURCES-MIB::hrSWRunIndex.235 = INTEGER: 235
HOST-RESOURCES-MIB::hrSWRunName.1 = STRING: "bash"
こちらに型一覧が載っている。
おわりに
snmptrap
の各引数が何者であるかはわかったので、次回以降はテキトーにコマンドを打つことはなくなると思う。
しかしながら、snmpTrapOID.0
に設定すべき値についてはまだ理解が浅いので、継続して勉強する。
さしあたっては、第三引数以降が大事(自分がトラップ送信したい値)であることがよくわかった。
おわりの余談
第三引数と第四引数のOIDを同一にして送ってみた。
snmptrap -v 2c -c public 172.20.240.2:1162 '' "a" SNMPv2-MIB::sysLocation.0 s 'japan' SNMPv2-MIB::sysLocation.0 s 'japan2'
Zabbixサーバのログでは、両方の値が表示されていた。
UDP: [172.20.240.7]:57826->[172.20.240.2]:1162
DISMAN-EVENT-MIB::sysUpTimeInstance = 6799884
SNMPv2-MIB::snmpTrapOID.0 = SNMPv2-MIB::authenticationFailure
SNMPv2-MIB::sysLocation.0 = japan
SNMPv2-MIB::sysLocation.0 = japan2
ZabbixのGUIでもこのとおり
参考