やりたいこと
日本語版vCenterやWindowsからの日本語トラップが文字化け(↓)することの対処。
環境
snmptrapdとsnmpttを使用したzabbix環境
- SNMPTT v1.4beta2
- NET-SNMP Version: 5.7.2
- Zabbix 3.0.9
実現方法
標準で構築すると、
snmptrapdはsnmptt用ハンドラ(/usr/sbin/snmptthandler)を直接呼ぶ。
が、今回は、
snmptt用ハンドラを呼ぶ前に、16進数テキストをバイナリに変換する。
構築するにあたり挙動の確認
snmptrapd が吐き出すもの(サンプル)
1497051259
hostname
UDP: [192.168.10.84]:48146->[192.168.10.84]:162
.1.3.6.1.2.1.1.3.0 0:1:24:40.47
.1.3.6.1.6.3.1.1.4.1.0 .1.3.6.1.4.1.3.1.1.0.99
.1.3.6.1.4.1.8072.9999.1 "31 32 33 E6 97 A5 E6 9C AC E8 AA 9E "
.1.3.6.1.4.1.8072.9999.2 "E6 97 A5 E6 9C AC E8 AA 9E 34 35 36 E3 81 82 E3
81 82 E3 81 82 "
.1.3.6.1.4.1.8072.9999.3 "E5 AF BF E9 99 90 E7 84 A1 E3 80 81 E5 AF BF E9
99 90 E7 84 A1 E4 BA 94 E5 8A AB E3 81 AE E6 93
A6 E3 82 8A E5 88 87 E3 82 8C E6 B5 B7 E7 A0 82
E5 88 A9 E6 B0 B4 E9 AD 9A E3 81 AE E6 B0 B4 E8
A1 8C E6 9C AB E9 9B B2 E6 9D A5 E6 9C AB E9 A2
A8 E6 9D A5 E6 9C AB E9 A3 9F E3 81 86 E5 AF 9D
E3 82 8B E5 87 A6 E3 81 AB E4 BD 8F E3 82 80 E5
87 A6 E8 97 AA E3 82 89 E6 9F 91 E5 AD 90 E3 81
AE E8 97 AA E6 9F 91 E5 AD 90 E3 83 91 E3 82 A4
E3 83 9D E3 83 91 E3 82 A4 E3 83 9D E3 83 91 E3
82 A4 E3 83 9D E3 81 AE E3 82 B7 E3 83 A5 E3 83
BC E3 83 AA E3 83 B3 E3 82 AC E3 83 B3 E3 82 B7
E3 83 A5 E3 83 BC E3 83 AA E3 83 B3 E3 82 AC E3
83 B3 E3 81 AE E3 82 B0 E3 83 BC E3 83 AA E3 83
B3 E3 83 80 E3 82 A4 E3 82 B0 E3 83 BC E3 83 AA
E3 83 B3 E3 83 80 E3 82 A4 E3 81 AE E3 83 9D E3
83 B3 E3 83 9D E3 82 B3 E3 83 94 E3 83 BC E3 81
AE E3 83 9D E3 83 B3 E3 83 9D E3 82 B3 E3 83 8A
E3 83 BC E3 81 AE E9 95 B7 E4 B9 85 E5 91 BD E3
81 AE E9 95 B7 E5 8A A9 "
.1.3.6.1.6.3.18.1.3.0 192.168.10.84
.1.3.6.1.6.3.18.1.4.0 "public"
.1.3.6.1.6.3.1.1.4.3.0 .1.3.6.1.4.1.3.1.1
1497027708
hostname
UDP: [192.168.10.35]:60869->[192.168.10.84]:162
.1.3.6.1.2.1.1.3.0 0:0:51:24.96
.1.3.6.1.6.3.1.1.4.1.0 .1.3.6.1.4.1.311.1.13.1.9.84.101.115.116.98.97.116.99.104.0.1
.1.3.6.1.4.1.311.1.13.1.9999.1.0 "83 70 83 89 83 81 81 5B 83 5E 81 5B 20 27 4D 65
73 73 61 67 65 20 82 CC 88 F8 90 94 82 F0 8A 6D
94 46 82 C5 82 AB 82 DC 82 B9 82 F1 81 42 88 F8
90 94 82 AA 20 6E 75 6C 6C 0D 0A "
.1.3.6.1.4.1.311.1.13.1.9999.2.0 "Unknown"
.1.3.6.1.4.1.311.1.13.1.9999.3.0 "win2016"
.1.3.6.1.4.1.311.1.13.1.9999.4.0 "1"
.1.3.6.1.4.1.311.1.13.1.9999.5.0 "1"
.1.3.6.1.4.1.311.1.13.1.9999.6.0 "83 70 83 89 83 81 81 5B 83 5E 81 5B 20 27 4D 65
73 73 61 67 65 20 82 CC 88 F8 90 94 82 F0 8A 6D
94 46 82 C5 82 AB 82 DC 82 B9 82 F1 81 42 88 F8
90 94 82 AA 20 6E 75 6C 6C "
.1.3.6.1.6.3.18.1.3.0 192.168.10.35
.1.3.6.1.6.3.18.1.4.0 "public"
.1.3.6.1.6.3.1.1.4.3.0 .1.3.6.1.4.1.311.1.13.1.9.84.101.115.116.98.97.116.99.104
snmptrapd が吐き出すもの(考察)
- 最初の数行に、時刻・ホスト・パケット(src/dest)等の情報がある(今回は変換対象外)
- 各OIDと値(文字列や数字)がペアで格納している
- 上記ペアは基本1行であるが、値が長くなると複数行に跨る
- 跨った値は、始点終点がわかるようにダブルクォート(")で囲まれている
- マルチバイトの場合、"2桁の16進数+空白"のパターンの繰り返しである
- 上記16進数をバイナリとしてつなげるとマルチバイト文字列となる
やること(詳細)
値部分のダブルクォート(")で囲まれた文字列が、パターン(2桁16進数+空白)であれば、マルチバイトとみなし、バイナリデータ(マルチバイト文字)に変換する
その他の文字列は触らない。また、ダブルクォートで囲まれていても、パターンに一致しなければ変換しない
上記やることを実現したプログラムをgithubに登録した
実際の手順
- snmptrapdが稼働しているサーバに、プログラムを1本置く。
- snmptrapd.confを修正する。
- 以上!!
プログラムを取ってくる
$ git clone https://github.com/mishikawan/conv_snmptrap_mb.git
$ cp -p conv_snmptrap_mb/conv_snmptrap_mb /usr/local/bin/.
$ chmod a+x /usr/local/bin/conv_snmptrap_mb
snmptrapd.confの設定(その1(望ましい))
以下のように設定し、snmptrapdのrestartする。
マルチバイトのトラップのOIDがわかっている場合は、こちらが望ましい。
e.g.) 以下のような仕様の場合
- vCenter(1.3.6.1.4.1.6876.*) ... UTF8
- windows-event(1.3.6.1.4.1.311.*) ...CP932
- それ以外は、シングルバイトのトラップ
disableAuthorization yes
traphandle 1.3.6.1.4.1.6876.* /usr/local/bin/conv_snmptrap_mb | /usr/sbin/snmptthandler
traphandle 1.3.6.1.4.1.311.* /usr/local/bin/conv_snmptrap_mb | iconv -f cp932 | /usr/sbin/snmptthandler
traphandle default /usr/sbin/snmptthandler
- UTF8の場合は別途iconvいらない( 下から3行目 )
- CP932(UTF8以外のエンコード)の場合は、iconvの別途記載が必要( 下から2行目 )
snmptrapd.confの設定(その2(楽ちんだけど非推奨))
以下のように設定し、snmptrapdのrestartする。
これで、vCenterやUTF8で飛んでくるトラップにも対応できる。
けどこれじゃあ、CP932の場合は文字化けするし、すべてのトラップが私のプログラムを通過することで怖い。
disableAuthorization yes
traphandle default /usr/local/bin/conv_snmptrap_mb | /usr/sbin/snmptthandler
最後に
明確な回避策がインターネット上になく、困ったため作りました。
プログラム組める人じゃないのでコーディングセンス無いですが、私の環境では問題なく動いています。
本当は、Encode::Guess も使いたかったですが、trapのOID毎に使用するエンコードは人が判別できるため、設定で回避しています。