snmp.png

 

 

SNMP(Simple Network Management Protocol)とは何か

■ UCD-SNMPとNET−SNMP

Linux 上のSNMPはもともとUCD-SNMPという名前だったが、現在ではNET-SNMPに変わっている。ただし、両者は別のものではなく、バージョンの違いと考えてよい。ちなみに、バージョン5以降が NET-SNMP と呼ばれており、本稿では後者の NET-SNMP-5.0.1-6 以降のバージョンを前提に論を進める。


■ SNMPプロトコル

SNMPは、ネットワーク上の管理対象機器と管理ステーションとの間で管理情報をやり取りするための通信プロトコルで、RFC1157で規定されている。訳語では「簡易ネットワーク管理プロトコル」と呼ばれるが、その名前の通り比較的に簡単な構造をしている。特に後述するエージェントと呼ばれる対象機器側のプログラムサイズをコンパクト化しやすいことから、ルータやハブなどの機器にも実装が容易であり、TCP/IPをベースとした管理プロトコルの標準となっている。SNMPは現在までに3種類のバージョンあり、1および2が非暗号化で IPv4 対応となっており、v3 になってはじめて IPv6 と暗号化に対応している。

SNMPは通信にUDPを用いており、ウェルノウンポート161番(メッセージ待ち受け)と162番(トラップ待ち受け)が予約されている。TCPを用いないのは、どのような障害が起きているかわからないネットワークにTCPパケットを不用意に送り出さないための配慮である。(ネットワーク機器が障害を発生した場合、TCPプロトコルでは再送パケットが無用のトラフィックを発生させることになり、かえって問題を悪化させる可能性がある。)また、NET‐SNMPではマルチプレックスサービスとして smux( tcp199/udp199 ) を併せて使用する。


■ SNMPマネージャとSNMPエージェント

SNMPでは、管理対象機器にエージェント(代理人)と呼ぶソフトウェアを常駐させ、同時に管理ステーションにはマネージャ(管理者)と呼ぶソフトウェアを常駐させる。これらのプログラムがそれぞれおたがいに通信を交わし、ネットワーク機器の性能や構成、障害、セキュリティ、アカウントの5種類の情報をやりとりする。

エージェントはマネージャからのクエリーに対応するMIBデータを選択して送り返すだけの動作しかしないのでプログラムはコンパクトにできるが、マネージャはその他の仕事をすべてこなさなければならないため、それなりに大掛かりなものとなる。UCD−SNMPは非常に多機能なマネージャであり、同時にエージェントにもなることができる。UNIX上で動くSNMPマネージャとしては OpenView が知られており、別項で解説するMRTGなどもマネージャ機能を持っている。


■ MIBツリー

マネージャやエージェントは、これら5種類の管理情報をMIB(Management Information Base  を略したもので「みぶ」と読む。)と呼ばれる独自のデータベースに保存する。MIBファイルは通常テキストファイルの形になっており、それぞれの機器メーカーが固有のMIBファイルを供給している。以下にMIBツリーの構造を示す。なお、これは snmptranslate コマンドに -Tp オプションをつけて出力した上位の一部分であり、実際にはずっと大きなファイルである。

# snmptranslate -Tp

