2009年12月14日月曜日

WindowsServerのサービスをSNMPで監視する

Windowsには標準でSNMPサービスが付いている、それを利用して特定のサービスが起動しているかどうかをチェックしよう。
 
 


タスクスケジューラは外部監視しかない


まず何故にいきなりSNMPで監視なのか、に触れておく。
 

私はよく定期的なサービスの監視を仕込んだりする、前に書いたASP.NETアプリケーションプールの監視もそうだった。
 

だがつい最近、タスクスケジューラが止まってるという馬鹿げた自体が発生した、これが止まると内部監視がほとんど止まるじゃないか!
原因とかはとりあえず後だ、こいつを見張るにはどうしたらいい?
 
 

内部監視であれば一定時間...1時間毎とかに生存をメールで通知するか?馬鹿な。止まった時にならない鈴に意味は無い。「そういえばしばらく通知が来ていない?」なんてトリガは存在してはならない。
常駐プロセスか?まずそれが止まるかもしれんだろうが。
選択は自ずと外部監視に限られる。
 
 


外部というとWMIで見る...135番ポートほかを開けるか?悪くはないんだが130番台にいい思い出をもつ管理者はいないのではないか、出来れば空けたくないだろう。
 

そこでSNMPを調べてみた、WMI関連のポートを開放するよりマシだろう。
結論を言って置けば、サービスの監視は可能だ、ただちょっと嫌な仕様だ
 
 


WindowsServerのSNMPの紹介


WindowsServerでSNMPを使うのは簡単だ、コンポーネントの追加とか機能の追加と呼ばれているやり方でセットアップしてやるといい。
 

[caption id="attachment_1616" align="alignnone" width="476" caption="画像:SNMPのRead許可"]画像:SNMPのRead許可[/caption]
 


トラップが送りたければ 『evntwin.exe』 などを立ち上げて通知したいイベントを設定しよう。
 
[caption id="attachment_1617" align="alignnone" width="618" caption="画像:evntwin.exeの設定例"]画像:evntwin.exeの設定例[/caption]
 

詳しくはやってないが、eventcreate.exe で動作確認をしてみた。ちゃんとトラップきてるでしょ?
 
[caption id="attachment_1618" align="alignnone" width="655" caption="画像:トラップテスト"]画像:トラップテスト[/caption]
 


SNMPの標準的なトラフィック取得、ホストステータス取得は出来るから、Cactiでパフォーマンスをグラフ化するなり、トラップでNagiosのパッシブチェックからアラートするなりしたらいい。
 
 

SNMPで取れるWindowsサービスの内容


ではSNMPクライアントから確認できるWindowsサービスについて。
 

WindowsのSNMPをセットアップすると、%SYSTEMROOT%System32\ の下あたりにMIBがいっぱいできる、その中のLanManager用のMIBにWindowsサービスの情報がある。
ファイル名は『lmmib2.mib』だ。
 

その中から svSvcName を取ってみよう、
 

svSvcName.6.83.101.114.118.101.114 Server OctetString
svSvcName.8.72.84.84.80.32.83.83.76 HTTP SSL OctetString
svSvcName.9.69.118.101.110.116.32.76.111.103 Event Log OctetString
--snip--
svSvcName.14.73.80.83.69.67.32.83.101.114.118.105.99.101.115 IPSEC Services OctetString
svSvcName.14.84.97.115.107.32.83.99.104.101.100.117.108.101.114 Task Scheduler OctetString
svSvcName.15.82.101.109.111.116.101.32.82.101.103.105.115.116.114.121 Remote Registry OctetString
svSvcName.15.83.101.99.111.110.100.97.114.121.32.76.111.103.111.110 Secondary Logon OctetString
svSvcName.16.67.111.109.112.117.116.101.114.32.66.114.111.119.115.101.114 Computer Browser OctetString
svSvcName.16.72.101.108.112.32.97.110.100.32.83.117.112.112.111.114.116 Help and Support OctetString
--snip--
svSvcName.37.65.112.112.108.105.99.97.116.105.111.110.32.69.120.112.101.114.105.101.110.99.101.32.76.111.111.107.117.112.32.83.101.114.118.105.99.101 Application Experience Lookup Service OctetString
svSvcName.40.87.105.110.72.84.84.80.32.87.101.98.32.80.114.111.120.121.32.65.117.116.111.45.68.105.115.99.111.118.101.114.121.32.83.101.114.118.105.99.101 WinHTTP Web Proxy Auto-Discovery Service OctetString

 

Windowsで使われているサービスがずらずらと出てきたろう、その中で Task Scheduler のステータスを取るとしたら『svSvcOperatingState』を参照する。
 

svSvcOperatingState.14.84.97.115.107.32.83.99.104.101.100.117.108.101.114 active Integer
 

ほれ、アクティブだ。起動しているってことだ。
 
 


『svSvcName.14.84.97.115.107.32.83.99.104.101.100.117.108.101.114』 がなんでイコール『Task Scheduler』やねんと思うかもしれないが、それはOctetStringだからだ。
 

数字の最初の14は文字列長を表し、このあと14バイトの文字ですよーというのを表している。
そこから続く『84.97.115.107.32.83.99.104.101.100.117.108.101.114』はASCIIコードで変換してくれ...
 

ほら『Task Scheduler』になった、なったろ?
 
 



じゃあサービスの監視をしましょう


さて、サービス状態と思われる、『svSvcOperatingState』の取りうる値はこうだ。
 

svSvcOperatingState OBJECT-TYPE
SYNTAX
INTEGER {
active(1),
continue-pending(2),
pause-pending(3),
paused(4)
}

 


これの変化を取ればいいと思うじゃん、普通にscコマンドとかだとこのまま1-4のステータス取れるし。
1なら正常、2-4は異常として管理したい、したいんだけど。。。
 
 


それがさあ、サービス止めると消えちゃうんだよねこのオブジェクト。
このOID叩いても、何も帰ってこないというかそんなOID見つからないって言われるんだ、冗談きついぜ。
 

当然『svSvcName』のほうも空っぽさ、仕方ないからステータスがUNKNOWNならサービスが止まっているという情けない監視になっちゃう。
 

この仕様はいただけない、いただけないよMicrosoft。改善提案はどこに出したらいいんだい?
それともLanMagnagerではそうするって決まってたのかしら、それはちょっと。。。
 
 



まあ当初の目的は達成されました、この仕組みで立派にWindowsサービスの監視はできますと。
多少不本意ですがUNKNOWN拾ってアラート上げましょう。
追記:サービスの状態が変更されてからSNMPで取れる値が変化するまで2-3分かかる、監視対象によっては少しネックか。
 

まあどうしても外部から見たいのって、タスクスケジューラとファイアーウォールくらいかな。
 
 




追記:
「.1.3.6.1.4.1.119.2.2.4.4.16.2.2.1.2.1.2」なら全サービスが登録されている事を発見、こっちがいいのかも知れない。
だがOIDがサービス名に依存してないので、構成変わるとOIDも変わりそうでこまる。
むむ。。