+--iso
(1)
   |
   +--org(3)
      |
      +--dod(6)
         |
         +--internet(1)
            |
            +--directory(1)
            |
            +--mgmt(2)
            |  |
            |  +--mib-2(1)
            |     |
            |     +--system(1)
            |     |  |
            |     |  +-- -R-- String    sysDescr(1)
            |     |  |        Textual Convention: DisplayString
            |     |  |        Size: 0..255
            |     |  +-- -R-- ObjID     sysObjectID(2)
            |     |  +-- -R-- TimeTicks sysUpTime(3)
            |     |  +-- -RW- String    sysContact(4)
            |     |  |        Textual Convention: DisplayString
            |     |  |        Size: 0..255
            |     |  +-- -RW- String    sysName(5)
            |     |  |        Textual Convention: DisplayString
            |     |  |        Size: 0..255
            |     |  +-- -RW- String    sysLocation(6)
            |     |  |        Textual Convention: DisplayString
            |     |  |        Size: 0..255
            |     |  +-- -R-- INTEGER   sysServices(7)
            |     |  |        Range: 0..127
            |     |  +-- -R-- TimeTicks sysORLastChange(8)
            |     |  |        Textual Convention: TimeStamp
            |     |  |
            |     |  +--sysORTable(9)
            |     |     |
            |     |     +--sysOREntry(1)
            |     |        |  Index: sysORIndex
            |     |        |
            |     |        +-- ---- INTEGER   sysORIndex(1)
            |     |        |        Range: 1..2147483647
            |     |        +-- -R-- ObjID     sysORID(2)
            |     |        +-- -R-- String    sysORDescr(3)
            |     |        |        Textual Convention: DisplayString
            |     |        |        Size: 0..255
            |     |        +-- -R-- TimeTicks sysORUpTime(4)
            |     |                 Textual Convention: TimeStamp
            |     |
            |     +--interfaces(2)
            |     |  |
            |     |  +-- -R-- Integer32 ifNumber(1)
            |     |  |
            |     |  +--ifTable(2)
            |     |     |
            |     |     +--ifEntry(1)
            |     |        |  Index: ifIndex
            |     |        |
            |     |        +-- -R-- Integer32 ifIndex(1)
            |     |        |        Textual Convention: InterfaceIndex
            |     |        |        Range: 1..2147483647
            |     |        +-- -R-- String    ifDescr(2)
            |     |        |        Textual Convention: DisplayString
            |     |        |        Size: 0..255

        -------------- 以下継続 ---------------



MIBファイルは管理項目によってDNSと似たツリー状の階層構造を持ち、.1.3.6.1.2.1…のような数値表現によって管理情報を表す。ここで述べた.1.3.6.1.2.1 というOID数列は、上のツリーの青文字をたどったもので、iso-org-dod-internet-mgmnt-mib2-system として管理されている一連の情報を表す。この情報は数値でしか表現できないわけではなく、DNSのように名前への変換が可能である。変換は先に述べた snmptranslate コマンドによって実行する。

     #
snmptranslate 1.3.6.1.2.1
      
SNMPv2-SMI::mib-2

-On オプションを使えば、逆に名前を数値表現へ変換することもできる。

     
# snmptranslate  -On UCD-SNMP-MIB::ucdavis
      .1.3.6.1.4.1.2021


さらに便利なのは -On -IR オプションを指定すると、OIDシンボルから数値を引き出せることである。たとえば上の表の赤字で表示された ifTable を検索するには次のように行う。

     
# snmptranslate -On -IR ifTable
      
.1.3.6.1.2.1.2.2

エージェントはマネージャからの要求にこたえてMIBから必要な情報を読み出し、管理情報を送信する。MIBにはTと2のバージョンがあり、それぞれ
RFC1156とRFC1213で定義されている。現在ではほとんどのネットワーク機器がMIB−2をサポートしているが、ネットワーク上に古い機器がある場合は仕様を調べておいた方が確実である。


■ マネージャによるポーリングとエージェントからの非同期トラップ

マネージャはエージェントに対して問い合わせ(ポーリング)を発行することができる。マネージャはMIBターゲットを引数としたSNMPコマンドを実行し、エージェントが持っている特定の管理情報を要求する。ポーリングを自動化したい場合はスクリプトにSNMPコマンドを記述し cron に登録すればよい。また、httpd のプロセス数を監視したい場合、snmpd.conf の proc 行に設定しておけばよい。ステータスは自動的にMIBに書き込まれ、ポーリングによってステータス情報を返す。


snmp1.png


このようなポーリングに対する応答は常に同期的であるが、NET-SNMPでは snmptrapd を動かすことによって、障害が発生したとき自動的に非同期トラップを上げることができる。たとえば、snmpd.conf の exec 行に障害時に動かしたいプログラム(障害通知スクリプト名や障害対応プログラム名)を書き込み、その一方で snmptrapd.conf にプログラム名を traphandle としてフルパスで記述しておく。この設定によってネットワーク機器からトラップが上がるたびに当該スクリプトがコールされ、管理者にメール通知したりデーモンを再起動するなど、障害対応を自動化することができる。(なお、プログラムには引数をつけることもできる。)


trap1.png



■ snmpd.conf および snmptrapd.conf による管理対象(コミュニティ)

snmp では管理対象となるネットワーク機器を community (コミュニティ)という名前でグループ化する。コミュニティは snmp で管理するネットワーク範囲のことで、snmpd.conf の com2sec 行で定義する。デフォルトでは、ローカルサブネット上から管理できるコミュニティを private と名付け、LAN経由で管理できるコミュニティを public としているが、これは
運用時に必ず変更すべきである。ネットワーク機器のデフォルトも public になっていることが多いので、コミュニティ名を変更するのは億劫かもしれないが、コミュニティ名は SNMP にとってパスワードの性格を持っているばかりでなく、snmpset コマンドによって機器の設定変更が可能であるため、デフォルトの使用は機能テスト時以外、禁止するのが無難である。

なお、管理対象となる機器にもそれぞれコミュニティ名を登録する必要があるので、これも怠りなく実施すること。




NET-SNMP

■ インストールと起動

RedHat でサーバインストールを選択すると SNMP は自動的にインストールされるが、ソースコードをコンパイルしてインストールしたい場合は次のように行う。

1
.コンパイルとインストール(この項目に関してのみ筆者のメモをもとに ucd-snmp-4.2.1で解説する。)

     # gzip -d ucd-snmp-4.2.1.tar.gz
     # tar -xvf ucd-snmp-4.2.1.tar
     # cd ucd-snmp-4.2.1

     # ./configure            ※ ここで
管理者のメールアドレスや logの保管場所を質問されるが、コンフィグで変更可能である。

     # make
     # make install

インストールされるファイルは次の通り。ただし、snmpd.conf は、make install ではインストールされないので、サンプルファイルを必要なディレクトリに cp しておく。 snmp.conf は他のユーザの目に触れないよう、600に chmod しておくとよい。

     /usr/local/sbin/snmpd
     /usr/local/bin/snmpget
     /usr/local/bin/snmpwalk

     # cp EXAMPLE.conf /usr/local/share/snmp/snmp.conf
     # chmod 600 snmpd.conf

すでにお気づきかと思うが、rpm でインストールした場合とはパスが異なっているので注意が必要である。特にMRTGと連携させる場合は、Apache のパスも併せて確認しておくこと。

2.実行環境の確認

/etc/servicesに次のサービス名があり、利用が可能になっていることを確認しておく。なお smux はUNIXにおけるSNMP用のマルチプレクサ(多重化した複数の情報を単一チャネルによって転送するサービス)である。

snmp 161/udp   # Simple Net Mgmt Proto
snmp-trap 162/udp   # Traps for SNMP
smux 199/tcp   # SNMP Unix Multiplexer
smux 199/udp   

また、ファイアウォールを通る必要がある場合は、これらのポーリングパケットやトラップパケットを許可しておく。

3.起動と停止

RedHatの場合、デーモンの起動は /etc/rc.d/init.d/snmpd start または service snmpd start で行う。これは他のデーモンと変わらないので、自動実行する場合は chkconfig コマンドで実行レベルを指定してONにしておくか、/etc/rc.local に起動コマンドを記述しておく。なお、動作の確認は snmpd.conf を編集後、次のように行う。ここでは対象ホストを 192.168.0.1 とし、コミュニティ名をデフォルトの public とする。

     snmpwalk -v 2c 192.168.0.1(対象ホスト) -c public(コミュニティ名)

これでMIB情報が流れたらOKである。また、ログや出力に関してオプションをつけてシステム起動時にSNMPを有効にしたい場合は、次のような一行を /etc/rc.local に記述しておく。

     
/usr/local/sbin/snmpd -s -l /dev/null -P /var/run/snmpd -a

ここでのオプション指定は次のとおり。

     ○ -s によって syslog を有効にする。
     ○ -l /dev/null によって標準出力には出力しない。
     ○ -p /var/run/snmpd -a によってプロセスID保存ファイルを指定し、併せて送信元IPアドレスも記録する。



■ snmpd.conf の設定例

snmpd の設定は /etc/snmp/snmpd.conf で行う。このファイルはかなり長いものだが、そのほとんどは用例とコメントになっており、一部をコメントアウトするか、変更するだけで使用することができる。以下に snmpd.conf の雛型としての設定例を示す。

  ---- snmpd.conf ----

# sec.name source community
com2sec local localhost private_local
com2sec mynetwork 192.168.0.10 public_global  

# sec.model sec.name
#group MyRWGroup v1 local
#group MyRWGroup v2c local
#group MyRWGroup usm local
group MyROGroup v1 mynetwork
group MyROGroup v2c mynetwork
group MyROGroup usm mynetwork  

# incl/excl subtree mask 80
view all include .1 80


# context sec.model sec.level match read write notif
access MyROGroup "" any noauth exact all none none
# access MyRWGroup "" any noauth exact all all none

# location
syslocation SNMP MANAGEMENT Server

# contact
syscontact administrator<root@mydomain.com>

# proc
proc sendmail 10 1
proc httpd 50 1
proc named
proc syslogd
proc sshd

# exec
execechotest /bin/echo hello world

# disk
disk / 10000
disk / 20%
disk /home 20%
disk /var 30%

# load avalage
load 6 7 7

# file
file/var/log/messages50000



アクセス制御
ローカルホストからアクセスさせる内部専用コミュニティ名を private_local
とし、192.168.0.10 のみに許可する mynetwork のコミュニティ名を public_global とする。




mynetwork に対する読み取り権限ユーザの定義



ビューの設定:すべて参照可能(デフォルト)




グループのアクセス許可設定(書き込み可はなし)



ロケーション(サーバ名)の設定


システム管理者の連絡先


sendmail は1以上10以下で稼動しているか

httpd は1以上50以下で稼動しているか
named は動いているか
syslogd は動いているか
sshd は動いているか


テストスクリプトの実行結果を返す(デフォルトのテストケース)


/ の空き容量は10Mあるか

/ の残りは20%あるか
/home の残りは20%あるか
/var の残りは30%あるか


平均負荷(ロードアベレージ)のチェック


ログの messages が5GBを越えたらエラー扱い

LINUXサーバ同士を監視するのであれば、同じ snmpd.conf を雛型としてコピーして使うのが便利である。その上でホストごとに異なる監視要件をコンフィグに記述する。たとえばWEBサーバであれば proc 行に httpd の監視項目がある、という具合にすればよい。



SNMP コマンド

■ snmp コマンドによるポーリング

SNMP ではコマンドラインから直接コマンドを叩いたり、cron にスクリプトを仕掛けてたりしエージェントにポーリングを実施できる。snmp コマンドの代表的なものは、MIBを連続して読み込む snmpwalk 、特定のMIBを読み込む snmpget 、逆にMIBに書き込む snmpset などがある。ここでは読み出しコマンドとMIB−2およびUCDAVISについてかいつまんで解説する。まず、SNMPコマンドの書式を snmpwalk で示す。

     snmpwalk -v 2c HOSTNAME -c COMMUNITYNAME  OID数列

-v 2c はSNMPのバージョンを 2c に指定するオプションで、-c はコミュニティを指定するために必要なオプションである。このホスト名
には接続したいSNMPエージェントのホスト名またはIPアドレスを使い、コミュニティ名には接続に使うコミュニティ名を指定する。(もちろん、snmpd.conf で定義したコミュニティ名を使う必要がある。)

snmpget が指定したOIDだけを読み出すのに対して、snmpwalk は指定したOIDを起点として、連番のOIDを読み出す。したがってMIB情報をまとめて取得して、対象の概要が知りたい場合は snmpwalk コマンドを使用するとよい。このとき番号表示がされないので、snmpwalk の結果を less -N にパイプしておくと、何行目に何があるかわかりやすくなる。なお、less の行番号表示はターミナル上の折り返しにも同じ行番号を振るので、どちらが行頭であるのか注意すること。

     
snmpwalk -v 2c 192.168.1.1 -c public .1.3.6.1.2.1.1 | less -N

MIB-2 は標準的な対象をサポートし、UCDAVISはNET-SNMP固有の対象をサポートする。詳細は /usr/local/share/snmp/mibs ディレクトリにインストールされる UCD-SNMP-MIB.txt ファイルを参照のこと。以下によく使われるサブツリー単位で snmpwalk コマンドとOIDを示す。

MIB-2
     snmpwalk -v 2c 192.168.1.1 -c public .1.3.6.1.2.1.1   ( system サブツリー )

     snmpwalk -v 2c 192.168.1.1 -c public .1.3.6.1.2.1.2   ( interface  サブツリー )

     snmpwalk -v 2c 192.168.1.1 -c public .1.3.6.1.2.1.4   ( ip サブツリー )
     snmpwalk -v 2c 192.168.1.1 -c public .1.3.6.1.2.1.5   ( icmp サブツリー )
     snmpwalk -v 2c 192.168.1.1 -c public .1.3.6.1.2.1.6   ( tcp サブツリー )
     snmpwalk -v 2c 192.168.1.1 -c public .1.3.6.1.2.1.7   ( udp サブツリー )

     snmpwalk -v 2c 192.168.1.1 -c public .1.3.6.1.6.1.11   ( snmp サブツリー )

UCDAVIS
     snmpwalk -v 2c 192.168.1.1 -c public .1.3.6.1.4.1.2021   ( ucdavis サブツリー )

UCDAVISサブツリーにはプロセスやディスクの情報が格納される。このサブツリーはプロセスの状態などがレポートされるが、これは /proc ファイルシステムの状態を反映したものである。以下にUCDAVISでよく使う項目について一覧する。

名称

OID

内容

prTable

1.3.6.1.4.1.2021.2

プロセスの状態

memory

1.3.6.1.4.1.2021.4

メモリの状態

extTable

1.3.6.1.4.1.2021.8

指定コマンドの実行結果

dskTable

1.3.6.1.4.1.2021.9

ディスクの状態

laTable

1.3.6.1.4.1.2021.10

システムのロードアベレージ情報

systemStats

1.3.6.1.4.1.2021.11

システムの状態

fileTable

1.3.6.1.4.1.2021.15

指定ファイルのファイルサイズなど

version

1.3.6.1.4.1.2021.100

snmpd のバージョン情報

snmperrs

1.3.6.1.4.1.2021.101

エラー発生時の情報

mrTable

1.3.6.1.4.1.2021.102

snmpd の追加モジュールに関する情報

ここで一例として、TeraTermから snmpwalk でUCDAVISの10番をスキャンし、ロードアベレージを調べた結果を示す。

ucdavis1.png

ここでは snmpd.conf に書いた値を問題なく下回っているのでエラーフラグはすべて0になっている。この結果を解析スクリプトに渡し、時系列でロードアベレージの遷移を記録しておくと、いざエラーフラグが立ったとき、どのような推移で閾値を越えたか、推測が容易になる。また、このデータをMRTGに渡すように設定し、グラフとして目視できるようにしておくといっそうわかりやすくなる。



SNMPtrapd

■ snmptrapd とトラップ

一般にSNMPによる監視は cron にスクリプトを仕掛け、マネージャ側が定期的にポーリングすることによって実施する。しかし、仮にこのポーリング間隔を1時間に設定したとすると、最後のポーリングが終了してから一時間はシステムのステータスが急変してもSNPMは報告を返さない。これでは困る、とポーリング間隔を狭めると、今度はネットワークトラフィックが増大するという別の問題が発生する。このような事情を考慮して、エージェントから自発的に障害イベントの発生をレポートさせるように作られたのが snmptrapd である。snmptrapd は監視対象に設定された閾値を越えるとイベントをトラップし、ただちにマネージャに通知する。
簡単に両者の役割を区別すると次のようになる。

     定常監視 → snmpd
     緊急報告 → snmptrapd

障害がわかればいいのだからと、トラップだけを動かしている監視系があるそうだが、これは感心できない。というのは、対象機器が深刻な障害に見舞われて突然停止してしまえば、エージェントも当然死んでしまうのでトラップの上げようがないからである。また、トラップが上がって障害がスナップショット的に報告されても、時系列資料がないと何が発生したのか突き止められないことが多い。この意味でSNMPを使う以上、両デーモンを動かすべきである。


■ snmptrapd.conf

snmp でトラップを仕掛けるとき、必要な設定ファイルが /etc/snmptrapd.conf である。ここにはトラップする対象(OID)と処理するプログラム(フルパスで記述)を書き、プログラム中で必要ならば引数をつける。プログラム起動の流れは次のようになる。

      事象発生 → snmptrapd によるトラップ → トラップハンドルの参照 → 該当プログラムの起動

なお、ハンドリングするプログラムには実行権限をつけておくこと。ただし、SNMP関連のプログラムは基本的に root 権限で動かすことになるので、不用意なプログラムをセットしないようにする。(一般に、セキュリティ面を考えればシステムクリティカルなプログラムは snmpd / snmptrapd にセットするべきでない。また、 traphandle を /root/bin に置いていることに注意。)

 ---- snmptrapd.conf ----
#
# net-snmp (or ucd-snmp) persistent data file.
#

# Please save normal configuration tokens for snmptrapd in SNMPCONFPATH/snmptrapd.conf.

# Only "createUser" tokens should be placed here by snmptrapd administrators.
#

engineBoots 179
oldEngineID 0x800007e58005d34a6510335a3e

# engineBoots 175
# oldEngineID 0x800007e58005d34a6510335a3e

#
# add configration for trap-interface
#

traphandle SNMPv2-MIB::coldStart /root/bin/trap.sh 1
traphandle SNMPv2-MIB::warmStart /root/bin/trap.sh 2
traphandle
IF-MIB::linkDown /root/bin/trap.sh 3
traphandle
IF-MIB::linkUp /root/bin/trap.sh 4
traphandle default /root/bin/trap.sh 999
 















←起動時に自動構成されるのでこのままにしておくこと




サーバ側トラップインタフェース


OID+プログラム名+引数を記述


 

なお、OIDを数値で並べるとどうしても入力ミスを起こしやすい。SNMPはDNSのアイディアを数多く取り入れているが、OIDに対する名前快活に相当するコマンド snmptranslate を使って、OIDを英文に変換しておくとよい。


■ サーバ側トラップインタフェース

snmp におけるサーバ側インタフェースはsnmpd.conf の exec 行にセットするプログラムと、snmptrapd.conf に記述するトラップハンドルプログラムである。前者はプログラムの実行結果が ucdavis サブツリーのOIDに格納され、後者は snmptrapd.conf の設定項目(トラップハンドルプログラム)に連動して実行される。

ここでトラップインタフェース用シェルプログラムの例として trap.sh を示す。マニュアルの snmptrapd チュートリアルに英文ながらわかりやすい解説があるので、バージョンごとの詳細を知りたい向きはそちらも参照のこと。ここではチュートリアルにあるサンプルプログラムをもとに、対象として coldStart と warmStart および linkDown と linkUp を採用し、トラップが発生したらメールで携帯電話のアドレス(trap_handle@docomo.ne.jp)に飛ばす形式にした。もちろんこの場合は正しく設定された sendmail 等のMTAがシステムで稼動しているのが前提である。なお、このプログラムは case 文を使った普通のシェルスクリプトであるから、 5) 6) …のようにしてトラップ項目を増やすことができるが、あまりメール通知項目を増やすと携帯が鳴りっぱなしということにもなりかねないので、ほどほどに。 なお、999) は case 文のデフォルト処理である。

 ---- trap.sh -----

#!/bin/bash

read host
read ip

case $1 in
        1)
                subject="$host: SNMPv2-MIB::coldStart"
                message="SNMPv2-MIB::coldStart"
                ;;

        2)
                subject="$host: SNMPv2-MIB::warmStart"
                message="SNMPv2-MIB::warmStart"
                ;;

        3)
                subject="$host:
IF-MIB::linkDown"
                message="
IF-MIB::linkDown"
                ;;

        4)
                subject="$host:
IF-MIB::linkUp"
                message="
IF-MIB::linkUp"
                ;;

        999)
                subject="$host: UNKNOWN EVENT"
                message="UNKNOWN EVENT OCCARED."
                ;;
esac

cat << END | mail -s "$subject" trap_handle@docomo.ne.jp

DATE: $(date "+%Y/%m/%d %H:%M:%S")
HOSTNAME: $host
IP: $ip
$message

END

exit 0
 

このプログラムの動作を確認するには、snmptrap コマンドを使って実際にトラップを生成してみればよい。

     #
snmptrap -v 2c -c "" servername "" SNMPv2-MIB::coldStart

直後に
SNMPv2-MIB::coldStart を subject とするサーバからのメールが受信できればOKである。


メールフォーマット

DATE: 2003/10/31 18:48:27
HOSTNAME: localhost.localdomain
IP: 127.0.0.1

SNMPv2-MIB::coldStart



■ crontab への登録と定常監視

snmp コマンドはコマンドラインからポーリングできることから、crontab に登録して動作させることが可能である。この方法では一定時間ごとにポーリングを繰り返すことができるので、ポーリングの結果をファイルに append して解析スクリプトに渡すように設計しておけば、定常監視として機能させることができる。以下にごく単純な監視データ出力スクリプトを紹介する。このスクリプトは snmp ポーリングによってCPU負荷情報を得るものだが、cron に呼ばれるたびに過去15分ごとの負荷平均を切り出して laLoad3.dat にデータを追加してゆく。

 ---- load_avarage_watch.sh ----

#!/bin/bash

snmpwalk -v 2c localhost -c public .1.3.6.1.4.1.2021.10 | grep laLoad.3 | awk '{pront $4}' >> laLoad3.dat
 

このスクリプト load_avarage_watch.sh を /root/bin に置き、cron に10分ごとに実行させるには crontab -e を実行して、次のようなエントリを書けばよい。

     # crontab -e
     */10 * * * * /root/bin/load_avarage_watch.sh

この設定によって、10分ごとに laLoad3.dat にデータが追加されてゆく。出力されるデータは単純な数列であるから、グラフを作成するなりヒストグラムを作るなりするプログラムへ渡せばよい。おそらくもっとも手っ取り早いのは scp でWindowsマシンへデータファイルを飛ばし、CSVファイルとして Excel に読み込ませて処理する方法であろうが、単純なY軸データとして Linux ホスト上で GNUplot に出力させることもできる。

     $ gnuplot
     gnuplot > plot "./laLoad3.dat" with linespoints

また、最初からMRTGを使ってグラフ化し、ブラウザから状態の推移を見る方法もある。もっとも、このあたりは実装上の問題であるので、それぞれの現場で検討していただきたい。



ネットワーク監視系

■ ネットワーク監視系の設計指針

ネットワーク監視系を設計するとき、重要なポイントとなるのは監視マネージャをネットワークのどの部分に設置するか、ということである。SNMPは監視の自動化を目的としているので、接続したノードが障害を起こした場合は、当然その先のネットワークに対するポーリングができなくなり、非同期トラップも受信できなくなってしまう。この意味で、SNMPマネージャの接続ポイントは次の3つの条件を勘案して決めなければならない。

   ○ 外部へのルータや部門分割用のスイッチなど、システム全体にとってクリティカルなノードが直接監視できること
   ○ なるべく広いネットワーク範囲を見渡せるノードに接続できること(VLAN構成がある場合などはその上流)
   ○ システム全体のセキュリティ強度を低下させないこと

ネットワークやファイアウォールの構成によってはこの条件が満たせない場合があるが、そのようなケースでは監視をSNMPにこだわらず、他の方法を含めて柔軟に対応する必要がある。また、冗長クラスタ構成を採っている場合は、フェイルオーバが発生したサーバに対する対処やクラスタ間のハートビートラインの機能確認なども重要な監視項目となる。なお、こうしたHAシステムではメーカー側が監視用のソフトウェアを提供していることが多いので、併せて利用を検討しておくこと。

外部に対して閉ざされたネットワークであれば、基本的に監視サーバはどこに置いてもかまわないが、インターネットに接続しているネットワークではマネージャの設置場所いかんによってセキュリティ強度を低下させる恐れがある。データセンタに設置するようなサーバならば、リモートでログオンするマネージャのために専用線を引いて、直接内部に接続してしまうのが安全であるが、そのような環境が構成できない場合はVPNを使って経路自体を暗号化したり、プロトコルをトンネリングする(SNMP自体は v3 以外非暗号化プロトコル)など、セキュアな接続を考慮する必要がある。なお、SNMPv1からv3への移行については、
AIX用の日本語文書が存在するので、参考までに目を通しておくとよい。

一方、ネットワーク監視を総合的に見渡すには、システムの機能階層を意識しなければならない。

    システム機能階層の概念図

kaisou.png

 

ネットワークシステムの機能階層とシステム監視

ネットワークシステムの機能はハードウェア→ネットワークファームウェア→OS→サーバアプリケーション→プロセスの順番で機能的に従属している。そのため、下位機能の監視を行わないまま上位機能を監視しても、原因の究明や早期対応にはあまり役に立たないばかりか、かえって混乱を招きやすい。

熟練した管理者がシステム障害についてトラブルシューティングを行う場合は、最初に最初に電源供給が確実に行われているか調査し、次いでネットワークがハードウェア的に正しく機能しているか調べる。さらにOSが必要なプロトコルをサポートしているか、サーバアプリは正しく起動されてエラーを出力していないか、サーバアプリに必要なプロセスが起動しているかどうか調べて行き、障害が発生している階層を突き止める。

システム監視ではこのように下位機能から上位機能への作業が重要であり、逆の順番で作業をしても原因を特定することはむずかしい。たとえば httpd プロセスが停止していることをSNMPがトラップしても、停止した原因を調べないままとりあえず再起動しておく、という対処では、本質的な解決には至らない。
 
このため、監視系は一つの事象に対する機能依存がある場合、下位からの調査結果をレポートできるように設計しなければならない。また、問題がいつから発生しているのか、時系列で検討できるよう、一定期間のポーリングについてロギングしておくことも重要である。



■ 監視系設計上の諸注意

一般に監視系を設計する場合は、次のような注意が必要である。

1.監視対象の絞り込み

監視対象機器を絞り込むことはネットワーク内部のトラフィックを無駄に増やさないために重要である。システム全体の状況を把握したいからといって、すべてのクライアント機までSNMPで監視していてはきりがない。監視系はあくまでもメインシステムの運用をサポートするための補助系であるので、本来基幹業務に使用されてしかるべきネットワークリソースを圧迫するようでは本末転倒ということになる。一般論になるが、監視すべき対象は次のように考えるのが妥当であろう。

    ○ ネットワーク境界ノード(ルータ・スイッチ・ゲートウェイサーバなど)
    ○ ケーブル接続ポート両端の Link up
    ○ ネットワークカードのモード(プロミスキャスモードで盗聴されていないか)
    ○ 各種サーバ
       ・プロセス(総数・必要プロセスの生存確認・異常プロセスの発見等)
       ・ディスク容量(上限チェック・時系列による増加率のチェック)
       ・ログ
       ・CPU稼働率
       ・メモリ使用量
    ○ 電源補機(UPSなど)
    ○ 出力装置(プリンタなど)

管理者が特に理解しておかなければならないのは、監視系はシステムが落ちたことを発見するためにあるのではなく、落ちるのを未然に防ぐためにある、ということである。SNMPはサーバや機器が落ちる寸前の低空飛行であってもその値が閾値よりも大きいかぎり、危険性をアラートしてくれない。したがって管理者にはトラップの安全限度(閾値)を前もって見積り、危険な状態になる前に情報を入手する工夫が必要になる。このためには時系列での情報収集や、定期的なチェックなど、実行すべき管理タスクを定型・スケジュール化しておく。

また、システム管理を cron やSNMPまかせにするのではなく、担当者は常にシステムの状態を把握する努力が必要である。ハードウェアからの異音発生、発熱、異臭など、人間でなければわからないチェックポイントがあることをぜひ理解してほしい。

2.対象機器のプロトコルバージョンの確認とMIBデータの収集

最近のネットワーク機器はエンドユーザ向けの低廉化商品以外、ほとんど MIB-2 対応となっている。この意味では監視対象とするのに問題はないが、MIBファイルはそれぞれのメーカーによって異なっている。MIBファイルをよく読まないとSNMPコマンドを実行する対象がつかめないので、工程初期にMIBの構成を調査してターゲットを確定しておくこと。

3.ファイアウォールの設定変更

先に述べたとおり、SNMPはUDP
ウェルノウンポート161番(メッセージ待ち受け)と162番(トラップ待ち受け)を使用するので、ファイアウォールに通過許可が必要である。この際、管理ホストにログオンする外部ホストのみを許可し、他のホストにはアクセス制限をかけておく。また、外部からリモートでログオンする場合は、内部に対する名前解決ができるようにしておく必要がある。

4.監視の検証

監視が十分に機能しているかどうかの検証は、監視対象を「何」とするかにかかっている。たとえばWEBサーバを監視するとき、最も重要なポイントは監視対象がWEBサーバとして機能しているかどうか、ということが問題になる。すなわち、サーバホストがWEBサーバとして機能するためには、単にサーバマシンの電源が入っているだけではなく、次のような要件が満たされていなければならない。

    ○ httpd プロセスが必要十分な数だけ起動され、http 要求に応答できること
    ○ ネットワークパスが確保されて、ゲートウェイやDNSサーバと通信ができること
    ○ Tomcat のような別プロセスで動くアプリケーションがあれば、そのプロセスが動いていること

この意味において、WEBサーバに対する監視は、HTTPDプロセス数の監視・NICのリンクアップの確認という2項目が最低限必要である。(ホストの生存確認のためにPINGを打つことがあるが、内部のICMPを許可することは、多くの場合ファイアウォール構成上の妨げとなるばかりであまり意味がない。)もちろんこれだけでOKというわけではなく、過大なトラフィックはかかっていないか、Apache がエラーログを吐いていないか、不正アクセスがなかったかなど、総合的な観点でWEBサーバのステータスを見守らなければならない。およそシステム管理には「何を」「どのように」「どうする」が欠かせないが、SNMPによる監視系の設計では特に注意が必要である。


 

 

 

Copyright(c) 2003 My Company. All rights reserved. www.suzu841.com / mrs.suzu841.com