SNMPによるネットワークモニタリング

SNMPによる
ネットワークモニタリング
 ネットワークは常時正常に動作していることが求められる。そのためには,構築後にも放置せず定期的にメンテナンスする必要がある。日々管理を行うための具体的な方法としては,サーバが書き出すログ情報を見たり,セキュリティホールを埋めるパッチを当てたりと,きめ細やかな配慮が必要だ。
 しかしこれらの作業だけでなく,ハードウェアや回線のトラブルがなく,ネットワークに接続されている機器類が正常に動作しているのかどうかを調べることも,安定した動作を保つのに欠かせないことだ。このようなネットワーク機器の監視を行う場合に便利なのが,「SNMP(Simple Network Management Protocol)」の利用である。本稿では,SNMPを使い,MRTGと組み合わせてネットワークモニタリングを行う方法を解説しよう。

One Point! 本稿はOSとして,Red Hat Linux 6.2日本語版を想定する。しかしRed Hat Linux 6.2に依存する部分はほとんどないので,ほぼ同等な方法で他のディストリビューションやLinux以外のUNIX系のOSにも適用できるはずだ。

icon SNMPって何だ?

 SNMPとは,ネットワークに接続された機器類をネットワーク経由で監視するためのプロトコルだ。このプロトコルはRFC1157で定義されている。


One Point! RFCドキュメントは,JPNIC RFC-JPなどで入手できる。

 SNMPに対応する機器類には,その機器の情報を保持するための「管理情報領域」と呼ばれる領域が用意されている。たとえばルーターであれば,そのルーターを流れたデータのバイト数,ネットワークプリンタであれば,プリンタのステータス,用紙情報,トナー残量などが管理情報領域に格納されている。管理情報領域にどのような情報が保存されているのかは,機器によって異なる。

 SNMPに対応する機器内には,ネットワークを通じて管理情報領域にアクセスするためのインタフェースが用意される。このインタフェースは「SNMPエージェント」と呼ばれる。SNMPエージェントはUDPを使ってネットワーク通信するモジュールだ。

 SNMPに対応する機器——つまりSNMPエージェントが搭載された機器——の情報を得るには,サーバーやクライアントなどのホストに「SNMPマネージャ」と呼ばれるソフトをインストールする。SNMPマネージャは,SNMPエージェントと通信し,SNMPに対応する機器類内にある管理情報領域の情報を,取得したり設定する機能を持つ。つまりネットワーク管理者は,SNMPマネージャを使うことで,ネットワーク上に配置されたネットワーク機器の情報を1か所で管理できるようになる(Fig.1)。

Fig.1 SNMPの構成 fig_01


SNMPを使うには
 Fig.1を見るとわかるように,SNMPは,管理される側である「SNMPエージェント」と,管理する側である「SNMPマネージャ」の2つで構成される。

 SNMPエージェントは,インテリジェントハブやルータ,ネットワークプリンタなどに搭載されている。よってSNMPに対応したそれらの機器を管理するのであれば,LinuxマシンにSNMPマネージャをインストールするだけでよい。

 また,LinuxマシンにSNMPエージェントとなるソフトをインストールすると,そのLinuxマシンを別のLinuxマシンからSNMPマネージャを使って管理することができる。LinuxマシンがSNMPエージェントとして機能するようになると,ネットワーク上に複数のLinuxマシン(Linuxサーバー)が存在するとき,SNMPマネージャを使って,それらのLinuxサーバーの情報を集中管理できて便利だ(Fig.2)。

Fig.2 LinuxマシンをSNMPで管理する
fig_02

 本稿では,まず,SNMPエージェントとなるソフトをLinuxマシンにインストールし,Linuxマシン自身をSNMP対応機器に仕立て上げてしまう方法を説明する。

 そして次に,SNMPマネージャを(ネットワーク管理者がネットワーク管理に使う)Linuxマシンにインストールし,SNMPに対応した機器(SNMPエージェントをインストールしたLinuxマシンも含む)を管理する方法を説明する。

 もちろん読者のなかには,LinuxマシンをSNMPで管理する必要はなく,SNMPに対応したネットワーク機器だけをLinuxマシンからSNMPで集中管理できればよいという人もいるだろう。その場合には,LinuxマシンにSNMPエージェントをインストールする作業は不要なので,その部分は飛ばし,LinuxマシンにSNMPマネージャをインストールするところから読み進めてもらってかまわない。

icon ucd-snmp

 LinuxにインストールすることができるSNMPエージェントとなるソフトには,いくつかの種類がある。本稿では,比較的よく使われている「ucd-snmp」を使うことにする。ucd-snmpは,SNMPエージェントといくつかの簡単なコマンドライン形式のSNMPマネージャを含むSNMP統合パッケージだ。ちなみにucd-snmpは,Linux以外にも,FreeBSDやSolarisなどさまざまなUNIX系のOSで動作する。


One Point! ucd-snmpは,NET-SNMPという名称に変わった。しかしまだNET-SNMPという名称が付いたプログラムは開発中で公開されておらず,旧称であるucd-snmpのプログラムが公開され続けている。そこで本稿では,NET-SNMPという名称ではなくucd-snmpという名称で記述することにする。将来NET-SNMPが公開されれば,ucd-snmpは旧バージョンとなり,ucd-snmpという名称は次第に使われなくなるだろう。

ucd-snmpのインストール
 ucd-snmpのソースファイルは,http://net-snmp.sourceforge.net/にあるリンクから入手することができる。ここではhttp://sourceforge.net/project/showfiles.php?group_id=12694にある,ucd-snmp-4.2.1.tar.gzというtar.gz形式のファイルをダウンロードしてインストールすることにする。
One Point! ucd-snmpをインストールするために,ucd-snmp-4.2.1-2.rh62.i386.rpmというRPMパッケージを使ってもよい。しかし筆者の環境では,ライブラリの関係で正しくインストールできなかったため,本稿では,ucd-snmp-4.2.1.tar.gzというtar.gz形式のソースファイルから構築することにした。

 ucd-snmp-4.2.1.tar.gzをインストールするには,次のようにする。

(1)ucd-snmp-4.2.1.tar.gzをダウンロードする
 前出のURLより,ucd-snmp-4.2.1.tar.gzをダウンロードする。いくつかのミラーサイトもあるので,ミラーサイトからダウンロードするほうが望ましい。
(2)tarコマンドを使って展開する
 ダウンロードしたディレクトリにカレントディレクトリを移し,次のようにtarコマンドを使って展開する。

$ tar xzvf ucd-snmp-4.2.1.tar.gz

(3)環境設定する
 するとカレントディレクトリにucd-snmp-4.2.1というディレクトリができるので,カレントディレクトリをそこに移動する。

$ cd ucd-snmp-4.2.1

 次に環境設定をするため,configureコマンドを実行する。

$ ./configure

 configureコマンドを実行すると,途中いくつかの質問がされるので,適切に答える。ここで設定する情報は,SNMPの管理情報となる。

 とはいえ,ここでの設定内容は,デフォルト値の設定であり,「SNMPエージェントを動かしてみる」で説明するsnmpd.confファイルを書き換えると変更できる。よって,よくわからなければ,適当に入力しても問題ない。

 各質問のまえには,まず,次のようなメッセージが表示されるので,[Enter]キーを押す。

checking if you have run configure before...
************** Configuration Section **************

You are about to be prompted by a series of questions. Answer
them carefully, as they determine how the snmp agent and related
applications are to function.

After the configure script finishes, you can browse the newly
created config.h file for further - less important - parameters to
modify. Be careful if you re-run configure though since config.h will
be over written.

-Press return to continue-

 するとまず,次のようなメッセージが表示され,SNMPエージェントの管理者として設定したいメールアドレスが尋ねられる。ここには,管理者となるユーザーのメールアドレスを入力する。普通は,自分のメールアドレスやrootユーザーのメールアドレスを入力することになるだろう。

disabling above prompt for future runs... yes
checking System Contact Information...


*** System Contact Information:

Describes who should be contacted about the host the agent is
running on. This information is available in the MIB-II tree. This
Can Also Be Over-Ridden Using The "syscontact" Syntax In The Agent'S
Configuration Files.

System Contact Information (ユーザー名@): ここにメールアドレスを入力する

 すると,次のように表示され,管理者情報が設定される。

System Contact Information (osawa@): 入力したメールアドレス
setting System Contact Information to... 入力したメールアドレス

 次に,このLinuxマシンの配置場所を設定する。これはSNMPマネージャを使って管理する時に表示される場所の情報となる。たとえば,経理部に配置したLinuxマシンであれば“Accounting”,開発部に配置したLinuxマシンでは“Development”といった情報を入力することになる。もっとも,これは場所を示すというよりも,管理上わかりやすくするのが目的なので,サーバー名を入力したり,“gateway server”とか“print server”といったサーバーの役割を示す名前を設定したりしてもよい。ここでは仮に,“Red Hat Linux Server”と入力することにする。

checking System Location...


*** System Location:

Describes the location of the system. This information is
available in the MIB-II tree. This Can also be over-ridden using the
"syslocation" syntax in the agent's configuration files.

System Location (Unknown): Red Hat Linux Server <--- ここに場所情報を入力する

 すると次のように表示され,配置場所が設定される。

setting System Location to... 入力した場所情報

 次にログファイルのファイル名を設定する。デフォルトでは,/var/log/snmpd.logファイルになっている。変更したければ変更してもかまわないが,とくに変更する必要もないので,ここでは,[Enter]キーを押すだけでよい。

checking Location to write logfile...


*** Logfile location:

Enter the default location for the snmpd agent to dump
information & errors to. If not defined (enter the keyword "none"
at the prompt below) the agent will use stdout and stderr instead.
(Note: This value can be over-ridden using command line options.)

Location to write logfile (/var/log/snmpd.log): [Enter]キーを押す

 すると次のように,ログファイル名が/var/log/snmpd.logに設定される。

setting Location to write logfile to... /var/log/snmpd.log

 次に,SNMPエージェントが保持する永続的なデータ(管理情報領域)の保存場所を設定する。デフォルトでは,/var/ucd-snmpディレクトリになっている。変更したければ変更してもかまわないが,とくに変更する必要もないので,ここでは,[Enter]キーを押すだけでよい。

checking Location to write persistent information...


*** snmpd persistent storage location:

Enter a directory for the snmp library to store persistent
data in the form of a configuration file.

Location to write persistent information (/var/ucd-snmp): [Enter]キーを押す

 以上の入力をし終えると,ふたたび自動的な環境設定が続けられる。configureコマンドの実行が終われば,設定は完了だ。

(4)makeする
 次に,makeコマンドを実行し,makeする。

$ make

 この作業にはしばらく時間がかかる。

(5)インストールする
 次にucd-snmpをインストールする。そのためにまず,suコマンドを使い,rootユーザーとしてログオンする。

$ su
Password: rootユーザーのパスワードを入力する

 次にumaskコマンドを次のように実行し,インストールするときにコピーされるファイルが,rootユーザー以外によって不正に書き換えられないようにする。

# umask 022

 次にmake installとし,ucd-snmpをインストールする。

# make install

 以上でucd-snmpのインストールは完了だ。exitコマンドを実行し,rootユーザーから一般ユーザーに戻る。

# exit


SNMPエージェントを動かしてみる
 ucd-snmpをインストールすると,さまざまなファイルがインストールされる。そしてそれらの多くの設定ファイルは,/usr/local/share/snmpディレクトリに置かれ,実行ファイルは/usr/local/sbinディレクトリや/usr/local/binディレクトリに置かれる。

 ucd-snmpに含まれるファイルのうち,SNMPエージェントを構成するのは,snmpdとその設定ファイルであるsnmpd.confファイルだ。そのため,snmpd.confファイルを正しく設定し,snmpdを動作させれば,LinuxマシンがSNMPエージェントとして機能する——つまりほかのマシンからSNMPマネージャを使って管理できる——ようになる。

 snmpd.confファイルは,デフォルトでは用意されていない。そこで管理者が自ら,/usr/local/share/snmpディレクトリにsnmpd.confファイルを作らなければならない。

 snmpd.confファイルの雛形が,ucd-snmp-4.2.1.tar.gzを展開したときに作成されるディレクトリ(ucd-snmp-4.2.1ディレクトリ)にEXAMPLE.confというファイル名で含まれている。そこで,これを/usr/local/share/snmpディレクトリにsnmpd.confという名前でコピーし,それを編集するとよい。

$ su
Password: rootユーザーのパスワードを入力する
# cp EXAMPLE.conf /usr/local/share/snmp/snmpd.conf
# exit

 ここでコピーした/usr/local/share/snmp/snmpd.confファイルをviなどのエディタを使って開き,編集する。以下,snmpd.confファイルに必要な設定項目を説明する。

●コミュニティの設定
 まずは,コミュニティを設定する。コミュニティとは,SNMPにおけるネットワーク範囲のことをいう。コミュニティは,com2sec行で設定する。デフォルトの設定(EXAMPLE.confファイルをコピーしたsnmpd.confファイルの状態)は,次のようになっている。

# sec.name source community
com2sec local localhost COMMUNITY
com2sec mynetwork NETWORK/24 COMMUNITY

 このうちの“NETWORK/24”と書かれている部分を,SNMPマネージャを使いたいネットワーク範囲——いい換えれば管理者がSNMPマネージャを使って管理情報を見るホストが存在するネットワーク——に変更する。多くの場合,LANで使われているネットワークを設定する。

 そしてさらに,“COMMUNITY”の部分を,設定したいコミュニティ名に設定する。コミュニティ名とは,SNMPのパスワードにも該当する設定だ。多くの場合,ローカル環境で使うコミュニティ名には“private”,比較的グローバルな環境で使うコミュニティ名には“public”を使うことが多い。そこで本稿ではそれに倣い,localhost(自分自身)から接続できるコミュニティ名には“private”,LANから接続できるコミュニティ名には“public”と名付けることにする。

 たとえば,192.168.0.0/24192.168.0.0/255.255.255.0と同じ)のネットワークからSNMPマネージャを使って,このマシンを管理できるようにするには,設定を次のように変更する。

# sec.name source community
com2sec local localhost private
com2sec mynetwork 192.168.0.0/24 public

One Point! ここではコミュニティ名にそれぞれ,privatepublicを指定しているが,先にも説明したように,コミュニティ名はパスワードの役割ももつので,実運用するのであれば,別の名前にしておくことを推奨する。また,snmpd.confファイルには,このようにコミュニティ名が記述されるから,rootユーザー以外は参照できない設定にしておくことが望ましい。つまり,“chmod 600 /usr/local/share/snmp/snmpd.conf”を実行しておいたほうがよい。

 もちろんネットワーク全体ではなく,特定のホストからしかSNMPマネージャを使った管理を行わせたくないこともあるだろう。その場合には,そのホストのアドレスを指定すればよい。たとえば次のようにすると,192.168.0.100というIPアドレスをもつホストもしくはlocalhost(SNMPエージェントが動作しているマシン自身)以外からは,SNMPエージェントに接続できなくなる。

# sec.name source community
com2sec local localhost private
com2sec mynetwork 192.168.0.100 public

One Point!com2sec行は,2行分しか書けないわけではなく,必要があれば,何行でもcom2sec行を記述してよい。また,利用許可を与えるホストには,インターネット上にあるホスト名やIPアドレスを指定することもできる。しかしSNMPデータは暗号化されないので(SNMPv3を使えば暗号化できるが本稿では説明しない),インターネット越しにSNMPエージェントとSNMPマネージャが通信することは推奨しない。なぜならば,SNMPデータが途中で盗聴されたり,偽造される可能性があるためだ。


●セキュリティグループの設定
 次に,セキュリティグループを設定する。セキュリティグループは,group行で設定する。デフォルトは次のようになっている。

# 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

 この設定は,MyRWGroupグループとMyROGroupグループの2つのセキュリティグループを作る設定になっている。すぐあとに説明するaccessの設定にて,MyRWGroupグループには管理情報領域の読み書き権限が,MyROGroupグループには管理情報領域の読み取り権限のみが与えられる。

 SNMPでは,SNMPマネージャを使ってSNMPエージェント側の管理情報領域を読み出すだけでなく,管理情報領域内を書き換えることもできる。しかしSNMPは基本的にコミュニティ名での簡単なパスワード識別しか行わないので,適切なセキュリティ対策をとらずにそのまま書き換え許可を与えると,第三者が不正な書き換えをする可能性がある。

 そこで本稿では,より安全にSNMPを使うために,SNMPを使って情報を読み取ることができるが,情報を書き換えることはできないよう設定する。それにはMyRWGroupという部分の行の先頭に“#”を挿入し,次のようにコメントアウトすればよい。

# 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

●ビューの設定
 次に,SNMPエージェント(snmpd)が保持する管理情報領域のうち,どの部分を公開するのかを設定する。その設定をするのがview行だ。デフォルトでは,次のようになっている。

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

 この設定は,すべての情報を見せるという設定だ。詳しくは「SNMPにおける情報取得の基礎」にて説明するが,管理情報領域は階層構造をもつツリー構造になっている。この設定を変更すると,一部の階層以下しか公開しない設定にすることができる。

 LANから利用する場合には,すべての管理情報領域を公開するというデフォルトの設定で問題ない。

●アクセス権限の設定
 次に,どのホストで動作しているSNMPマネージャから,どのような操作を許すのかを設定する。この設定はaccess行で指定する。デフォルトでは,次のようになっている。

# 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

 この設定は,すでにgroupにて設定したMyROGroupグループに読み取り権限を,MyRWGroupグループに書き込み権限を与える設定となっている(ただしgroupの説明において,MyRWGroupグループを定義しているgroup行の行頭に“#”を挿入し,コメント行として無効化しているからMyRWGroupグループは存在しない。つまり読み書きできるグループそのものがない)。通常は,このままの設定でよい。

 よりセキュリティを高めたいのであれば,“noauth”と書かれている部分を“auth”や“priv”に変更すると,コミュニティ名の一致だけでなく,別の認証方式を組み合わせて使うことができるのだが,その説明は本稿では割愛する。

●システム情報の設定
 システム情報を設定する。これは,syslocation行とsyscontact行に設定する。デフォルトでは,次のようになっている。

syslocation Right here, right now.
syscontact Me <me@somewhere.org>

 syslocation行には,このLinuxマシンの場所や用途など,syscontact行には管理者のメールアドレスの情報などをそれぞれ設定する。両者とも,任意の文字列を設定できる。たとえば,次のように変更する。

syslocation Red Hat Linux Server
syscontact Fumitaka Osawa<osawa@example.co.jp>

 syslocation行やsyscontact行そのものを省略したときには,configureコマンドを実行したときに入力した情報が設定されたものとみなされる。

snmpdの起動
 snmpd.confファイルには,以上で説明した以外の設定項目もあるが,説明した部分以外はとりあえずデフォルトのままでかまわない。snmpd.confファイルで設定できるより高度な設定については「ucdavisサブツリー」にて改めて説明する。

 ではsnmpd.confファイルができたところで,SNMPエージェントを動かしてみよう。

 SNMPエージェントを動かすには,rootユーザーとしてログインし,snmpdを実行すればよい。

$ su
Password: rootユーザーのパスワードを入力する
# snmpd
# exit

One Point!snmpdファイルは/usr/local/sbinディレクトリに存在する。パス(PATH)の設定をしていない場合には,フルパスで“/usr/local/sbin/snmpd”と実行する必要がある。

 これでsnmpdが動作し,そのLinuxマシンがSNMPエージェントとして動作したはずである。snmpdが正しく動作したかどうかは,psコマンドを実行すると調べることができる。

$ ps -ax | grep snmpd
30338 pts/0 S 0:00 /usr/local/sbin/snmpd

 一番左のプロセスIDや実行時間などは環境によって異なる。表示結果が/usr/local/sbin/snmpdとなっていれば,snmpdは動作しているので安心してほしい。もし上記のpsコマンドを実行しても何も表示されないときには,snmpdが正しくインストールされていないか,snmpd.confファイルに誤りがある可能性がある。/var/log/snmpd.logにログ情報が書き出されるので,もしうまく動作しなかった場合には,ログ情報を参照して原因を調べていただきたい。

iconSNMPにおける情報取得の基礎

 snmpdが正しく動作したならば,そのLinuxマシンがSNMPエージェントとして動作したことになる。つまり,別のホストからSNMPマネージャを使って,snmpdを動作させたLinuxマシンの情報を取得するというネットワークモニタリングが可能となる。

 つまり,あとは何らかのSNMPマネージャをインストールし,その設定方法や利用方法を理解すればよいわけだ。

 しかしSNMPマネージャを使って情報を監視するためには,SNMPエージェントが保持する管理情報領域にどのようなデータがどのような構造で格納されているのかを知っていなければならない。

 そこで本格的なSNMPマネージャをインストールするまえに,ucd-snmpに付属するSNMPマネージャとして動作する簡単なコマンドを使いながら,管理情報領域の構造を説明する。

OIDツリー
 管理情報領域内では,各情報をオブジェクトとして名前を付けて管理している。そしてそのそれぞれのオブジェクトにOID(Object IDentifier:オブジェクト識別子)というの名前を付けて区別する。OIDは,“1.3.6.1.2.1.1”といったように,ピリオドで区切られた数字として表現され,ピリオドで区切られる各数値は,階層構造をとるツリー構造となっている(Fig.3)。
Fig.3 OIDツリー
fig_03


 どのOIDが割り当てられたオブジェクトにどのような情報が格納されているのかは,あらかじめ定められている。たとえば,“1.3.6.1.2.1.1.4”は管理者のメールアドレス,“1.3.6.1.2.1.1.6”はシステムの場所情報を示すといった具合だ。

 SNMPは,SNMPマネージャからSNMPエージェントに対し,OIDを送ると,そのOIDが割り当てられたオブジェクトに格納されている値が返されるという単純な仕組みで構成される(Fig.4

Fig.4 SNMPによる情報のやりとり
fig_04

 すなわち,SNMPを使う上ではどのようなOIDをもつオブジェクトに,どのような情報が格納されているのかを知ることが重要となる。それが分かれば,SNMPエージェントを通じて機器のさまざまな情報を取得できるのだ。

 逆にいえば,どのOIDをもつオブジェクトにどのような情報が格納されているのかを知らなければ,SNMPは何の意味もなさない。たとえば,SNMPを使ってネットワークのトラフィック情報を取得したい場合,ネットワークのトラフィック情報がどのOIDが割り当てられたオブジェクトに格納されているのかを知らなければ,いくらSNMPエージェントとSNMPマネージャが正しく動作していたとしても,トラフィック情報を取得できない。

 ucd-snmpが対応する管理領域情報は,次の4種類だ。

  1. RFC1213で定義されるmib-2サブツリー

  2. ucd-snmpが独自に定義するucdavisサブツリー

  3. RFC1514で定義されるHost Resourceの初期化情報(内容は空)

  4. RFC2571〜RFC2976で定義されるSNMPv3のMIB

 これらの管理領域情報は,数がかなり多く,到底ここで紹介することはできない。そこで本稿では,よく使われる1.と2.のみを説明する。

●OIDツリーの一覧を得る
 オブジェクトのツリー構造を知るには,snmpdと接続して,snmpdがもっている管理情報領域内のオブジェクトの一覧を参照しておくとより理解が早いだろう。

 ucd-snmpには,特定の階層ツリー以下のオブジェクトを一覧表示するsnmpwalkというコマンドが用意されている。snmpwalkコマンドは,次の書式で用いる

snmpwalk ホスト名コミュニティ名OID

One Point!snmpwalkコマンドやすぐあとに説明するsnmpgetコマンドの実行にあたり,root権限は必要ない。

 ホスト名には接続したいSNMPエージェントのホスト名またはIPアドレスを,コミュニティ名には接続に使うコミュニティ名を指定する。ここで指定するコミュニティ名は,snmpd.confファイル内のcom2secで指定したものだ。OIDには,取得したい階層ツリーとなるオブジェクトのOIDの先頭に“.”(ピリオド)を付けて指定する。すべてのオブジェクトを取得したければ,OIDとして単に“.”を指定すればよい。もし特定のツリー以下を表示したいのであれば,そのツリーのオブジェクトのOIDを指定する。たとえばFig.3に示したmib-2サブツリー以下を取得したいのであれば,“.1.3.6.1.2.1”というOIDを指定する。


One Point! OIDの先頭に“.”を付けるのはsnmpwalkコマンドの仕様的な問題だ(後述するsnmpgetコマンドも同様)。先頭の“.”を省略した場合,“1.3.6.1.2.”が省略されたものとみなされる。また,OIDの代わりに,英字名を使うこともできる。たとえば,mib-2サブツリーを示すのに“.iso.org.dod.internet.mgmt.mib-2”と指定してもよい。

 たとえば,localhost(自分自身)に対して,コミュニティ名privateで接続し,全ツリーの一覧を取得するには,次のようにする。

$ snmpwalk localhost private .

One Point!snmpwalkコマンドは/usr/local/binに格納されている。パスが通っていない場合には,/usr/local/bin/snmpwalkとフルバスで実行すればよい。後述するsnmpgetコマンドも同様だ。

 すると,次のように,全ツリーの一覧が表示される。

system.sysDescr.0 = Linux tiger.example.co.jp 2.2.14-5.0 #1 Tue Mar 7 21:07:39 EST 2000 i686
system.sysObjectID.0 = OID: enterprises.ucdavis.ucdSnmpAgent.linux
system.sysUpTime.0 = Timeticks: (40995719) 4 days, 17:52:37.19
system.sysContact.0 = Fumitaka Osawa <osawa@example.co.jp>
system.sysName.0 = tiger.example.co.jp
system.sysLocation.0 = Red Hat Linux Server
system.sysORLastChange.0 = Timeticks: (0) 0:00:00.00
system.sysORTable.sysOREntry.sysORID.1 = OID: ifMIB
system.sysORTable.sysOREntry.sysORID.2 = OID: .iso.org.dod.internet.snmpV2.snmpM
odules.snmpMIB
system.sysORTable.sysOREntry.sysORID.3 = OID: tcpMIB
system.sysORTable.sysOREntry.sysORID.4 = OID: ip
system.sysORTable.sysOREntry.sysORID.5 = OID: udpMIB
…以下略…

One Point!snmpwalkコマンドやsnmpgetコマンドに“-On”オプションを指定して実行すると,OIDを英文字の形ではなく数字で表示することもできる。


mib-2サブツリー
 mib-2サブツリー以下には,IPプロトコルにおける汎用的な管理情報を保持するオブジェクトが含まれている。mib-2サブツリーの構造はRFC1213で定義されており,SNMPに対応するほとんどのネットワーク機器は,mib-2サブツリーをサポートしている。

 mib-2サブツリーには,OID“1.3.6.1.2.1”が割り当てられている。そしてその配下には,Table 1に示す10個のサブツリーが存在する(Fig.5)。たとえば,systemサブツリーのOIDは“1.3.6.1.2.1.1”,interfacesサブツリーのOIDは“1.3.6.1.2.1.2”のようになる。

 以下,各サブツリーを解説する。


One Point!mib-2サブサリーには,Table 1に示したもの以外にもいくつかのサブツリーがある。しかし本稿ではRFC1213で示されている範囲しか説明しない。
Table 1 mib-2サブツリー(1.3.6.1.2.1
OID 1.3.6.1.2.1.1
サブツリー名 system
用途 システム(SNMPエージェント)に関する情報が格納される
OID 1.3.6.1.2.1.2
サブツリー名 interfaces
用途 インタフェース情報に関する情報が格納される
OID 1.3.6.1.2.1.3
サブツリー名 at
用途 IPアドレスと物理的なアドレスとの変換テーブルが格納される。現在は,同じ内容の情報が,ipサブツリーやtransmissionサブツリーのほうに存在するので,atサブツリーの使用は推奨されない
OID 1.3.6.1.2.1.4
サブツリー名 ip
用途 IPに関する情報が格納される
OID 1.3.6.1.2.1.5
サブツリー名 icmp
用途 ICMPに関する情報が格納される
OID 1.3.6.1.2.1.6
サブツリー名 tcp
用途 TCPに関する情報が格納される
OID 1.3.6.1.2.1.7
サブツリー名 udp
用途 UDPに関する情報が格納される
OID 1.3.6.1.2.1.8
サブツリー名 egp
用途 EGP(Exteior Gateway Protocol)に関する情報が格納される
OID 1.3.6.1.2.1.9
サブツリー名 transmission
用途 ネットワークの送受信をするモジュール(トランスミッタ)に関する情報が格納される。snmpdでは未サポート
OID 1.3.6.1.2.1.11
サブツリー名 snmp
用途 SNMPに関する情報が格納される
Fig.5 mib-2サブツリーの階層構造
fig_05


systemサブツリー(1.3.6.1.2.1.1
 systemサブツリーの配下には,システム情報を保持するオブジェクトが含まれる(Table 2)。
Table 2 systemサブツリー(1.3.6.1.2.1.1
OID 1.3.6.1.2.1.1.1
サブツリー名 sysDescr
用途 機器に関する説明文字。uname -aコマンドの実行結果が格納される
OID 1.3.6.1.2.1.1.2
サブツリー名 sysObjectID
用途 機器の開発会社固有のOID
OID 1.3.6.1.2.1.1.3
サブツリー名 sysUpTime
用途 SNMPエージェントが起動してからの時間が100分の1秒単位で格納される
OID 1.3.6.1.2.1.1.4
サブツリー名 sysContact
用途 機器の管理者のメールアドレス。snmpd.confファイルのsyscontactでの設定値
OID 1.3.6.1.2.1.1.5
サブツリー名 sysName
用途 機器のFQDN(完全修飾ドメイン名)
OID 1.3.6.1.2.1.1.6
サブツリー名 sysLocation
用途 機器の場所。snmpd.confファイルのsyslocationでの設定値
OID 1.3.6.1.2.1.1.7
サブツリー名 sysServices
用途 機器がサポートする設定フラグ。デフォルトでは存在しない。snmpd.confファイルのsysservices行で設定できる。snmpdの場合のsysServicesの推奨値は72。詳細はRFC1213を参照

snmpgetコマンドを使って情報を取得する
 それでは,Table 2に示したsystemサブツリーの各情報を取得してみよう。ucd-snmpには,特定のOIDが割り当てられたオブジェクトの値を取得するためのsnmpgetというコマンドが用意されている。snmpgetコマンドは,次の書式で使う。

snmpget ホスト名コミュニティ名OID

 書式を見るとわかるように,使い方は先に説明したsnmpwalkコマンドと同じだ。OIDにはオブジェクトに割り当てられたOIDを指定する。ただし,snmpwalkコマンドと同様,OIDの先頭には“.”を付ける。

 しかしここで指定するOIDは,Table 2に示した値をそのまま利用するのではない。というのは,Table 2に指定したものは,階層ツリーのOIDであって,オブジェクトそのもののOIDではないのだ。

 SNMPでは,1つの項目に複数の値が設定されることがある。たとえばネットワークの受信バイト数を保持するということを考えてみる。ネットワーク機器に1つのネットワークインタフェース(ネットワークカード)しか装着されていなければ,その情報の保存場所は1つでよい。つまり1つのオブジェクトで足りる。しかし複数のネットワークインタフェースをもつ場合には,そのネットワークインタフェースの数だけ保存場所——すなわちオブジェクト——が必要になる。

 そこでSNMPでは,OIDの後ろにピリオドで区切って,そのインデックス番号を指定する決まりになっている。つまり,1枚目のネットワークカードであれば“.1”,2枚目のネットワークカードであれば“.2”といった数値を付けてオブジェクトそのものを差すのだ。


One Point! ただしこのインデックス番号は,必ずしも1から始まる連番とは限らない。すぐあとに出てくるが,インデックス番号がIPアドレス(aaa.bbb.ccc.dddのような4つの数値がピリオドで区切られた形式)であったりすることもある。どのようなインデックス番号が振られるのかは,OIDを定義するファイルに記されている。その書式は,ASN.1という書式だ。ASN.1の書式はやや複雑であり,詳細な説明をすることはここではできない。そのため,どのようなインデックス番号が振られるのかについては,オブジェクトの説明の都度,具体例を示すだけに留める。

 このような決まりは,値が1つしか格納されないオブジェクトに関しても例外ではない。値が1つしか格納されないオブジェクトの場合には,後ろに“.0”を付けてオブジェクト自身を示すことになっている。

 Table 2に示したsystemサブツリー内に含まれるオブジェクトは,すべて値を1つしか含まない(つまりインデックスをもたない)。よって,たとえばsysDescrオブジェクトの値を取得したいのであれば,“1.3.6.1.2.1.1.1”に“.0”を加えた“1.3.6.1.2.1.1.1.0”というOIDを,sysObjectIDオブジェクトの値を取得したいのであれば同様に“1.3.6.1.2.1.1.2.0”というOIDをそれぞれ指定することになる。

 では,実際にsnmpgetコマンドを使って,情報を取得してみよう。ここでは,sysDescrオブジェクトの値を取得してみる。その場合,次のようにsnmpgetコマンドを実行すればよい。

$ snmpget localhost private .1.3.6.1.2.1.1.1.0
system.sysDescr.0 = Linux tiger.example.co.jp 2.2.14-5.0 #1 Tue Mar 7 21:07:39 EST 2000 i686

 実行結果を見るとわかるように,確かに,sysDescrオブジェクトにはOSの情報が格納されていることがわかる。

 同様にして別のOIDを指定すれば,Table 2に示した各オブジェクトの値を取得することもできる。各自試していただきたい。

interfacesサブツリー(1.3.6.1.2.1.2
 インタフェースの情報を保持するサブツリーだ。このサブツリーには,Table 3に示す各サブツリーが含まれる。
Table 3 interfacesサブツリー(1.3.6.1.2.1.2
OID 1.3.6.1.2.1.2.1
サブツリー名 ifNumber
用途 ネットワークインタフェースの数。ループバック(lo127.0.0.1)も含まれるので,1枚のネットワークカードを装着している場合,値は2となる
OID 1.3.6.1.2.1.2.2
サブツリー名 ifTable
用途 配下にifEntryサブツリーを含むための階層ツリー。値はない
OID 1.3.6.1.2.1.2.2.1
サブツリー名 ifEntry
用途 配下に各インタフェースの情報(下に示すifIndexifDescrなど)を含むための階層ツリー。値はない
OID 1.3.6.1.2.1.2.2.1.1.x
サブツリー名 ifIndex
用途 各インタフェースに割り当てられる固有の値。インデックス番号。1〜ifNumberまでのいずれかの値。xと同じ値である
OID 1.3.6.1.2.1.2.2.1.2.x
サブツリー名 ifDescr
用途 各インタフェースの説明文。“eth0”,“lo”など
OID 1.3.6.1.2.1.2.2.1.3.x
サブツリー名 ifType
用途 各インタフェースの種類。Ethernetの場合には6,ループバックの場合は24,PPPの場合は23など。すべての値についてはRFC1213を参照
OID 1.3.6.1.2.1.2.2.1.4.x
サブツリー名 ifMtu
用途 各インタフェースのMTUの値
OID 1.3.6.1.2.1.2.2.1.5.x
サブツリー名 ifSpeed
用途 各インタフェースがサポートする帯域速度(bps)
OID 1.3.6.1.2.1.2.2.1.6.x
サブツリー名 ifPhysAddress
用途 各インタフェースの物理アドレス。たとえばインタフェースカードのMACアドレスなど
OID 1.3.6.1.2.1.2.2.1.7.x
サブツリー名 ifAdminStatus
用途 各インタフェースの設定情報。アップリンク(1),ダウンリンク(2),テスト中(3)のいずれかの値
OID 1.3.6.1.2.1.2.2.1.8.x
サブツリー名 ifOperStatus
用途 各インタフェースの現在の情報。アップリンク(1),ダウンリンク(2),テスト中(3)のいずれか
OID 1.3.6.1.2.1.2.2.1.9.x
サブツリー名 ifLastChange
用途 各インタフェースがifOperStatusで示された状態に入ったときのsysUpTimeオブジェクト(systemサブツリー以下にある)の値
OID 1.3.6.1.2.1.2.2.1.10.x
サブツリー名 ifInOctets
用途 各インタフェースが受信した総バイト数
OID 1.3.6.1.2.1.2.2.1.11.x
サブツリー名 ifInUcastPkts
用途 各インタフェースが受信したユニキャストパケットのパケット総数
OID 1.3.6.1.2.1.2.2.1.12.x
サブツリー名 ifInNUcastPkts
用途 各インタフェースが受信したユニキャストではないパケット(ブロードキャストパケットなど複数のホストに同時に転送するパケット)のパケット総数
OID 1.3.6.1.2.1.2.2.1.13.x
サブツリー名 ifInDiscards
用途 各インタフェースが受信時に破棄したパケットの総数(エラーパケットは除く)
OID 1.3.6.1.2.1.2.2.1.14.x
サブツリー名 ifInErrors
用途 各インタフェースが受信したエラーパケットの総数
OID 1.3.6.1.2.1.2.2.1.15.x
サブツリー名 ifInUnknownProtos
用途 各インタフェースが受信したパケットのうちプロトコル不明で破棄したパケットの総数
OID 1.3.6.1.2.1.2.2.1.16.x
サブツリー名 ifOutOctets
用途 各インタフェースが送信した総バイト数
OID 1.3.6.1.2.1.2.2.1.17.x
サブツリー名 ifOutUcastPkts
用途 各インタフェースが送信したユニキャストパケットのパケット総数
OID 1.3.6.1.2.1.2.2.1.18.x
サブツリー名 ifOutNUcastPkts
用途 各インタフェースが送信したユニキャストではないパケット(ブロードキャストパケットなど)のパケット総数
OID 1.3.6.1.2.1.2.2.1.19.x
サブツリー名 ifOutDiscards
用途 各インタフェースが送信時に破棄したパケットの総数(エラーパケットは除く)
OID 1.3.6.1.2.1.2.2.1.20.x
サブツリー名 ifOutErrors
用途 各インタフェースが送信したエラーパケットの総数
OID 1.3.6.1.2.1.2.2.1.21.x
サブツリー名 ifOutQLen
用途 各インタフェースの出力バッファに溜まっている出力待ちパケットの数
OID 1.3.6.1.2.1.2.2.1.22.x
サブツリー名 ifSpecific
用途 各インタフェースの追加情報を保存しているオブジェクトのOID。追加情報がない場合,“0.0”が設定される
xはインタフェースのインデックス番号。最初のインタフェースから順に,1,2,…となる。

 interfacesサブツリーの配下には,ネットワークの情報を保持するオブジェクトが含まれるので,SNMPを使ってネットワークの帯域情報を調べる場合には,頻繁に利用される。

 interfacesサブツリーは,オブジェクトが配列のような階層構造になっていて,少々わかりにくい。そこで少し具体例を挙げて説明する。

 まず装着されているインタフェースの総数は,ifNumberオブジェクト(1.3.6.1.2.1.2.1)に格納されている。この値は,snmpgetコマンドを次のように使えば取得できる。

$ snmpget localhost private .1.3.6.1.2.1.2.1.0
interfaces.ifNumber.0 = 2

 取得できるインタフェースの数には,ループバックインタフェース(lo)も含まれるので,実際に装着しているインタフェースの数よりも1つ多い数になる。もちろんPPPやSLIPをインストールしていれば,それも数として数えられる。

 各インタフェースの情報は,“1.3.6.1.2.1.2.2.1.情報番号.インタフェース番号”となる(Table 3を参照)。たとえば,1番目のインタフェースの送信バイト数(情報番号16:“1.3.6.1.2.1.2.1.16.インタフェース番号”)を得るには,次のようにする。

$ snmpget localhost private .1.3.6.1.2.1.2.2.1.16.1
interfaces.ifTable.ifEntry.ifOutOctets.1 = Counter32: 1446493

 もちろん表示される値(送信バイト数)は,そのインタフェースが実際に送信したバイト数だから,上に表記した値になるとは限らない。上の結果は,1番目のインタフェースが,1446493バイトを送信したという統計情報を表示しただけに過ぎない。

 同様にして,2番目のインタフェースの送信バイト数を取得したいのであれば,次のようにすればよい。

$ snmpget localhost private .1.3.6.1.2.1.2.2.1.16.2
interfaces.ifTable.ifEntry.ifOutOctets.2 = Counter32: 235041

 このように,interfacesサブツリーは,最後にインタフェース番号を“.”で区切って付けることにより,それぞれのインタフェースに関する情報を取得することができるようになっている。

 しかしこのような配列のように構成されている情報を1つ1つ取得してゆくのは面倒なので,snmpgetコマンドを使うよりも,snmpwalkコマンドを使ってinterfacesサブツリー以下の一覧をすべて取得してしまったほうが簡単だろう。それには,snmpwatlkコマンドで,interfacesサブツリーのOIDである“1.3.6.1.2.1.2”を指定すればよい(List 1)。

atサブツリー(1.3.6.1.2.1.3
 atサブツリーの配下には,IPアドレスと物理的なアドレス(MACアドレスなど)との対応表を保持するオブジェクトが含まれる。しかしRFC1213では,atサブツリーは非推奨となっており,過去との互換性のためだけに使われる。よって本稿での説明は割愛する。

 IPネットワークの場合,次に説明するipサブツリー1.3.6.1.2.1.4)のipNetToMediaTableサブツリー(1.3.6.1.2.4.22)以下に,IPアドレスと物理的なアドレスとの対応表を含むオブジェクトが存在するので,必要があればそちらの情報を利用すればよい。

ipサブツリー(1.3.6.1.2.1.4
 ipサブツリーは,IP情報を保持する階層ツリーだ。interfacesサブツリー1.3.6.1.2.1.3)と同じく,ネットワークを流れるパケット数のほか,各インタフェースに割り当てられたIPアドレスや物理アドレス,そして,ルーティング情報なども保存されている。ipサブツリーはTable 4に示すように,多大なオブジェクトを含む。
Table 4 ipサブツリー(1.3.6.1.2.1.4
OID 1.3.6.1.2.1.4.1
サブツリー名 ipForwarding
用途 ゲートウェイとして動作し,パケット中継がされているかどうかのフラグ。1で中継していることを,0で中継していないことを示す。たとえば2枚のネットワークカードを装着し,ゲートウェイとして動作させている場合には,1となる
OID 1.3.6.1.2.1.4.2
サブツリー名 ipDefaultTTL
用途 IPパケットのTTL(生存時間)に設定されるデフォルト値
OID 1.3.6.1.2.1.4.3
サブツリー名 ipInReceives
用途 全インタフェースを通じて取得したパケットの総数(エラーパケットも含む)
OID 1.3.6.1.2.1.4.4
サブツリー名 ipInHdrErrors
用途 全インタフェースを通じて取得したパケットのうち,ヘッダにエラーがあったために破棄したパケット数
OID 1.3.6.1.2.1.4.5
サブツリー名 ipInAddrErrors
用途 全インタフェースを通じて取得したパケットのうち,宛先のIPアドレスが無効であったために破棄したパケット数
OID 1.3.6.1.2.1.4.6
サブツリー名 ipForwDatagrams
用途 (ゲートウェイとして動作しているときに)中継したパケットの総数
OID 1.3.6.1.2.1.4.7
サブツリー名 ipInUnknownProtos
用途 全インタフェースを通じて取得したパケットのうち,プロトコルが不明であったため破棄したパケット数
OID 1.3.6.1.2.1.4.8
サブツリー名 ipInDiscards
用途 パケットを受信したものの,受信バッファ不足などで破棄してしまったパケット数
OID 1.3.6.1.2.1.4.9
サブツリー名 ipInDelivers
用途 正常に受け取ったIPパケット(ICMP含む)の総数
OID 1.3.6.1.2.1.4.10
サブツリー名 ipOutRequests
用途 送信を試みたIPパケット(ICMP)の総数(中継パケットは含まない)
OID 1.3.6.1.2.1.4.11
サブツリー名 ipOutDiscards
用途 送信バッファ不足などで送信できなかったパケットの総数
OID 1.3.6.1.2.1.4.12
サブツリー名 ipOutNoRoutes
用途 送信先への経路(ルーティング情報)が不明であるため送信できなかったパケットの総数
OID 1.3.6.1.2.1.4.13
サブツリー名 ipReasmTimeout
用途 フラグメントされたパケットを再構築するためにバッファに保持しておく最大秒数
OID 1.3.6.1.2.1.4.14
サブツリー名 ipReasmReqds
用途 フラグメントの再構築が必要とされたパケット数
OID 1.3.6.1.2.1.4.15
サブツリー名 ipReasmOKs
用途 フラグメントが正しく再構築できたパケット数
OID 1.3.6.1.2.1.4.16
サブツリー名 ipReasmFails
用途 フラグメントが正しく再構築できなかったパケット数
OID 1.3.6.1.2.1.4.17
サブツリー名 ipFragOKs
用途 正しくフラグメントされたパケット数
OID 1.3.6.1.2.1.4.18
サブツリー名 ipFragFails
用途 正しくフラグメントできなかったパケット数
OID 1.3.6.1.2.1.4.19
サブツリー名 ipFragCreates
用途 作成されたフラグメントパケット数
OID 1.3.6.1.2.1.4.20
サブツリー名 ipAddrTable
用途 IPアドレス情報を含む階層ツリー。下位にipAddrEntryサブツリーを含む。値はない。機器に設定されているIPアドレスの数だけ配列状に構成される
OID 1.3.6.1.2.1.4.20.1
サブツリー名 ipAddrEntry
用途 下位にIPアドレス情報を含むための階層ツリー。値はない
OID 1.3.6.1.2.1.4.20.1.aaa.bbb.ccc.ddd
サブツリー名 ipAdEntAddr
用途 それぞれのIPアドレス。値はaaa.bbb.ccc.ddd。これが配列のインデックス値になる
OID 1.3.6.1.2.1.4.20.2.aaa.bbb.ccc.ddd
サブツリー名 ipAdEntIfIndex
用途 このIPアドレスに割り当てられているインタフェースのインデックス番号。interfacesサブツリー下にあるifIndexの値と同じ
OID 1.3.6.1.2.1.4.20.3.aaa.bbb.ccc.ddd
サブツリー名 ipAdEntNetMask
用途 このIPアドレスに設定されたサブネットマスク値
OID 1.3.6.1.2.1.4.20.4.aaa.bbb.ccc.ddd
サブツリー名 ipAdEntBcastAddr
用途 このIPアドレスに設定されたブロードキャストアドレスの値
OID 1.3.6.1.2.1.4.20.5.aaa.bbb.ccc.ddd
サブツリー名 ipAdEntReasmMaxSize
用途 このIPアドレスを通じて送受信できるIPデータグラムの最大バイト数(フラグメントが必要とされる限界バイト数)
OID 1.3.6.1.2.1.4.21
サブツリー名 ipRouteTable
用途 IPルーティング情報を含む階層ツリー。下位にipRouteTableサブツリーを含む。値はない。機器に設定されているルーティング情報の数だけ配列状に構成される
OID 1.3.6.1.2.1.4.21.1
サブツリー名 ipRouteEntry
用途 下位にルーティング情報を含むための階層ツリー。値はない
OID 1.3.6.1.2.1.4.21.1.aaa.bbb.ccc.ddd
サブツリー名 ipRouteDest
用途 ルーティング情報の到達先のIPアドレス。値はaaa.bbb.ccc.ddd。デフォルトゲートウェイの場合,0.0.0.0。これが配列のインデックス値になる
OID 1.3.6.1.2.1.4.21.2.aaa.bbb.ccc.ddd
サブツリー名 ipRouteIfIndex
用途 このルーティング情報に関連するインタフェースのインデックス番号。interfacesサブツリー下にあるifIndexの値と同じ
OID 1.3.6.1.2.1.4.21.3.aaa.bbb.ccc.ddd
サブツリー名 ipRouteMetric1
用途 このルーティング情報のメトリック値(優先順位)
OID 1.3.6.1.2.1.4.21.4.aaa.bbb.ccc.ddd
サブツリー名 ipRouteMetric2
用途 このルーティング情報の代替メトリック値その1
OID 1.3.6.1.2.1.4.21.5.aaa.bbb.ccc.ddd
サブツリー名 ipRouteMetric3
用途 このルーティング情報の代替メトリック値その2
OID 1.3.6.1.2.1.4.21.6.aaa.bbb.ccc.ddd
サブツリー名 ipRouteMetric4
用途 このルーティング情報の代替メトリック値その3
OID 1.3.6.1.2.1.4.21.7.aaa.bbb.ccc.ddd
サブツリー名 ipRouteNextHop
用途 このルーティング情報の次の到達先となるIPアドレス。いい換えればゲートウェイのIPアドレス
OID 1.3.6.1.2.1.4.21.8.aaa.bbb.ccc.ddd
サブツリー名 ipRouteType
用途 このルーティング情報のルーティングタイプ。1(その他)2(ルートなし),3(直接),4(非直接。ゲートウェイを経由する場合など)のいずれかの値
OID 1.3.6.1.2.1.4.21.9.aaa.bbb.ccc.ddd
サブツリー名 ipRouteProto
用途 このルーティング情報のルーティングプロトコル。1(その他),2(ローカル,静的なルーティング),5(EGP),6(GGP),8(RIP)など。取りうるすべての値についてはRFC1213を参照のこと
OID 1.3.6.1.2.1.4.21.10.aaa.bbb.ccc.ddd
サブツリー名 ipRouteAge
用途 このルーティング情報が有効になってから経過した秒数
OID 1.3.6.1.2.1.4.21.11.aaa.bbb.ccc.ddd
サブツリー名 ipRouteMask
用途 このルーティング情報のサブネットマスク値。デフォルトゲートウェイの場合,0.0.0.0
OID 1.3.6.1.2.1.4.21.12.aaa.bbb.ccc.ddd
サブツリー名 ipRouteMetric5
用途 このルーティング情報の代替メトリック値その4
OID 1.3.6.1.2.1.4.21.13.aaa.bbb.ccc.ddd
サブツリー名 ipRouteInfo
用途 このルーティング情報の追加情報を示すオブジェクトのOID。追加情報がない場合には0.0
OID 1.3.6.1.2.1.4.22
サブツリー名 ipNetToMediaTable
用途 IPアドレスから物理アドレスに変換するためのマッピングテーブルを含む階層ツリー。下位にipNetToMediaEntry階層ツリーを含む。値はない
OID 1.3.6.1.2.1.4.22.1
サブツリー名 ipNetToMediaEntry
用途 下位にIPアドレスから物理アドレスに変換するための情報を含むための階層ツリー。値はない
OID 1.3.6.1.2.1.4.22.1.1.x.aaa.bbb.ccc.ddd
サブツリー名 ipNetToMediaIfIndex
用途 この変換テーブルに関連するインタフェースのインデックス番号。interfacesサブツリー下にあるifIndexの値と同じ。xの値とも同じ
OID 1.3.6.1.2.1.4.22.1.2.x.aaa.bbb.ccc.ddd
サブツリー名 ipNetToMediaPhysAddress
用途 このIPアドレスに関連付けられる物理アドレス(MACアドレスなど)
OID 1.3.6.1.2.1.4.22.1.3.x.aaa.bbb.ccc.ddd
サブツリー名 ipNetToMediaNetAddress
用途 このIPアドレス自身。aaa.bbb.ccc.dddと同じ
OID 1.3.6.1.2.1.4.22.1.4.x.aaa.bbb.ccc.ddd
サブツリー名 ipNetToMediaType
用途 IPアドレスと物理アドレスとの対応設定方法。1(その他),2(無効),3(動的割り当て),4(静的割り当て)のいずれか
OID 1.3.6.1.2.1.4.23
サブツリー名 ipRoutingDiscards
用途 (動的なルーティングプロトコルを使っている場合に)有効だったが破棄されてしまったルーティングテーブルの総数。
xはインタフェースのインデックス番号。aaa.bbb.ccc.dddはIPアドレス

 ipサブツリーはinterfacesサブツリーと同様に,いくつかの項目がインデックスの付いた階層構造になっている。階層構造をとっているのは,IPアドレス情報が格納されているipAddrTableサブツリー,ルーティング情報が格納されているipRouteTableサブツリー,IPアドレスと物理アドレスとの変換情報が格納されているipNetToMediaTypeサブツリーだ。

 ここでは,ルーティング情報が格納されているipRouteTableサブツリーを見てみよう。ipRouteTableサブツリーには,1.3.6.1.2.1.4.21というOIDが割り当てられている。そこでsnmpwalkコマンドを使って,その一覧を取得してみる。

$ snmpwalk localhost private .1.3.6.1.2.1.4.21
ip.ipRouteTable.ipRouteEntry.ipRouteDest.0.0.0.0 = IpAddress: 0.0.0.0
ip.ipRouteTable.ipRouteEntry.ipRouteDest.127.0.0.0 = IpAddress: 127.0.0.0
ip.ipRouteTable.ipRouteEntry.ipRouteDest.192.168.0.0 = IpAddress: 192.168.0.0
ip.ipRouteTable.ipRouteEntry.ipRouteIfIndex.0.0.0.0 = 2
ip.ipRouteTable.ipRouteEntry.ipRouteIfIndex.127.0.0.0 = 2
ip.ipRouteTable.ipRouteEntry.ipRouteIfIndex.192.168.0.0 = 2
ip.ipRouteTable.ipRouteEntry.ipRouteMetric1.0.0.0.0 = 1
ip.ipRouteTable.ipRouteEntry.ipRouteMetric1.127.0.0.0 = 0
ip.ipRouteTable.ipRouteEntry.ipRouteMetric1.192.168.0.0 = 0
ip.ipRouteTable.ipRouteEntry.ipRouteNextHop.0.0.0.0 = IpAddress: 192.168.0.1
ip.ipRouteTable.ipRouteEntry.ipRouteNextHop.127.0.0.0 = IpAddress: 0.0.0.0
ip.ipRouteTable.ipRouteEntry.ipRouteNextHop.192.168.0.0 = IpAddress: 0.0.0.0
ip.ipRouteTable.ipRouteEntry.ipRouteType.0.0.0.0 = indirect(4)
ip.ipRouteTable.ipRouteEntry.ipRouteType.127.0.0.0 = direct(3)
ip.ipRouteTable.ipRouteEntry.ipRouteType.192.168.0.0 = direct(3)
ip.ipRouteTable.ipRouteEntry.ipRouteProto.0.0.0.0 = local(2)
ip.ipRouteTable.ipRouteEntry.ipRouteProto.127.0.0.0 = local(2)
ip.ipRouteTable.ipRouteEntry.ipRouteProto.192.168.0.0 = local(2)
ip.ipRouteTable.ipRouteEntry.ipRouteMask.0.0.0.0 = IpAddress: 0.0.0.0
ip.ipRouteTable.ipRouteEntry.ipRouteMask.127.0.0.0 = IpAddress: 255.0.0.0
ip.ipRouteTable.ipRouteEntry.ipRouteMask.192.168.0.0 = IpAddress: 255.255.255.0
ip.ipRouteTable.ipRouteEntry.ipRouteInfo.0.0.0.0 = OID: .ccitt.zeroDotZero.0
ip.ipRouteTable.ipRouteEntry.ipRouteInfo.127.0.0.0 = OID: .ccitt.zeroDotZero.0
ip.ipRouteTable.ipRouteEntry.ipRouteInfo.192.168.0.0 = OID: .ccitt.zeroDotZero.

 上は,ネットワークカードを1枚装着していて,そのネットワーク番号が192.168.0.0/24192.168.0.0/255.255.255.255),デフォルトゲートウェイが192.168.0.1の環境でsnmpwalkコマンドを実行した結果だ。

 この結果を見ると,“0.0.0.0”,“192.168.0.0”,“127.0.0.0”という3つの配列要素があることがわかる。これらはそれぞれデフォルトゲートウェイ,192.168.0.0/24のネットワーク,ループバックインタフェースに相当する。このように,ipサブツリーには,それぞれの値が,配列状に保存されている。

 ここではsnmpwalkコマンドを使って,ipサブツリーの下にあるipRouteTableサブツリーを参照したが,もちろん,snmpgetコマンドを使って特定のOIDを指定すれば,その特定のオブジェクトに保存されている値を取得することもできる。

 たとえば,デフォルトゲートウェイとなっているIPアドレスを取得したいとしよう。各ルーティング情報のゲートウェイ情報は,“1.3.6.1.2.1.4.21.1.7.aaa.bbb.ccc.ddd”というOIDをもつオブジェクトに格納されている。aaa.bbb.ccc.dddは,ルーティング情報の到着先となるIPアドレスで,デフォルトゲートウェイの場合には,“0.0.0.0”だ。よって,次のようにsnmpgetコマンドを実行すればよい。

$ snmpget localhost private .1.3.6.1.2.1.4.21.1.7.0.0.0.0
ip.ipRouteTable.ipRouteEntry.ipRouteNextHop.0.0.0.0 = IpAddress: 192.168.0.1

 この結果を見ると,このホストのデフォルトゲートウェイは,192.168.0.1に設定されているということがわかる。

 などといろいろ説明してきたが,小規模なシステムでは,静的なルーティングが設定されることが多く,あまりルーティング情報を監視したい場面はないだろう。

 それよりネットワーク監視として重要なのは,ipInHdrErrors1.3.6.1.2.1.4.4)やipInAddrErrors1.3.6.1.2.1.4.5)といった壊れたり宛先不明となっているパケット数だ。あまりにこれらの数が多いようだと,ネットワークがハードウェア的に不安定であったり,第三者があえて壊れたIPパケットを送信して攻撃を仕掛けているといった状況が考えられるからだ。

icmpサブツリー(1.3.6.1.2.1.5
 icmpサブツリーには,ICMPの情報が含まれる(Table 5)。icmpサブツリーのうち,ネットワーク監視という面から見て,あまり有用なものはない。

 とはいえ,あまりにもICMPメッセージの到着数が多い場合,何者かによってDoS攻撃やDDoS攻撃(分散DOS攻撃)を仕掛けられている可能性がある。よって,インターネットに接続されているサーバーを監視するのであれば,ICMPメッセージの数を定期的に記録しておき,いつもよりも格段と多いICMPメッセージが届いていないかを監視するとよい。

 icmpサブツリーは,配列状に階層化されているわけではなく単なるオブジェクトになっている。よって,すべての値は,各OIDの後ろに“.0”を指定したものをsnmpgetコマンドで指定すれば取得できる。たとえば,受信したICMPメッセージの総数を取得するには,icmpInMsgsオブジェクト(1.3.6.1.2.1.5.1)の値を取得すればよく,次のようにすればよい。

$ snmpget localhost private .1.3.6.1.2.1.5.1.0
icmp.icmpInMsgs.0 = Counter32: 11
Table 5 icmpサブツリー(1.3.6.1.2.1.5
OID 1.3.6.1.2.1.5.1
サブツリー名 icmpInMsgs
用途 受信したICMPメッセージの総数
OID 1.3.6.1.2.1.5.2
サブツリー名 icmpInErrors
用途 受信したICMPメッセージのうちエラーがあったメッセージの総数
OID 1.3.6.1.2.1.5.3
サブツリー名 icmpInDestUnreachs
用途 受信した「Destination Unreachable」メッセージの総数
OID 1.3.6.1.2.1.5.4
サブツリー名 icmpInTimeExcds
用途 受信した「Time Exceeded」メッセージの総数
OID 1.3.6.1.2.1.5.5
サブツリー名 icmpInParmProbs
用途 受信した「Parameter Problem」メッセージの総数
OID 1.3.6.1.2.1.5.6
サブツリー名 icmpInSrcQuenchs
用途 受信した「Source Quench」メッセージの総数
OID 1.3.6.1.2.1.5.7
サブツリー名 icmpInRedirects
用途 受信した「Redirect」メッセージの総数
OID 1.3.6.1.2.1.5.8
サブツリー名 icmpInEchos
用途 受信した「Echo」メッセージの総数
OID 1.3.6.1.2.1.5.9
サブツリー名 icmpInEchoReps
用途 受信した「Echo Reply」メッセージの総数
OID 1.3.6.1.2.1.5.10
サブツリー名 icmpInTimestamps
用途 受信した「Timestamp」メッセージの総数
OID 1.3.6.1.2.1.5.11
サブツリー名 icmpInTimestampReps
用途 受信した「Timestamp Reply」メッセージの総数
OID 1.3.6.1.2.1.6.12
サブツリー名 icmpInAddrMasks
用途 受信した「Address Mask Request」メッセージの総数
OID 1.3.6.1.2.1.6.13
サブツリー名 icmpInAddrMaskReps
用途 受信した「Address Mask Reply」メッセージの総数
OID 1.3.6.1.2.1.6.14
サブツリー名 icmpOutMsgs
用途 送信したICMPメッセージの総数
OID 1.3.6.1.2.1.6.15
サブツリー名 icmpOutErrors
用途 送信したICMPメッセージのうちエラーがあったメッセージの総数
OID 1.3.6.1.2.1.6.16
サブツリー名 icmpOutDestUnreachs
用途 送信した「Destination Unreachable」メッセージの総数
OID 1.3.6.1.2.1.6.17
サブツリー名 icmpOutTimeExcds
用途 送信した「Time Exceeded」メッセージの総数
OID 1.3.6.1.2.1.6.18
サブツリー名 icmpOutParmProbs
用途 送信した「Parameter Problem」メッセージの総数
OID 1.3.6.1.2.1.6.19
サブツリー名 icmpOutSrcQuenchs
用途 送信した「Source Quench」メッセージの総数
OID 1.3.6.1.2.1.6.20
サブツリー名 icmpOutRedirects
用途 送信した「Reditect」メッセージの総数
OID 1.3.6.1.2.1.6.21
サブツリー名 icmpOutEchos
用途 送信した「Echo」メッセージの総数
OID 1.3.6.1.2.1.6.22
サブツリー名 icmpOutEchoReps
用途 送信した「Echo Reply」メッセージの総数
OID 1.3.6.1.2.1.6.23
サブツリー名 icmpOutTimestamps
用途 送信した「Timestamp」メッセージの総数
OID 1.3.6.1.2.1.6.24
サブツリー名 icmpOutTimestampReps
用途 送信した「Timestamp Reply」メッセージの総数
OID 1.3.6.1.2.1.6.25
サブツリー名 icmpOutAddrMasks
用途 送信した「Address Mask Request」メッセージの総数
OID 1.3.6.1.2.1.6.26
サブツリー名 icmpOutAddrMaskReps
用途 送信した「Address Mask Reply」メッセージの総数


tcpサブツリー(1.3.6.1.2.1.6
 tcpサブツリーにはTCP接続に関する情報が格納されている(Table 6)。
Table 6 tcpサブツリー(1.3.6.1.2.1.6
OID 1.3.6.1.2.1.6.1
サブツリー名 tcpRtoAlgorithm
用途 応答が確認できなかったとき,再送までのタイミングを決めるアリゴリズムの種類。詳細はRFC1213を参照
OID 1.3.6.1.2.1.6.2
サブツリー名 tcpRtoMin
用途 再送時に使うタイムアウト時間の最小値(ミリ秒)
OID 1.3.6.1.2.1.6.3
サブツリー名 tcpRtoMax
用途 再送時に使うタイムアウト時間の最大値(ミリ秒)
OID 1.3.6.1.2.1.6.4
サブツリー名 tcpMaxConn
用途 サポートする最大TCPコネクション数
OID 1.3.6.1.2.1.6.5
サブツリー名 tcpActiveOpens
用途 アクティブオープン(CLOSE状態からSYN-SENT状態になった。つまりこちら側から別のホストにコネクションを張った)TCPコネクションの総計
OID 1.3.6.1.2.1.6.6
サブツリー名 tcpPassiveOpens
用途 パッシブオープン(LISTEN状態からSYN-REVD状態になった。つまりこちらが待ち受け状態になっていてほかのホストが接続してきた)TCPコネクションの総計
OID 1.3.6.1.2.1.6.7
サブツリー名 tcpAttemptFails
用途 接続に失敗した総数
OID 1.3.6.1.2.1.6.8
サブツリー名 tcpEstabResets
用途 リセットされた総数
OID 1.3.6.1.2.1.6.9
サブツリー名 tcpCurrEstab
用途 現在の状態がESTABLISHED(接続中)またはCLOSE-WAIT(切断待ち)であるコネクションの総数
OID 1.3.6.1.2.1.6.10
サブツリー名 tcpInSegs
用途 受信したセグメントの総数
OID 1.3.6.1.2.1.6.11
サブツリー名 tcpOutSegs
用途 送信したセグメントの総数
OID 1.3.6.1.2.1.6.12
サブツリー名 tcpRetransSegs
用途 再送したセグメントの総数
OID 1.3.6.1.2.1.6.13
サブツリー名 tcpConnTable
用途 現在張られているTCPコネクションを保持する階層ツリー。下位にtcpConnEntryサブツリーを含む。値はない
OID 1.3.6.1.2.1.6.13.1
サブツリー名 tcpConnEntry
用途 TCPコネクションの状態を保持する階層ツリー。値はない
OID 1.3.6.1.2.1.6.13.1.1.aaa.bbb.
ccc.ddd.ppp.AAA.BBB.CCC.DDD.PPP
サブツリー名 tcpConnState
用途 このコネクションの状態。取りうる値についてはRFC1213を参照
OID 1.3.6.1.2.1.6.13.1.2.aaa.bbb.
ccc
.ddd.ppp.AAA.BBB.CCC.DDD.PPP
サブツリー名 tcpConnLocalAddress
用途 このコネクションのローカル側のIPアドレス。aaa.bbb.ccc.dddと同じ
OID 1.3.6.1.2.1.6.13.1.3.aaa.bbb.
ccc
.ddd.ppp.AAA.BBB.CCC.DDD.PPP
サブツリー名 tcpConnLocalPort
用途 このコネクションのローカル側のポート番号。pppと同じ
OID 1.3.6.1.2.1.6.13.1.4.aaa.bbb.
ccc.ddd.ppp.AAA.BBB.CCC.DDD.PPP
サブツリー名 tcpConnRemAddress
用途 このコネクションのリモート側のIPアドレス。AAA.BBB.CCC.DDDと同じ
OID 1.3.6.1.2.1.6.13.1.5.aaa.bbb.
ccc.ddd.ppp.AAA.BBB.CCC.DDD.PPP
サブツリー名 tcpConnRemPort
用途 このコネクションのリモート側のポート番号。PPPと同じ
OID 1.3.6.1.2.1.6.14
サブツリー名 tcpInErrs
用途 受信したエラーセグメントの総数
OID 1.3.6.1.2.1.6.15
サブツリー名 tcpOutRsts
用途 送信したセグメントのうちRSTフラグを設定したもの(コネクションをリセットした)の総数
aaa.bbb.ccc.dddはローカル側のIPアドレス。pppはローカル側のポート番号。AAA.BBB.CCC.DDDはリモート側のIPアドレス。PPPはリモート側のポート番号。

 tcpサブツリーには,TCPでの送受信セグメント数だけでなく,現在のTCPコネクションの情報も含まれている。現在のTCPコネクションの情報が含まれているのは,tcpConnTableサブツリー(1.3.6.1.2.1.6.13)の配下だ。snmpwalkコマンドを使ってtcpConnTableサブツリーの配下の値を取り出してみるとわかるが,ここにはifconfigコマンドで取得できるような,TCPコネクションの状態が格納されている(List 2)。

 List 2の実行結果では,次のコネクションが用意されていることを示している。

 実際に稼働しているホストでは,この程度の情報では済まず,もっと多数のコネクション情報が表示される。

 このようにtcpConnTableサブツリー(1.3.6.1.2.1.6.13)以下は,次のようなOIDのオブジェクトとして示される。

1.3.6.1.2.1.6.13.1.y.aaa.bbb.ccc.ddd.ppp.
AAA.BBB.CCC.DDD.PPP
y=情報の種別を示す番号
aaa.bbb.ccc.ddd=ローカル側のIPアドレス
ppp=ローカル側のポート番号
AAA.BBB.CCC.DDD=リモート側のIPアドレス
PPP=リモート側のポート番号

 SNMPでは,あらかじめどのようなコネクションが張られているかを知るすべはないから,tcpConnTableサブツリーに対してsnmpgetコマンドを使い,直接オブジェクトのデータを取得することは無意味だ。そのためここで示したように,snmpwalkコマンドなどを使い,tcpConnTableサブツリーの配下に含まれるオブジェクトの一覧を取得することで,現在のコネクションの一覧を得るという方法がとられるのが一般的だ。snmpgetコマンドを使って,1つのオブジェクトの値を取得するという方法は,あまりとられない。

udpサブツリー(1.3.6.1.2.7
 udpサブツリーには,UDPの情報が格納される。構成はtcpサブツリーとよく似ている(Table 7)。ただしUDPは非接続型のプロトコルなので,リモートアドレスという概念はなく,どのポートで待ち受けをしているのかがわかるだけだ。参考までに,snmpwalkコマンドを使ってudpサブツリーを参照したものを以下に記す。
$ snmpwalk localhost private .1.3.6.1.2.1.7
udp.udpInDatagrams.0 = Counter32: 17515
udp.udpNoPorts.0 = Counter32: 5
udp.udpInErrors.0 = Counter32: 0
udp.udpOutDatagrams.0 = Counter32: 17520
udp.udpTable.udpEntry.udpLocalAddress.0.0.0.0.111 = IpAddress: 0.0.0.0
udp.udpTable.udpEntry.udpLocalAddress.0.0.0.0.161 = IpAddress: 0.0.0.0
udp.udpTable.udpEntry.udpLocalAddress.0.0.0.0.162 = IpAddress: 0.0.0.0
udp.udpTable.udpEntry.udpLocalAddress.0.0.0.0.960 = IpAddress: 0.0.0.0
udp.udpTable.udpEntry.udpLocalAddress.0.0.0.0.1024 = IpAddress: 0.0.0.0
udp.udpTable.udpEntry.udpLocalAddress.0.0.0.0.1041 = IpAddress: 0.0.0.0
udp.udpTable.udpEntry.udpLocalPort.0.0.0.0.111 = 111
udp.udpTable.udpEntry.udpLocalPort.0.0.0.0.161 = 161
udp.udpTable.udpEntry.udpLocalPort.0.0.0.0.162 = 162
udp.udpTable.udpEntry.udpLocalPort.0.0.0.0.960 = 960
udp.udpTable.udpEntry.udpLocalPort.0.0.0.0.1024 = 1024
udp.udpTable.udpEntry.udpLocalPort.0.0.0.0.1041 = 1041
Table 7 udpサブツリー(1.3.6.1.7.1
OID 1.3.6.1.6.1.7.1
サブツリー名 udpInDatagrams
用途 受信したUDPデータグラムの総数
OID 1.3.6.1.6.1.7.2
サブツリー名 udpNoPorts
用途 受信したUDPデータグラムのうち,待ち受けていなかったために破棄したデータグラムの総数
OID 1.3.6.1.6.1.7.3
サブツリー名 udpInErrors
用途 受信したUDPデータグラムのうちエラーがあったもののの総数
OID 1.3.6.1.6.1.7.4
サブツリー名 udpOutDatagrams
用途 送信したUDPデータグラムの総数
OID 1.3.6.1.6.1.7.5
サブツリー名 udpTable
用途 UDPデータグラムの待ち受け情報を保持するテーブルを含む階層ツリー。値はない。下位にudpEntryサブツリーを含む
OID 1.3.7.1.6.1.7.5.1
サブツリー名 udpEntry
用途 待ち受けているUDPデータグラムの一覧を含む階層ツリー。値はない
OID 1.3.7.1.6.1.7.5.1.aaa.bbb.
ccc.ddd.ppp
サブツリー名 udpLocalAddress
用途 このUDPデータグラムの待ち受けしているローカル側のIPアドレス。aaa.bbb.ccc.dddと同じ。すべてIPアドレスにおいて待ち受けているならば0.0.0.0
OID 1.3.7.1.6.1.7.5.1.aaa.bbb.
ccc
.ddd.ppp
サブツリー名 udpLocalPort
用途 このUDPデータグラムの待ち受けをしているローカル側のポート番号。pppと同じ
aaa.bbb.ccc.dddはローカル側のIPアドレス。pppはローカル側のポート番号


egpサブツリー(1.3.6.1.6.1.8
 egpサブツリーは,EGP(Expeior Gateway Protocol)に関する情報を保持するオブジェクトが含まれる。EGPは大規模なサイトで使われるものであり,小規模なところではまず使われることがない。よって本稿での解説は割愛する。

transmissionサブツリー(1.3.6.1.6.1.9
 transmissionサブツリーの配下には,ネットワークインターフェースなど,データの送受信をするのに関わるデータが格納される。しかしRFC1213では,その形式はシステム依存とされており,とくに定義されているわけではない。なお,snmpdは,transmissionサブツリーをサポートしていない。

snmpサブツリー(1.3.6.1.6.1.11
 snmpサブツリーには,SNMPに関する情報を保持するオブジェクトが含まれる(Table 8)。snmpサブツリーの情報を使えば,SNMPマネージャを使って,SNMPエージェント自身の情報を調べることができる。具体的には,認証に失敗した回数やエラーが発生した数などが得られる。これらの情報を利用すると,第三者がSNMPを悪用していないかどうかを調べることができる。

 snmpサブツリーの配下にあるオブジェクトは配列状にはなっていない単一のオブジェクトで構成される。よってTable 8に示したOIDの後ろに“.0”を指定すれば,その値を取得できる。たとえば,コミュニティ名が異なるSNMPメッセージが届いた総数——いい換えれば認証に失敗したメッセージ——を取得したいのであれば,snmpInBadCommunityNames1.3.6.1.2.1.4.11.4)オブジェクトの値を調べればよく,snmpgetコマンドを使って,次のようにすればよい。

$ snmpget localhost private .1.3.6.1.2.1.11.4.0
snmp.snmpInBadCommunityNames.0 = Counter32: 0
Table 8 snmpサブツリー(1.3.6.1.6.1.11
OID 1.3.6.1.2.1.11.1
サブツリー名 snmpInPkts
用途 受信したSNMPメッセージの総数
OID 1.3.6.1.2.1.11.2
サブツリー名 snmpOutPkts
用途 送信したSNMPメッセージの総数
OID 1.3.6.1.2.1.11.3
サブツリー名 snmpInBadVersions
用途 サポートしていないバージョンのSNMPメッセージが届いた総数
OID 1.3.6.1.2.1.11.4
サブツリー名 snmpInBadCommunityNames
用途 コミュニティ名が異なっていたSNMPメッセージの総数
OID 1.3.6.1.2.1.11.5
サブツリー名 snmpInBadCommunityUses
用途 権限がないのに操作しようとしたSNMPメッセージの総数
OID 1.3.6.1.2.1.11.6
サブツリー名 snmpInASNParseErrs
用途 OIDの形式が間違っていたSNMPメッセージの総数
OID 1.3.6.1.2.1.11.7
サブツリー名 欠番
用途
OID 1.3.6.1.2.1.11.8
サブツリー名 snmpInTooBigs
用途 「tooBig」エラーがあった受信SNMPメッセージの総数
OID 1.3.6.1.2.1.11.9
サブツリー名 snmpInNoSuchNames
用途 「noSuchName」エラーがあった受信SNMPメッセージの総数
OID 1.3.6.1.2.1.11.10
サブツリー名 snmpInBadValues
用途 「badValue」エラーがあったSNMP受信メッセージの総数
OID 1.3.6.1.2.1.11.11
サブツリー名 snmpInReadOnlys
用途 「readOnly」エラーがあったSNMP受信メッセージの総数
OID 1.3.6.1.2.1.11.12
サブツリー名 snmpInGenErrs
用途 「getErr」があった受信SNMPメッセージの総数
OID 1.3.6.1.2.1.11.13
サブツリー名 snmpInTotalReqVars
用途 値を取り出されたオブジェクトの総数
OID 1.3.6.1.2.1.11.14
サブツリー名 snmpInTotalSetVars
用途 値を変更されたオブジェクトの総数
OID 1.3.6.1.2.1.11.15
サブツリー名 snmpInGetRequests
用途 処理したGet-Requestの総数(snmpgetコマンドやsnmpwalkコマンドによるデータの取り出しなど)
OID 1.3.6.1.2.1.11.16
サブツリー名 snmpInGetNexts
用途 処理したGet-Nextの総数(snmpwalkコマンドにより階層ツリーを辿ったときなど)
OID 1.3.6.1.2.1.11.17
サブツリー名 snmpInSetRequests
用途 処理したSet-Requestの総数(snmpsetコマンドによるデータの設定など)
OID 1.3.6.1.2.1.11.18
サブツリー名 snmpInGetResponses
用途 処理したGet-Responseの総数
OID 1.3.6.1.2.1.11.19
サブツリー名 snmpInTraps
用途 処理したTrapの総数
OID 1.3.6.1.2.1.11.20
サブツリー名 snmpOutTooBigs
用途 「tooBig」エラーがあった送信SNMPメッセージの総数
OID 1.3.6.1.2.1.11.21
サブツリー名 snmpOutNoSuchNames
用途 「noSuchName」エラーがあった送信SNMPメッセージの総数
OID 1.3.6.1.2.1.11.22
サブツリー名 snmpOutBadValues
用途 「badValue」エラーがあった送信SNMPメッセージの総数
OID 1.3.6.1.2.1.11.23
サブツリー名 欠番
用途
OID 1.3.6.1.2.1.11.24
サブツリー名 snmpOutGetErrs
用途 「getErr」があった送信SNMPメッセージの総数
OID 1.3.6.1.2.1.11.25
サブツリー名 snmpOutGetRequests
用途 送信したGet-Requestの総数
OID 1.3.6.1.2.1.11.26
サブツリー名 snmpOutGetNexts
用途 送信したGet-Nextの総数
OID 1.3.6.1.2.1.11.27
サブツリー名 snmpOutSetRequests
用途 送信したSet-Requestの総数
OID 1.3.6.1.2.1.11.28
サブツリー名 snmpOutGetResponses
用途 送信したGetResponseの総数
OID 1.3.6.1.2.1.11.29
サブツリー名 snmpOutTraps
用途 送信したTrapの総数
OID 1.3.6.1.2.1.11.30
サブツリー名 snmpEnableAuthenTraps
用途 認証失敗Trapが許されているかどうか。1のとき許されている,0のとき許されていないことを示す


ucdavisサブツリー
 以上で説明してきたmib-2サブツリーは,ネットワーク機器の汎用的な情報を保持する管理情報領域だ。mib-2サブツリーの配下にあるオブジェクトを参照すれば,ネットワークの回線断やトラフィック情報を得ることができるが,snmpdでは,さらに独自の管理情報領域をもっている。それがこれから説明するucdavisサブツリー(1.3.6.1.4.1.2021)だ。ucdavisサブツリーの配下には,Table 9に示すサブツリーが格納されている。
Table 9 ucdavisサブツリー(1.3.6.1.4.1.2021
OID 1.3.6.1.4.1.2021.2
サブツリー名 prTable
用途 プロセスの状態が格納される
OID 1.3.6.1.4.1.2021.4
サブツリー名 memory
用途 メモリの状態が格納される
OID 1.3.6.1.4.1.2021.8
サブツリー名 extTable
用途 システム上であらかじめ指定しておいたコマンドを実行し,その結果が格納される
OID 1.3.6.1.4.1.2021.9
サブツリー名 dskTable
用途 ディスクの状態が格納される
OID 1.3.6.1.4.1.2021.10
サブツリー名 laTable
用途 システムのロードアベレージ情報が格納される
OID 1.3.6.1.4.1.2021.11
サブツリー名 systemStats
用途 システムの状態が格納される
OID 1.3.6.1.4.1.2021.14
サブツリー名 ucdDemoMIB
用途 ucd-snmpのサンプル
OID 1.3.6.1.4.1.2021.15
サブツリー名 fileTable
用途 あらかじめ指定しておいたファイルのファイルサイズなどが格納される
OID 1.3.6.1.4.1.2021.100
サブツリー名 version
用途 snmpdのバージョン情報が格納される
OID 1.3.6.1.4.1.2021.101
サブツリー名 snmperrs
用途 エラーが発生したときの情報が格納される
OID 1.3.6.1.4.1.2021.102
サブツリー名 mrTable
用途 snmpdにモジュールを組み込んで機能を追加したとき,そのモジュールに関する情報が格納される

 Table 9に示した各サブツリーには,Linux上で動作しているプロセスの情報やメモリ,ディスクの状態,そして特定のコマンドを実行したときの結果を格納することができる。

 どのような情報が取得できるのかは,snmpd.confファイルの設定にも依存する。デフォルトの(EXAMPLE.confファイルをコピーして編集した)snmpd.confファイルの設定は,次のようになっている(一部のコメントなどは省き,必要箇所のみ抜粋した)。

proc mountd
proc ntalkd 4
proc sendmail 10 1
exec echotest /bin/echo hello world
disk / 10000
load 12 14 14

 以下,snmpd.confファイルの設定方法と,ucdavisサブツリーで得られる情報との関係を説明する。

proc
 procの設定では,どのプロセスをSNMPから監視したいのかを指定する。proc行の設定書式は次のようになっている。
proc プロセス名 最大数 最小数

 プロセス名には,SNMPから監視したいプロセス名を,ps -eコマンドの出力で得られる形で指定する。そして,最大数の部分には,「このプロセスが最大いくつ存在する場合にエラーとして記録するのか」,最小数の部分には,「このプロセスが最低いくつ存在しない場合にエラーとして記録するのか」をそれぞれ指定する。最大数を省略した場合には無限大,最小数を省略した場合には1を指定したものとみなされる。

 デフォルトのsnmpd.confファイルには,次のようなproc行がある。

proc mountd
proc ntalkd 4
proc sendmail 10 1

 この意味は次の通りである。

 記録情報は,prTableサブツリー(1.3.6.1.4.1.2021.2)内に含まれる。proc行で指定した情報は,snmpd.confファイルに登場する順番で,先頭から1,2,3,…というインデックス番号が振られる。この例でいえば,mountdが1,ntalkdが2,sendmailが3にそれぞれ対応する。そしてprTableサブツリーには,配列のような形で各データが保存される(Table 10)。

Table 10 prTableサブツリー(1.3.6.1.4.1.2021.2
OID 1.3.6.1.4.1.2021.2.1
サブツリー名 prEntry
用途 プロセスの情報一覧を含むテーブルを構成する階層ツリー。値はない
OID 1.3.6.1.4.1.2021.2.1.1.i
サブツリー名 prIndex
用途 このプロセス情報に割り当てられたインデックス番号。proc行の登場する順に,1,2,…と割り当てられる。iと同じ
OID 1.3.6.1.4.1.2021.2.1.2.i
サブツリー名 prNames
用途 proc行のプロセス名に指定したプロセス名
OID 1.3.6.1.4.1.2021.2.1.3.i
サブツリー名 prMin
用途 proc行の最小値に設定した値
OID 1.3.6.1.4.1.2021.2.1.4.i
サブツリー名 prMax
用途 proc行の最大値に設定した値
OID 1.3.6.1.4.1.2021.2.1.5.i
サブツリー名 prCount
用途 prNamesに指定されたプロセスが現在動いている数
OID 1.3.6.1.4.1.2021.2.1.100.i
サブツリー名 prErrorFlag
用途 エラーとなった場合1が設定される。エラーとなっていない場合0が設定される
OID 1.3.6.1.4.1.2021.2.1.101.i
サブツリー名 prErrMessage
用途 prErrorFlagが1になったとき,エラーメッセージが格納される
OID 1.3.6.1.4.1.2021.2.1.102.i
サブツリー名 prErrFix
用途 管理者がこのオブジェクトに1を設定すると,あらかじめsnmpd.confファイルのprocfix行で指定したコマンドが実行される
OID 1.3.6.1.4.1.2021.2.1.103.i
サブツリー名 prErrFixCmd
用途 prErrFixに1が設定されたときに実行されるコマンド名
iはインデックス番号。snmpd.confファイル中に出てきたproc行の登場順に,先頭から1,2,3,…という値。

 snmpd.confファイルのproc行の設定で指定した条件がエラーとなった場合,1.3.6.1.4.1.2021.2.1.100.iの値が1となり,そのエラーメッセージが1.3.6.1.4.1.2021.2.1.101.iに格納される(iはインデックス番号)。デフォルトのsnmpd.confファイルの設定であれば,次のような動作をすることになる。

 このようにproc行を指定するとプロセスの状態が監視できるので,SNMPを通じて,特定のプロセスが何らかのトラブルにより消滅してしまったり,処理の増加により予想以上に増えてしまったりしたときの情報を取得できるというわけだ。

 proc行をどのように設定すればよいのかは,Linux上で動作しているどのプロセスを監視したいのかによる。たとえば,デフォルトの設定をすべてコメントアウト(先頭に“#”を挿入する)し,sendmailhttpdnamedsyslogdの4つのプロセスを管理するには,次のようにproc行を設定すればよい

proc sendmail 10 1
proc httpd 20 1
proc named
proc syslogd

 snmpd.confファイルを変更した場合,それを反映させるためには,snmpdに対してkill -HUPを実行しなければならない。kill -HUPを実行するには,次のようにする。

$ ps -ax | grep snmpd <--- プロセス番号を調べる
30711 ? S 0:14 [snmpd] <--- プロセス番号は30711
$ su <--- rootユーザーとしてログインする
Password: rootユーザーのパスワードを入力する
# kill -HUP 30711 <--- psコマンドで参照したプロセス番号に対してkill -HUPを実行する
# exit <--- 一般ユーザーに戻る

 snmpd.confファイルをこのように変更した場合,prTableサブツリー(1.3.6.1.4.2021.2.1)以下をsnmpwalkコマンドで取得すると,次のようになる。

$ snmpwalk localhost private .1.3.6.1.4.1.2021.2.1
enterprises.ucdavis.prTable.prEntry.prIndex.1 = 1
enterprises.ucdavis.prTable.prEntry.prIndex.2 = 2
enterprises.ucdavis.prTable.prEntry.prIndex.3 = 3
enterprises.ucdavis.prTable.prEntry.prIndex.4 = 4
enterprises.ucdavis.prTable.prEntry.prNames.1 = sendmail
enterprises.ucdavis.prTable.prEntry.prNames.2 = httpd
enterprises.ucdavis.prTable.prEntry.prNames.3 = named
enterprises.ucdavis.prTable.prEntry.prNames.4 = syslogd
enterprises.ucdavis.prTable.prEntry.prMin.1 = 1
enterprises.ucdavis.prTable.prEntry.prMin.2 = 1
enterprises.ucdavis.prTable.prEntry.prMin.3 = 0
enterprises.ucdavis.prTable.prEntry.prMin.4 = 0
enterprises.ucdavis.prTable.prEntry.prMax.1 = 10
enterprises.ucdavis.prTable.prEntry.prMax.2 = 20
enterprises.ucdavis.prTable.prEntry.prMax.3 = 0
enterprises.ucdavis.prTable.prEntry.prMax.4 = 0
enterprises.ucdavis.prTable.prEntry.prCount.1 = 1
enterprises.ucdavis.prTable.prEntry.prCount.2 = 0
enterprises.ucdavis.prTable.prEntry.prCount.3 = 0
enterprises.ucdavis.prTable.prEntry.prCount.4 = 1
enterprises.ucdavis.prTable.prEntry.prErrorFlag.1 = 0
enterprises.ucdavis.prTable.prEntry.prErrorFlag.2 = 1
enterprises.ucdavis.prTable.prEntry.prErrorFlag.3 = 1
enterprises.ucdavis.prTable.prEntry.prErrorFlag.4 = 0
enterprises.ucdavis.prTable.prEntry.prErrMessage.1 =
enterprises.ucdavis.prTable.prEntry.prErrMessage.2 = Too few httpd running (# = 0)
enterprises.ucdavis.prTable.prEntry.prErrMessage.3 = No named process running.
enterprises.ucdavis.prTable.prEntry.prErrMessage.4 =
enterprises.ucdavis.prTable.prEntry.prErrFix.1 = 0
enterprises.ucdavis.prTable.prEntry.prErrFix.2 = 0
enterprises.ucdavis.prTable.prEntry.prErrFix.3 = 0
enterprises.ucdavis.prTable.prEntry.prErrFix.4 = 0
enterprises.ucdavis.prTable.prEntry.prErrFixCmd.1 =
enterprises.ucdavis.prTable.prEntry.prErrFixCmd.2 =
enterprises.ucdavis.prTable.prEntry.prErrFixCmd.3 =
enterprises.ucdavis.prTable.prEntry.prErrFixCmd.4 =

 上の結果は,snmpwalkコマンドを実行したときに,sendmailsyslogdは動いているけれどもhttpdnamedは動いていないという状況を示したものだ。この結果を見るとわかるように,httpdに相当する2番目の項目とnamedに相当する3番目の項目に相当する,“1.3.6.1.4.1.2021.2.1.100.2”と“1.3.6.1.4.1.2021.2.1.100.3”は1となり,“1.3.6.1.4.1.2021.2.1.101.2”と“1.3.6.1.4.1.2021.2.1.101.3”にはエラーメッセージが格納されていることが確認できる。

 なおsnmpdでは,snmpd.confファイルにprocfix行をあらかじめ設定しておくと,管理者がprErrFixオブジェクト(1.3.6.1.4.1.2021.2.1.102.i)に1を書き込んだときに(値を書き込むにはsnmpsetというコマンドが使える),procfix行で定義しておいたプログラムを実行することができるようになっている。

 たとえば,httpdを再起動したり,sendmailを再起動したりするといったプロセスを起動するようなプログラムを用意し,それをprocfix行で指定しておけば,管理者が異常を発見したときにSNMPマネージャを使ってprErrFixオブジェクト(1.3.6.1.4.1.2021.2.1.102.i)に1を書き込むことで,それらのプログラムを呼び出すことができるようになり,エラー状態からの復帰が可能となる。

 この仕組みは,きちんと設定して使うと便利なのだが,管理者以外に悪用されると,システムにセキュリティホールが生じるという話にもなるので,今回は割愛する。

exec
 exec行を設定すると,特定のプログラムを実行し,その実行結果をSNMPのデータとして格納することができる。デフォルトのsnmpd.confファイルには,次のようなexec行がある。

exec echotest /bin/echo hello world

 この設定は,“/bin/echo hello world”の実行結果——つまり,文字列"hello world"——をSNMPデータとして格納するというサンプルであり,大きな意味はない。

 exec行は,次の書式で指定する。

exec 設定名 実行ファイルのフルパス名 引数

 設定名の部分には,任意の名前を指定する。そして実行ファイルのフルパス名には,実行したいプログラムのフルパス名を,引数には,そのプログラムに渡したい引数を指定する。デフォルトの設定は,echotestという設定名で/bin/echoを引数“hello world”を伴って実行するという設定になっている。

 exec行にて指定した実行ファイルの実行結果は,extTableサブツリー(1.3.6.1.4.1.2021.8)内に配列の形で含まれる(Table 11)。exec行もproc行の設定と同様,snmpd.confファイルでの登場順に,先頭から,1,2,3…というインデックス番号が振られる。この例では,echotestという1つの項目しかないので,echotestという設定名を付けたexec行のインデックス番号は1となる。

Table 11 extTableサブツリー(1.3.6.1.4.1.2021.8
OID 1.3.6.1.4.1.2021.8.1
サブツリー名 extEntry
用途 配下に実行結果のデータを含むテーブルを保持する階層ツリー。値はない
OID 1.3.6.1.4.1.2021.8.1.1.i
サブツリー名 extIndex
用途 exec行の登場順に,先頭から順に1,2,と割り当てられたインデックス番号。iの値と同じ
OID 1.3.6.1.4.1.2021.8.1.2.i
サブツリー名 extNames
用途 exec行の設定名に指定した名前
OID 1.3.6.1.4.1.2021.8.1.3.i
サブツリー名 extCommand
用途 exec行に指定した実行ファイルのフルパス名引数
OID 1.3.6.1.4.1.2021.8.1.100.i
サブツリー名 extResult
用途 extCommandで指定された実行ファイルが実行時に返したエラーコード(戻り値)
OID 1.3.6.1.4.1.2021.8.1.101.i
サブツリー名 extOutput
用途 extCommandで指定された実行ファイルの実行結果(標準出力に書き出された文字列)の1行目。1行目以降は切り捨てられる
OID 1.3.6.1.4.1.2021.8.1.102.i
サブツリー名 extErrFix
用途 管理者がこのオブジェクトに1を設定すると,あらかじめsnmpd.confファイルのexecfix行で指定したコマンドが実行される
OID 1.3.6.1.4.1.2021.8.1.103.i
サブツリー名 extErrFixCmd
用途 extErrFixに1が設定されたときに実行されるコマンド名
iはインデックス番号。snmpd.confファイル中に出てきたexec行の登場順に,先頭から1,2,3,…という値。

 Table 11に示したように,exec行で指定したプログラムの実行結果は,“1.3.6.1.4.1.2021.8.1.100.i”と“1.3.6.1.4.2021.8.1.101.i”にそれぞれ格納される。前者には,実行したプログラムのエラーコード,後者には,プログラムが標準出力に書き出した1行目がそれぞれ格納される。デフォルトのsnmpd.confファイルでは,/bin/echoコマンドを使って“hello world”と書き出している。そのため,“1.3.6.1.4.2021.8.1.101.1”の値が“hello world”に設定される。これはsnmpwalkコマンドを使ってextTableサブツリー(1.3.6.1.4.1.2021.8)を参照すれば確認できる。

$ snmpwalk localhost private .1.3.6.1.4.1.2021.8
enterprises.ucdavis.extTable.extEntry.extIndex.1 = 1
enterprises.ucdavis.extTable.extEntry.extNames.1 = echotest
enterprises.ucdavis.extTable.extEntry.extCommand.1 = /bin/echo hello world
enterprises.ucdavis.extTable.extEntry.extResult.1 = 0
enterprises.ucdavis.extTable.extEntry.extOutput.1 = hello world
enterprises.ucdavis.extTable.extEntry.extErrFix.1 = 0
enterprises.ucdavis.extTable.extEntry.extErrFixCmd.1 =

 exec行での設定は,さまざまな用途に使うことができる。たとえば,メールキューの情報を調べて,その数を返すようなスクリプトを用意すれば,SNMPを通じて,現在メールキューに溜まっているメールの数を調べるようなことができる。

 なおexec行を設定するとき,特定のOIDを指定すると,指定した実行ファイルの実行結果を1行ごとに配列として階層ツリーに格納することもできる(その場合,Table 11に示した階層ツリーが若干異なる)。詳細はucd-snmpのmanを参照してほしい。

 exec行の設定では,任意のプログラムを実行できるので自由度が高い反面,セキュリティには十分注意していただきたい。snmpdrootユーザーで動作するため,exec行で指定した各種実行ファイルは,rootユーザーのもとで実行される。よってセキュリティ上懸念がありそうなプログラムを指定するのは避けるべきだ。もちろん,snmpdから実行される実行ファイルは,rootユーザー以外には書き換えできないようにするべきだ。そうしないとsnmpdから実行されるプログラムが他のユーザーに書き換えられてしまい,想定しなかったプログラムがrootユーザーの権限で実行されることになるだろう。

 また,exec行での設定は,proc行の設定と同様,管理者がSNMPマネージャを使ってextErrFixオブジェクト(1.3.6.1.4.1.2021.8.1.102.i)に1を設定すると,snmpd.confファイル中のexecfix行で指定しておいたプログラムを実行することができるようになっている。そのときに実行するプログラム名を指定するのがexecfix行の設定だ。デフォルトのsnmpd.confファイルには,execfix行は1つもない。

 execfix行を設定すると,管理者がSNMPマネージャを使って,特定のプログラムを実行できるようになるが,セキュリティ対策をとらないと,悪用される危険性がある。本稿ではexecfix行の設定についての説明は割愛する。

disk
 disk行を設定すると,特定のパス以下の空き容量が,指定されたキロバイト数以下になるもしくは指定されたパーセント以下になったときにエラー扱いとすることができる。disk行の設定書式は次の通りだ。

disk 調査するパス名最小容量またはパーセンテージ

 調査するパス名の部分には,調査したいディレクトリパスを指定する。そして,空白(またはタブ)で区切って,エラー扱いとしたい容量またはパーセンテージを指定する。容量の場合には,キロバイト単位で,パーセント値の場合には,“80%”とか“90%”といったように数字の後ろに“%”記号を伴って指定する。

 デフォルトのsnmpd.confファイルでは,次の指定となっており,/ディレクトリの空き容量が10000キロバイト——すなわち10Mバイト——以下にになったならば,それをエラー扱いとする設定になっている。

disk / 10000

 disk行にて指定したディスクの調査結果は,dskTableサブツリー(1.3.6.1.4.1.2021.9)以下に,配列の形で格納される(Table 12)。

Table 12 dskTableサブツリー(1.3.6.1.4.1.2021.9
OID 1.3.6.1.4.1.2021.9.1
サブツリー名 dskEntry
用途 配下にディスク情報を含むための階層ツリー。値はない
OID 1.3.6.1.4.1.2021.9.1.i
サブツリー名 dskIndex
用途 インデックス番号。disk行の登場順に,先頭から1,2,3,…というインデックス番号が振られる。iの値と同じ
OID 1.3.6.1.4.1.2021.9.2.i
サブツリー名 dskPath
用途 調査対象となるパス名。disk行の調査するパス名に指定した値
OID 1.3.6.1.4.1.2021.9.3.i
サブツリー名 dskDevice
用途 dskPathが含まれるデバイス名。/dev/hda1など
OID 1.3.6.1.4.1.2021.9.4.i
サブツリー名 dskMinimum
用途 disk行で指定したエラー扱いとする最小容量。パーセント設定されているときには-1
OID 1.3.6.1.4.1.2021.9.5.i
サブツリー名 dskMinPercent
用途 disk行で指定したエラー扱いとする最小容量のパーセンテージ。キロバイト単位で設定されているときには-1
OID 1.3.6.1.4.1.2021.9.6.i
サブツリー名 dskTotal
用途 dskDeviceで指定されるデバイスが格納できる最大容量。キロバイト単位
OID 1.3.6.1.4.1.2021.9.7.i
サブツリー名 dskAvail
用途 dskDeviceで指定されるデバイスの現在の空き容量。キロバイト単位
OID 1.3.6.1.4.1.2021.9.8.i
サブツリー名 dskUsed
用途 dskDeviceで指定されるデバイスの現在の利用容量。キロバイト単位
OID 1.3.6.1.4.1.2021.9.9.i
サブツリー名 dskPercent
用途 dskDeviceで指定されているディスクの使用率を百分率で示した値
OID 1.3.6.1.4.1.2021.9.10.i
サブツリー名 dskPercentNode
用途 dskDeviceで指定されているディスクのiノードの使用率を百分率で示した値
OID 1.3.6.1.4.1.2021.9.100.i
サブツリー名 dskErrorFlag
用途 空き容量がdisk行で指定された容量以下になったかどうかのエラーフラグ。1のときに容量以下になったことを,0のときにまだその空き容量以上空いていることを示す
OID 1.3.6.1.4.1.2021.9.101.i
サブツリー名 dskErrorMsg
用途 dskErrorFlagが1になっているとき,そのエラーメッセージ
iはインデックス番号。snmpd.confファイル中に出てきたdisk行の登場順に,先頭から1,2,3,…という値。

 デフォルトの設定では,/ディレクトリの空き容量が10MB以下になったときにエラー扱いとなるように設定されている。snmpd.confファイルにはそれ以外にdisk行はなく,この項目にはインデックス番号として1が割り当てられる。よって,/ディレクトリの空き容量が10MB以下になったとき,1.3.6.1.4.1.2021.9.100.1の値が1に設定される。SNMPマネージャを使ってこの値を監視すれば,ディスクの空き容量不足を調べることができるというわけだ。snmpwalkコマンドを使ってdskTableサブツリー(1.3.6.1.4.1.2021.9)を参照した例を以下に示す。

$ snmpwalk localhost private .1.3.6.1.4.1.2021.9
enterprises.ucdavis.dskTable.dskEntry.dskIndex.1 = 1
enterprises.ucdavis.dskTable.dskEntry.dskPath.1 = /
enterprises.ucdavis.dskTable.dskEntry.dskDevice.1 = /dev/hda1
enterprises.ucdavis.dskTable.dskEntry.dskMinimum.1 = 10000
enterprises.ucdavis.dskTable.dskEntry.dskMinPercent.1 = -1
enterprises.ucdavis.dskTable.dskEntry.dskTotal.1 = 128812
enterprises.ucdavis.dskTable.dskEntry.dskAvail.1 = 72437
enterprises.ucdavis.dskTable.dskEntry.dskUsed.1 = 49724
enterprises.ucdavis.dskTable.dskEntry.dskPercent.1 = 41
enterprises.ucdavis.dskTable.dskEntry.dskPercentNode.1 = 23
enterprises.ucdavis.dskTable.dskEntry.dskErrorFlag.1 = 0
enterprises.ucdavis.dskTable.dskEntry.dskErrorMsg.1 =

 参考までに,このホストの現在のディスク使用状況を知るべく,dfコマンドを実行したときの結果を以下に示す。

$ df
Filesystem 1k-blocks Used Available Use% Mounted on
/dev/hda1 128812 49724 72437 41% /
/dev/hda3 378743 53262 305926 15% /home
/dev/hda6 1277792 736196 476684 61% /usr

 dfコマンドの出力結果とdskTableサブツリー内のオブジェクトに格納されている値とを比べると,どれとどれが対応するのかがわかるだろう。

 disk行は,もちろん必要なだけ追加することができる。disk行を追加するのであれば,パーティション単位に設定項目を追加しておくとよいだろう。たとえば,//home/varの3つのパーティションを使っているのであれば,そのそれぞれを監視するよう,たとえば,次の設定をすればよい。

disk / 20%
disk /home 10%
disk /var 30%

 snmpd.confdisk行を上記のようにしておくと,先頭の項目から順にインデックス番号が1,2,3と割り当てられる。よって,次のような動作になる。


One Point!disk行は最大50個まで指定できる。それ以上設定したいときには,ucd-snmpのソースファイルであるconfig.hファイルのMAXDISKS定数を書き換え,再度makeしなければならない。


load
 load行を設定すると,システムのロードアベレージを調べることができる。ロードアベレージとは,簡単にいうと,CPUの稼働率のことで,1.00以下であれば滞りなくプロセスが実行されているということを,1.00以上であれば,負荷が重く,いくつかのプロセスの実行に遅延が生じていることを示す。

 load行の設定書式は次の通りだ。

load 1分間の平均 5分間の平均 15分間の平均

 それぞれの平均には,エラー扱いとしたいアベレージの値を指定する。5分間の平均15分間の平均については省略してもかまわない。平均を省略したときには12が設定されたものとみなされる。

 デフォルトのload行の設定は,次のようになっている。

load 12 14 14

 この設定は,次のいずれかのときにエラー扱いとすることを示す。

 一般にこの設定は,かなりの可負荷がかかっている状況であり,普通,ロードアベレージが5を越えると,かなりシステムが重くなったと感ずる。そのため,この設定値は,もう少し小さな値に設定しておいたほうがよいかも知れない。

 load行で設定したロードアベレージの値は,laTableサブツリー(1.3.6.1.4.1.2021.10)に配列の形で含まれる(Table 13)。

Table 13 laTableサブツリー(1.3.6.1.4.1.2021.10
OID 1.3.6.1.4.1.2021.10.1
サブツリー名 laEntry
用途 配下にロードアベレージ情報を格納する階層ツリー。値はない
OID 1.3.6.1.4.1.2021.10.1.1.i
サブツリー名 laIndex
用途 インデックス番号。1分平均値情報には1,5分平均値情報には2,15分平均情報には3がそれぞれ割り当てられる。iの値と同じ
OID 1.3.6.1.4.1.2021.10.1.2.i
サブツリー名 laNames
用途 監視名。1分平均値情報には“Load-1”,5分平均値情報には“Load-5”,15分平均値情報には“Load-15”がそれぞれ格納される
OID 1.3.6.1.4.1.2021.10.1.3.i
サブツリー名 laLoad
用途 ロードアベレージ値を文字列として表現したもの
OID 1.3.6.1.4.1.2021.10.1.4.i
サブツリー名 laConfig
用途 load行で設定されたエラー扱いとする平均値
OID 1.3.6.1.4.1.2021.10.1.5i
サブツリー名 laLoadInt
用途 laLoadを百分率で示したもの
OID 1.3.6.1.4.1.2021.10.1.6.i
サブツリー名 laLoadFloat
用途 laLoadを小数値として示したもの
OID 1.3.6.1.4.1.2021.10.1.100.i
サブツリー名 laLoadErrorFlag
用途 エラーフラグ。設定されたロードアベレージの平均値を越えているときには1,そうでなければ0が格納される
OID 1.3.6.1.4.1.2021.10.1.101.i
サブツリー名 laErrMessage
用途 laLoadErrorFlagが1であるときのエラーメッセージ
iはインデックス番号。1分間の平均値が1,5分間の平均値が2,15分間の平均値が3。

 laTableサブツリーは,1分間の平均値,5分間の平均値,15分間の平均値に,それぞれ1,2,3というインデックス番号が割り当てられ,配列のように格納される。たとえば1分間ロードアベレージに関する情報は1.3.6.1.4.1.2021.10.1.1.11.3.6.1.4.1.
2021.10.1.2.1
1.3.6.1.4.1.2021.10.1.3.1,…などに格納されている。

 1分間の平均ロードアベレージがload行で設定されたロードアベレージの平均値を越えたときには,1.3.6.1.4.1.2021.10.1.100.1に1が設定され,エラーメッセージが1.3.6.1.4.1.2021.10.101.1に設定される。5分間や15分間のロードアベレージに関しても同様で,5分間のロードアベレージが設定平均値を超えている場合には1.3.6.1.4.1.2021.10.1.100.2が,15分間のロードアベレージが設定平均値を越えている場合には1.3.6.1.4.1.2021.10.1.100.3が,それぞれ1に設定される。これらの情報をSNMPマネージャを使って監視すれば,システムの負荷状態を知ることができる。

 参考までにsnmpwalkコマンドを使って,laTableサブツリー(1.3.6.1.4.1.2021.10)以下を参照したものを以下に示す。

$ snmpwalk localhost private .1.3.6.1.4.1.2021.10
enterprises.ucdavis.laTable.laEntry.laIndex.1 = 1
enterprises.ucdavis.laTable.laEntry.laIndex.2 = 2
enterprises.ucdavis.laTable.laEntry.laIndex.3 = 3
enterprises.ucdavis.laTable.laEntry.laNames.1 = Load-1
enterprises.ucdavis.laTable.laEntry.laNames.2 = Load-5
enterprises.ucdavis.laTable.laEntry.laNames.3 = Load-15
enterprises.ucdavis.laTable.laEntry.laLoad.1 = 0.00
enterprises.ucdavis.laTable.laEntry.laLoad.2 = 0.00
enterprises.ucdavis.laTable.laEntry.laLoad.3 = 0.00
enterprises.ucdavis.laTable.laEntry.laConfig.1 = 12.00
enterprises.ucdavis.laTable.laEntry.laConfig.2 = 14.00
enterprises.ucdavis.laTable.laEntry.laConfig.3 = 14.00
enterprises.ucdavis.laTable.laEntry.laLoadInt.1 = 0
enterprises.ucdavis.laTable.laEntry.laLoadInt.2 = 0
enterprises.ucdavis.laTable.laEntry.laLoadInt.3 = 0
enterprises.ucdavis.laTable.laEntry.laLoadFloat.1 = Opaque: Float: 0.000000
enterprises.ucdavis.laTable.laEntry.laLoadFloat.2 = Opaque: Float: 0.000000
enterprises.ucdavis.laTable.laEntry.laLoadFloat.3 = Opaque: Float: 0.000000
enterprises.ucdavis.laTable.laEntry.laErrorFlag.1 = 0
enterprises.ucdavis.laTable.laEntry.laErrorFlag.2 = 0
enterprises.ucdavis.laTable.laEntry.laErrorFlag.3 = 0
enterprises.ucdavis.laTable.laEntry.laErrMessage.1 =
enterprises.ucdavis.laTable.laEntry.laErrMessage.2 =
enterprises.ucdavis.laTable.laEntry.laErrMessage.3 =

 上の実行結果は,ほとんど負荷がないホスト上で実行したものだ。そのため,すべてのロードアベレージ値は0になっている。もう少し負荷がかかっているホストで実行すると,0.3とか0.5といった値が得られるはずだ。

file
 file行を設定すると,特定のファイルのファイルサイズを監視したり,ファイルが一定バイト数を越えたときにエラー扱いとしたりすることができる。file行の設定書式は,次の通りだ。

file 監視するファイル名 エラー扱いとするファイルサイズ

 エラー扱いとするファイルサイズはキロバイト単位で指定する。省略した場合には,無限大が設定されたものとみなされる。

 デフォルトのsnmpd.confファイルには,file行は用意されていない。たとえば,/var/log/messagesファイルが5MBを越えたときにエラー扱いとしたいのであれば,snmp.confファイルに次のようなfile行を加える。

file /var/log/messages 50000

 file行で指定された項目の情報は,snmpd.confファイルに登場した順番で,先頭から1,2,3,…のようにインデックス番号が付けられ,fileTableサブツリー(1.3.6.1.4.1.2021.15)以下に配列の形で格納される(Table 14)。

Table 14 fileTableサブツリー(1.3.6.1.4.1.2021.15
OID 1.3.6.1.4.2021.15.1
サブツリー名 fileEntry
用途 配下にファイル情報を含む階層ツリー。値はない
OID 1.3.6.1.4.2021.15.1.1.i
サブツリー名 fileIndex
用途 インデックス番号。file行の登場順に,先頭から1,2,…と振られる。iと同じ
OID 1.3.6.1.4.2021.15.1.2.i
サブツリー名 fileNames
用途 file行に指定した監視するファイル名
OID 1.3.6.1.4.2021.15.1.3.i
サブツリー名 fileSize
用途 fileNamesで指定されているファイルの現在のファイルサイズ(キロバイト単位)
OID 1.3.6.1.4.2021.15.1.4.i
サブツリー名 fileMax
用途 file行に指定したエラー扱いとするファイルサイズ(キロバイト単位)
OID 1.3.6.1.4.2021.15.1.100.i
サブツリー名 fileErrorFlag
用途 fileNamesで指定されているファイルがfileMaxで指定されているファイルサイズよりも大きくなっているかどうかのエラーフラグ。大きくなっていれば1,そうでなければ0
OID 1.3.6.1.4.2021.15.1.101.i
サブツリー名 fileErrorMsg
用途 fileErrorFlagが1であるとき,そのエラーメッセージ
iはインデックス番号。snmpd.confファイル中に出てきたfile行の登場順に,先頭から1,2,3,…という値。

 上に挙げた/var/log/messagesファイルを監視する例であれば,1つしかfile行を用意していないので,この/var/log/messagesファイルの監視項目のインデックス番号は1となる。よって,/var/log/messagesファイルの現在のファイルサイズ(キロバイト単位)は,1.3.6.1.4.1.2021.15.1.3.1に格納される。そして,設定されたエラー扱いとするファイルサイズである5Mバイト(50000キロバイト)を越えたときには1.3.6.1.4.1.2021.15.1.100.1の値が1に設定され,そのときのエラーメッセージが1.3.6.1.4.1.2021.15.1.101.1に設定される。

 このようにfile行を指定すると,特定のファイルを監視するのに便利だ。ただしfile行の指定は,あくまでも1つのファイルを監視対象とするものであり,あるディレクトリに含まれる総容量を調べるものではない。ディレクトリに含まれるファイルサイズを総和を監視したいのであれば,diskの指定を使うか(ただしその場合,ディレクトリではなくパーティションの監視になる),特定のディレクトリに対するfindコマンドやduコマンドの結果を加工して出力するようなスクリプトを用意しておき,それをexecの指定を使って呼び出すような手法をとることになる。

●設定せずに参照できる値
 以上で説明したように,snmpd.confファイルを編集することで,さまざまな値をSNMPデータに含めることができるようになる。しかしそれ以外に,とくにsnmpd.confファイルを設定しなくても,いくつかの値を参照することができる。ここでは簡単に,それらの情報について説明する。

memoryサブツリー
 memoryサブツリー(1.3.6.1.4.1.2021.4)には,freeコマンドを使って取得できるメモリの状態やスワップファイルに関する情報を保持するオブジェクトが格納されている(Table 15)。
Table 15 memoryサブツリー(1.3.6.1.4.1.2021.4
OID 1.3.6.1.4.2021.4.1
サブツリー名 memIndex
用途 ダミーなインデックス番号.つねに0
OID 1.3.6.1.4.2021.4.2
サブツリー名 memErrorName
用途 ダミーな名前.つねに“swap”
OID 1.3.6.1.4.2021.4.3
サブツリー名 memTotalSwap
用途 スワップファイルの確保容量(キロバイト単位)
OID 1.3.6.1.4.2021.4.4
サブツリー名 memAvailSwap
用途 スワップファイルの未使用容量(キロバイト単位)
OID 1.3.6.1.4.2021.4.5
サブツリー名 memTotalReal
用途 搭載されている実メモリ(キロバイト単位)
OID 1.3.6.1.4.2021.4.6
サブツリー名 memAvailReal
用途 空き実メモリ(キロバイト単位)
OID 1.3.6.1.4.2021.4.7
サブツリー名 memTotalSwapTXT
用途 テキストで使われるスワップファイルの確保領域(キロバイト単位)
OID 1.3.6.1.4.2021.4.8
サブツリー名 memAvailSwapTXT
用途 テキストで使われるスワップファイルの未使用容量(キロバイト単位)
OID 1.3.6.1.4.2021.4.9
サブツリー名 memTotalRealTXT
用途 テキストで使われる総実メモリ(キロバイト単位)
OID 1.3.6.1.4.2021.4.10
サブツリー名 memAvailRealTXT
用途 テキストで使われる空きメモリ(キロバイト単位)
OID 1.3.6.1.4.2021.4.11
サブツリー名 memTotalFree
用途 総空きメモリ(実空きメモリ+スワップ空き容量)。キロバイト単位
OID 1.3.6.1.4.2021.4.12
サブツリー名 memMinimumSwap
用途 エラー扱いとするスワップファイルの空きサイズ(キロバイト単位)。デフォルトでは16000(16Mバイト)。スワップファイルの空きサイズがこの値を下回ったとき,memSwapErrorが1に設定される
OID 1.3.6.1.4.2021.4.13
サブツリー名 memShared
用途 総共有メモリの容量(キロバイト単位)
OID 1.3.6.1.4.2021.4.14
サブツリー名 memBuffer
用途 総バッファメモリの容量(キロバイト単位)
OID 1.3.6.1.4.2021.4.15
サブツリー名 memCached
用途 総キャッシュメモリ容量(キロバイト単位)
OID 1.3.6.1.4.2021.4.100
サブツリー名 memSwapError
用途 スワップエラーフラグ。スワップファイルの空き容量がmemMininumSwapで指定された容量よりも小さくなったときに1が設定される。そうでなければ0が設定される
OID 1.3.6.1.4.2021.4.101
サブツリー名 memSwapErrorMsg
用途 memSwapErrorが1になったとき,そのエラーメッセージ

 memoryサブツリーの配下に含まれるオブジェクトはすべて配列構造ではなく単一の値だ。よって,Table 15に示した各OIDの後ろに“.0”を付与して指定すれば,そのオブジェクトの値を取得できる.

 参考までに,snmpwalkコマンドを使ってmemoryサブツリー(1.3.6.1.4.1.2021.4)以下の一覧を表示したものを下に示す。

$ snmpwalk localhost private .1.3.6.1.4.1.2021.4
enterprises.ucdavis.memory.memIndex.0 = 0
enterprises.ucdavis.memory.memErrorName.0 = swap
enterprises.ucdavis.memory.memTotalSwap.0 = 133016
enterprises.ucdavis.memory.memAvailSwap.0 = 131256
enterprises.ucdavis.memory.memTotalReal.0 = 63092
enterprises.ucdavis.memory.memAvailReal.0 = 4116
enterprises.ucdavis.memory.memTotalFree.0 = 135372
enterprises.ucdavis.memory.memMinimumSwap.0 = 16000
enterprises.ucdavis.memory.memShared.0 = 54804
enterprises.ucdavis.memory.memBuffer.0 = 2796
enterprises.ucdavis.memory.memCached.0 = 21528
enterprises.ucdavis.memory.memSwapError.0 = 0
enterprises.ucdavis.memory.memSwapErrorMsg.0 =

 memoryサブツリー以下に含まれる情報を監視すれば,サーバーの使用メモリを調べたり,スワップファイルの空き容量が不足していないかどうかなどを調べたりすることができる。

systemStatsサブツリー(1.3.6.4.1.2021.11
 systemStatsサブツリーには,vmstatコマンドで取得できるCPUの状態を保持するオブジェクトが格納されている(Table 16)。
Table 16 systemStatsサブツリー(1.3.6.4.2021.11
OID 1.3.6.4.1.2021.11.1
サブツリー名 ssIndex
用途 ダミーインデックス番号。つねに1
OID 1.3.6.4.1.2021.11.2
サブツリー名 ssErrorName
用途 systemStatsの名前。つねに“systemStats
OID 1.3.6.4.1.2021.11.3
サブツリー名 ssSwapIn
用途 スワップインにかかった時間(キロバイト/秒)
OID 1.3.6.4.1.2021.11.4
サブツリー名 ssSwapOut
用途 スワップアウトにかかった時間(キロバイト/秒)
OID 1.3.6.4.1.2021.11.5
サブツリー名 ssIOSent
用途 ブロックデバイスへの送信にかかった時間(ブロック/秒)
OID 1.3.6.4.1.2021.11.6
サブツリー名 ssIOReceive
用途 ブロックデバイスからの受信にかかった時間(ブロック/秒)
OID 1.3.6.4.1.2021.11.7
サブツリー名 ssSysInterrupts
用途 1秒間にかかった割り込みの回数。クロック割り込みも含む
OID 1.3.6.4.1.2021.11.8
サブツリー名 ssSysContext
用途 1秒間に切り替えられたコンテキストスイッチの回数
OID 1.3.6.4.1.2021.11.9
サブツリー名 ssCpuUser
用途 ユーザーがCPUを使っている割合(百分率)
OID 1.3.6.4.1.2021.11.10
サブツリー名 ssCpuSystem
用途 システムがCPUを使っている割合(百分率)
OID 1.3.6.4.1.2021.11.11
サブツリー名 ssCpuIdle
用途 CPUがアイドルである割合(百分率)
OID 1.3.6.4.1.2021.11.50
サブツリー名 ssCpuRawUser
用途 ユーザーがCPUを使っている時間(システム時間)
OID 1.3.6.4.1.2021.11.51
サブツリー名 ssCpuRawNice
用途 niceプロセスの値(システム時間)
OID 1.3.6.4.1.2021.11.52
サブツリー名 ssCpuRawSystem
用途 システムがCPUを使っている時間(システム時間)
OID 1.3.6.4.1.2021.11.53
サブツリー名 ssCpuRawIdle
用途 CPUがアイドルである時間(システム時間)

 systemStatsサブツリーの配下に含まれるオブジェクトはすべて配列構造ではなく単一の値だ。よって,Table 16に示した各OIDの後ろに“.0”を付与して指定すれば,そのオブジェクトの値を取得できる。

 Table 16に示したように,systemStatsサブツリーには,おもにシステムのCPUの状態などが含まれる。systemStatsサブツリー(1.3.6.4.1.2021.11)をsnmpwalkコマンドを使って参照した例を以下に示す。

$ snmpwalk localhost private .1.3.6.1.4.1.2021.11
enterprises.ucdavis.systemStats.ssIndex.0 = 1
enterprises.ucdavis.systemStats.ssErrorName.0 = systemStats
enterprises.ucdavis.systemStats.ssSwapIn.0 = 0
enterprises.ucdavis.systemStats.ssSwapOut.0 = 1
enterprises.ucdavis.systemStats.ssIOSent.0 = 14
enterprises.ucdavis.systemStats.ssIOReceive.0 = 1
enterprises.ucdavis.systemStats.ssSysInterrupts.0 = 127
enterprises.ucdavis.systemStats.ssSysContext.0 = 41
enterprises.ucdavis.systemStats.ssCpuUser.0 = 0
enterprises.ucdavis.systemStats.ssCpuSystem.0 = 0
enterprises.ucdavis.systemStats.ssCpuIdle.0 = 98
enterprises.ucdavis.systemStats.ssCpuRawUser.0 = Counter32: 3110
enterprises.ucdavis.systemStats.ssCpuRawNice.0 = Counter32: 1
enterprises.ucdavis.systemStats.ssCpuRawSystem.0 = Counter32: 3114
enterprises.ucdavis.systemStats.ssCpuRawIdle.0 = Counter32: 576100


●その他のサブツリー
 以上が,ucdavisサブツリーの配下にある,おもなサブツリーだ。しかしそれ以外にも次に示すサブツリーがサポートされている。

 本稿では,これらのサブツリーについての説明は割愛する。詳細は,snmpdman/usr/loacl/share/snmp/mibsディレクトリにあるUCD-SNMP-MIB.txtファイルなどを参照してほしい。

snmpdのまとめ
 以上で説明してきたように,snmpd.confファイルを適切に設定し,snmpdを動作させれば,Linuxの情報をSNMPを通じて取得できるようになるということがお分かりいただけたと思う。

 いままでの説明では,ucd-snmpをインストールしたマシンでsnmpgetコマンドやsnmpwalkコマンドを使ってSNMPのデータを取得したわけだが,別のマシンにucd-snmpをインストールして,ネットワーク経由でsnmpgetコマンドやsnmpwalkコマンドを使い,リモートで特定のマシンの情報を取得することもできる(というよりむしろそれが本来のSNMPの使い方だ)。

 ところで,いまは手動でsnmpdを実行していたわけだが,ucd-snmpをインストールしてもシステムの起動時にsnmpdは自動的に実行されるようには設定されない。もし,システムの起動時にsnmpdを起動したいのであれば,/etc/rc.d/rc.localファイルなどに,次のように記述すればよい。

/usr/local/sbin/snmpd

 そうすれば,Linuxの起動時にsnmpdが自動的に起動するようになる。

iconMRTGを使って統計をとろう

 SNMPを使ってネットワークモニタリングする場合,ucd-snmpに含まれるsnmpgetコマンドやsnmpwalkコマンドを使ってもかまわないが,それらのコマンドは高機能なものとはいえない。そこで何らかのより使いやすいSNMPマネージャが欲しいところだ。

 SNMPマネージャとしてよく使われているのが,MRTG(Multi Router Traffic Grapher)というソフトだ。MRTGは,数値の統計をとってグラフ化するためのソフトで,SNMPマネージャの機能をもっている。そのため,MRTGを使えば定期的にSNMPエージェントに接続し,その統計データをグラフ化することがいとも簡単にできる。

 以下,MRTGを使ってsnmpdに接続し,snmpdが保持する各種データをグラフ化する方法を説明する。

MRTGのインストール
 MRTGのWebページ(http://www.mrtg.org/)には,MRTGをダウンロードするページへのリンクがある。ここでは,mrtg-2.9.12.tar.gzファイルをダウンロードし,それをインストールする方法を説明する。

 MRTGを動作させるためには,Table 17に示すソフトがインストールされていなければならない。

Table 17 MRTGの動作に必要なソフトやライブラリ
ソフト名 解説
perl バージョン5.005以上
gd グラフィック描画ライブラリ
libpng PNG形式イメージを作成するライブラリ
zlib libpngが使う圧縮ライブラリ

 幸い,Red Hat Linux 6.2には,Table 17に示したすべてのソフトがインストールされているので,とくにこれらのソフトをインストールする必要はない。

 なおMRTGは,先に説明したucd-snmpとの関連性はまったくない。よって,管理者が操作するホストにはMRTGだけをインストールすればよく,ucd-snmpとMRTGの両方をインストールする必要はない。つまり,SNMPエージェントとして動作させたいホスト(主にサーバー)にはucd-snmpを,SNMPマネージャとして動作させたいホスト(管理者が操作するコンピュータ)にはMRTGを,それぞれインストールすればよいということになる。


One Point! MRTGは,集計したデータをHTML形式のファイルと画像ファイルとで表現する。そのため,Webサーバーが動作しているサーバーにMRTGをインストールすれば,集計結果をWebブラウザを通じてリモートで参照できる。

 MRTGは,次のようにしてインストールする。

(1)mrtg-2.9.12.tar.gzをダウンロードする
 前出のURLなどから,mrtg-2.9.12.tar.gzをダウンロードする。日本国内では,RingServerプロジェクトにミラーリングされているので,そこからダウンロードするとよいだろう。

(2)tarコマンドを使って展開する
 ダウンロードしたディレクトリにカレントディレクトリを移し,次のようにtarコマンドを使って展開する。

$ tar xzvf mrtg-2.9.12.tar.gz

(3)環境設定する
 するとカレントディレクトリにmrtg-2.9.12というディレクトリができるので,カレントディレクトリをそこに移動する。

$ cd mrtg-2.9.12

 次に環境設定をするため,configureコマンドを実行する。

$ ./configure

 すると環境設定が完了する。場合によってはconfigureコマンドを実行したときにエラーが発生するかも知れない。その場合には,Table 17に示した各ソフトが不足している可能性があるので,その際には不足しているものをインストールしてから,再度MRTGのインストールを試みてもらいたい。

(4)makeする
 次にmakeコマンドを実行し,makeする。

$ make

 MRTGはそれほどステップ数の多いソースコードではないため,make作業はすぐに完了する。

(5)インストールする
 次にMRTGをインストールする。そのためには,suコマンドを使ってrootユーザーとしてログインする。

$ su
Password: rootユーザーのパスワードを入力する

 次にmake installとし,MRTGをインストールする。

# make install

 以上でMRTGのインストールは完了だ。なお,MRTGのファイルは,/usr/local/mrtg-2ディレクトリにコピーされる。

MRTGの設定と起動
 MRTGのインストールが終わったならば,MRTGの設定をする。

 MRTGで出力されるファイルは,統計をとりたい分野ごとに,GIF形式またはPNG形式の画像ファイルとそれを含むHTMLファイルとで構成される。


One Point! 画像ファイルの形式は,MRTGのコンパイルオプションならびにインストールされているgdライブラリのバージョンに依存する。gdライブラリは,ライセンスの関係上,バージョン1.6以降ではGIF形式をサポートしなくなった。そのためgdライブラリのバージョンが1.6以降であれば,PNG形式となる。

 これらのファイルは1つのディレクトリに配置されるので,まず,これらのファイルを格納するディレクトリを用意する。ここでは,仮に/usr/local/mrtg-2/dataというディレクトリを作ることにする。

# mkdir /usr/local/mrtg-2/data

One Point! HTMLファイルは,Webブラウザなどで参照することになる。ApacheなどのWebサーバーが動作しているのであれば,Apacheから参照できるディレクトリの配下にディレクトリを作成するとよいだろう(たとえば/usr/local/apache/htdocs/mrtgdataディレクトリなど)。しかしその場合,Apacheの設定で適切な権限の設定をしないと,インターネットからSNMPの情報を第三者に見られてしまう可能性があるので注意したい。

One Point! MRTGの実行にはroot権限は必ずしも必要というわけではない。もしユーザーのホームディレクトリ(/home/ユーザー名など)以下にMRTGの結果を保存するのであれば,rootユーザーではなく一般ユーザーで作業してもよい。

 データ保存先のディレクトリを作ったならば,次に設定ファイルを作る。設定ファイルをいちから作ってもよいのだが,それは面倒だ。そこで,MRTGにはcfgmakerというプログラムが用意されていて,それを使うとMRTGの設定ファイルを自動的に作成できる。cfgmakerは,次のように実行する。

/usr/local/mrtg-2/bin/cfgmaker コミュニティ名@SNMPエージェントのIPアドレス

 そうすると設定ファイルが標準出力に書き出されるので,通常はそれをリダイレクトする。たとえば,コミュニティ名がpublicで,データを参照したいSNMPエージェントのIPアドレスが192.168.0.33である場合,設定ファイルを/usr/local/mrtg-2/data/mrtg.cfgというファイル名として書き出すには,次のようにする。

# /usr/local/mrtg-2/bin/cfgmaker public@192.168.0.33 > /usr/local/mrtg-2/data/mrtg.cfg

 プログラムの実行が完了すれば,/usr/local/mrtg-2/data/mrtg.cfgファイルが作られるはずだ。以下,このようにしてできたmrtg.cfgファイルをcfgファイルと称す。

cfgファイルの設定
 cfgファイルにはいくつかの設定項目があるが,必ず設定しなければならないのは,WorkDirの設定だ。

 WorkDirには,MRTGを実行したときに画像ファイルやHTMLファイルなどを書き出すディレクトリを指定する。今回は,/usr/local/mrtg-2/dataディレクトリにそれらを書き出そうと思うので,cfgファイル(/usr/local/mrtg-2/data/mrtg.cfgファイル)の先頭に,次のような文を挿入する。

WorkDir: /usr/local/mrtg-2/data

 以上で,とりあえずの設定は完了だ。

●MTRGの実行
 ではMRTGを実行してみよう。MRTGを実行するには,次のようにmrtgコマンドの引数にcfgファイル名を渡せばよい。

/usr/local/mrtg-2/bin/mrtg cfgファイル名

 今回は,先にcfgmakerコマンドで作っておいた/usr/local/mrtg-2/data/mrtg.cfgファイルを設定ファイルとして実行するので,次のようにする。

# /usr/local/mrtg-2/bin/mrtg /usr/local/mrtg-2/data/mrtg.cfg

 初回実行時と2回目に実行したときには,いくつかのワーニングメッセージが出るが,これは過去の統計データが存在しないという意味であり,無視してかまわない。3回目以降は,ワーニングメッセージは出なくなる。

 実行が完了すると,/usr/local/mrtg-2/dataディレクトリに,HTMLファイルと画像ファイルができるはずだ。その表示結果は,Fig.6のようになる。

Fig.6 実行結果
fig_06

 Fig.6にあるように,デフォルトで表示されるのは,各インタフェースのトラフィック情報だ。いまは実行したばかりなので,グラフの値は,とくにない。しかし,mrtgコマンドを何回か実行すれば,徐々にグラフの値がたまってゆく。


One Point! グラフの値は,WorkDir行で指定したディレクトリに,拡張子が“.log”のファイルに保存される。もし過去の統計情報を削除したくなったならば,拡張子が“.log”のファイルを削除すればよい。

cronを使って自動的に実行されるようにする
 しかし,mrtgコマンドは1回限りの実行であり,継続して実行されるコマンドではない。よって,継続的にデータを取得してグラフを作ってゆくためにはcronを設定するなどして,mrtgコマンドを定期的に実行するように設定しなければならない。
One Point! 以下に説明するcronを設定する方法以外にも,cfgファイル内にRunAsDaemonIntervalを指定する方法もとれる。RunAsDaemonを指定すると,mrtgコマンドはデーモンとして(バックグラウンドで)動作するようになる。

 たとえば,5分おきにmrtgコマンドを実行するには,次のようにする。

(1)crontabコマンドを実行する
 まず,crontabコマンドを-eオプションを付けて実行する。

# crontab -e

(2)mrtgコマンドを実行する行を記述する
 するとエディタが起動するので,次のようにmrtgコマンドを起動する行を記述する。

0,5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/local/mrtg-2/bin/mrtg /usr/local/mrtg-2/data/mrtg.cfg

 以上で,5分ごとにMRTGが実行されるようになった。5分後,10分後などに再度先のHTMLファイル(Fig.6)を参照すれば,グラフが徐々に作られていくのがわかる(Fig.7)。

Fig.7 24時間以上経過した状態のグラフ
fig_07


さまざまなデータを取得する
 Fig.6Fig.7を見るとわかるように,cfgmakerコマンドを実行して作成したcfgファイルで作られるHTMLファイルには,機器のトラフィック情報しか含んでいない。これだけでも便利ではあるが,できればsnmpdが吐き出すさまざまな情報をグラフ化したいところだ。

 MRTGは,cfgファイルの構成次第で,さまざまな情報をグラフ化することができる。極端な話,SNMPデータ以外のデータをグラフ化することもできるのだが,それらについては割愛し,今回は,snmpdが吐き出すCPUの負荷情報と空きメモリ容量の2つの情報を書き出す設定を説明する。

●MRTGではどのようなグラフを作成できるのか
 実際にcfgファイルの設定方法について説明するまえに,MRTGがグラフ化する動作をまとめておこう。Fig.6Fig.7を見るとわかるが,MRTGは,2つの数値を1つのグラフにまとめる機能をもつ。デフォルトのcfgファイルでは,トラフィック情報の受信データが緑色,送信データが青色で示されている(色は設定変更できる)。

 そして,データは,日にちごと,週ごと,月ごと,年ごとに集計され,全部で4つのグラフが作られる。

 すぐあとに説明するが,MRTGでは,SNMPエージェント内にある管理情報領域のオブジェクトのOIDを指定することで,特定のオブジェクトがもつ任意の値をグラフ化できる。しかし1つのグラフ上には,2つの数値を示すことしかできず,3つ以上の数値を1つのグラフにまとめることができないばかりか,1つの数値のみをグラフ化することもできない。あくまでも1つのグラフに表示できるのは,2つの数値のペアに限られる。

cfgファイルの構成
 それでは,cfgファイルの構成について説明する。cfgファイル内では,さまざまな設定ができるが,基本的には,次の4つの要素で構成される。

 これらの4つの要素が1組としてグループ化され,1つの統計情報(1つのHTMLファイル)が構成される。これらの4つの要素は必須であり,省略することはできない。情報をグループ化するためには,各オプションの後ろに“[統計情報名]”を付ける。“[]”内に指定された統計情報名が,作成されるHTMLファイル名にもなる。


One Point! SNMP機器の種類によっては,機器が正しく内部時間のカウンタ値を返さないために,さらにRouterUptimeの設定をしなければならないことがある。snmpdの場合,正しくカウンタ値を返すので,RouterUptimeを設定する必要はない。

 たとえばcfgファイルが,List 3のようになっていたとする。これは,IPアドレス192.168.0.33のホストに対してcfgmakerコマンドを実行して得たcfgファイルだ。

 List 3の設定の意味は,次のようになる。

 List 3cfgファイルに,TargetMaxBytesTitlePageTopの各設定を変更したり,さらに追加したりすれば,MRTGを使ってさまざまなデータをグラフ化できるようになる。

Targetの設定方法
 cfgファイルの設定に際し,MaxBytesTitlePageTopについてはとくに説明はいらないだろう。問題はTargetの指定のしかただ。

 Targetでは,SNMP以外のデータも設定できるために,やや複雑な文法になっている。ここでは,(1)インタフェースの転送速度を得る方法,(2)指定したOIDをもつオブジェクトのデータを取得する方法の,2つに限って説明する。

(1)指定したインタフェースのデータを取得する方法
 まず1つ目の指定方法は,もっとも簡単な方法で,SNMPエージェントと通信し,指定したインタフェースのトラフィック情報を取得する方法だ。これには,次の書式を使う。

Target[統計情報名]: インタフェース番号:コミュニティ名@SNMPエージェントのIPアドレス

 すると,指定されたインタフェース番号の転送の受信バイト数と送信バイト数がグラフ化される。List 3では,インタフェース番号が2である送受信バイト数をグラフ化しているという意味になる。より詳しくいえば,interfacesサブツリーIfInOctets1.3.6.1.2.1.2.2.1.10.x)とIfOutOctet1.3.6.1.2.1.2.2.1.16.x)の値をグラフ化するという意味になる。

 デフォルトでは,受信のほうが緑色で,送信のほうが青色で表示される。

(2)特定のOIDの値を取得する方法
 もう1つの指定方法は,オブジェクトのOIDを指定し,そのオブジェクトがもつ値をグラフ化する方法だ。これには次の書式を使う。

Target[統計情報名]: データ1のOID & データ2のOID:コミニュティ名@SNMPエージェントのIPアドレス

 すると,データ1のOIDが受信バイト数,データ2のOIDが送信バイト数と見なされてグラフ化される。つまりデータ1のデータが緑色で,データ2のデータが青色で表示されることになる。

cfgファイルで指定できるオプション
 さて,いま説明したように,Targetに特定のオブジェクトのOIDを指定すれば,SNMPエージェントから得た任意のデータをグラフ化できるわけだが,得られるデータの種類によっては,グラフの表示形式を変更しなければならないことがある。

 というのは,デフォルトの設定では,取得したデータを送受信バイト数とみなし,次の計算によりネットワークの転送速度としてグラフ化するためだ。

  1. 前回取得したデータから今回取得したデータの差をとる(特定の時間内に何バイト送受信したのかを算出する)

  2. その結果を時間で割る(時間で割ることで転送速度(bps)を出す)

 たとえば,メモリの空き情報をグラフ化する場合,勝手にメモリの空き容量の差がとられてしまって,さらに時間で割られてしまうとグラフは意味不明なものとなる。よって,そのようなデータをグラフ化するには,グラフの描画オプションを変更しなければならない。

 グラフのオプションを変更するには,Optionsの設定を使う。

Options[統計情報名]: オプション

 オプションには,Table 18に示す項目をカンマで区切って指定する。たとえば,差をとらずにかつ時間で割らないようにするには,次のように設定すればよい。

Options[統計情報名]: absolute, gauge
Table 18 Optionsの設定項目
項目名 意味
growright グラフの横軸(時間)を左から右方向にとる(左が過去で右にいくほど現在に近い)。この設定をしないとき(デフォルト)は,右から左方向にとる
bits 値を8倍し,ビットとして扱う。デフォルト
perminute 分単位のグラフを表示するときに値を60倍する。デフォルト
perhour 時間単位のグラフを表示するときに値を3600倍する。デフォルト
noinfo 作成されたWebページの先頭にデバイス名や時刻(uptime)についての情報を出力しない
nopercent パーセント表示しない
transparent グラフ画像の背景を透明にする
integer 値を整数化する
dorelpercent 百分率にしたグラフ(値÷MaxBytesで指定した最大値)を重ねて表示する
gauge データの値の差をとらない
absolute 時間で割らない
unknaszero (特定の時間のあいだシステムトラブルなどによって)取得できなかった部分のデータを0として扱う。このオプションを指定しない場合(デフォルト),一番最後に取得できた値を継続的に利用する
withzeroes 0であるデータを無視しない

 また,Table 19に示すいくつかのオプションを指定すると,グラフの拡大率や表示方法などを変更することができる。そして,Table 20に示すいくつかのオプションを指定すると,出力されるHTMLファイルをカスタマイズすることができる。

Table 19 グラフのオプション
オプション名 意味
AbsMax グラフの絶対的な最大値を指定する。このオプションを指定しない場合,取得したデータの値に応じて縦軸が適時拡大縮小される。AbsMaxを指定するとデータの値にかかわらず,つねにここでの設定値がグラフの縦軸の最大値となる
UnScaled データに合わせて拡大縮小しない。この設定は,日グラフ(d),週グラフ(w),月グラフ(m),年グラフ(y)の組み合わせで設定する。たとえば,日グラフと週グラフを拡大縮小しないのであれば,“UnScaled[統計情報名]: dw”と指定する
WithPeak 平均値ではなく,ピーク値をとる。この設定は,週グラフ(w),月グラフ(m),年グラフ(y)の組み合わせで設定する。たとえば,年グラフでピーク値をとるようにするには“WithPeak[統計情報名]: y”と指定する
Suppress どの種類のグラフを作成するのかを設定する。この設定は,日グラフ(d),週グラフ(w),月グラフ(m),年グラフ(y)の組み合わせで設定する。たとえば,日グラフと週グラフだけを作成するのであれば,“Suppress[統計情報名]: dw”と指定する
MaxBytes1 データ1の最大値を設定する
MaxBytes2 データ2の最大値を設定する
XSize 作成するグラフの画像ファイルの横幅のピクセル数を指定する。20〜600まで指定できる。デフォルトは400
YSize 作成するグラフの画像ファイルの縦幅のピクセル数を指定する。20以上の値を指定できる。デフォルトは100
XZoom 横軸の拡大縮小率を指定する。作成される画像ファイルの横幅がここで指定した値を乗じた値になる
YZoom 縦軸の拡大縮小率を指定する。作成される画像ファイルの縦幅がここで指定した値を乗じた数になる
XScale 横軸の拡大縮小率を指定する。画像ファイルのサイズは変更されない。主に画面のアスペクト比を調整するために用いる
YScale 縦軸の拡大縮小率を指定する。画像ファイルのサイズは変更されない。主に画面のアスペクト比を調整するために用いる
YTics 1つのグラフに4本以上の線を描画するときに設定する
YTicsFactor Y軸のデータにここで指定した値を乗算する
Factor 取得したデータにここで指定した値を乗算する
Step データの描画間隔を指定する。デフォルトは300秒(5分)
Colours グラフの描画色を設定する
YLegend Y軸の軸の名前(ラベル)を指定する
ShortLegend Y軸の軸の単位(ラベル)を指定する
Legend1 データ1(受信データ)のグラフ名(ラベル)を指定する
Legend2 データ2(送信データ)のグラフ名(ラベル)を指定する
Legend3 データ1(受信データ)の百分率グラフ名(ラベル)を指定する。Optionsdorelpercentを指定したときのみ有効
Legend4 データ2(送信データ)の百分率グラフ名(ラベル)を指定する。Optionsdorelpercentを指定したときのみ有効
LegendI データ1(受信データ)のラベルを指定する
LegendO データ2(送信データ)のラベルを指定する
kilo キロの単位を切り替える。デフォルトは1000。kiloを1024に設定すると,1キロ=1024に変更できる
kMG k(キロ),M(メガ),T(テラ)などの単位を変更する
Timezone タイムゾーンを設定する。デフォルトではシステムのタイムゾーンが使われるので,とくに設定変更する必要はない
Weekformat 週の表示形式を変更する
SetEnv 外部プログラムを呼び出すときに設定する環境変数を指定する。外部プログラムを呼び出さないのであれば関係ない
Table 20 HTMLのオプション
オプション名 意味
PageFoot Webページの一番下に表示されるHTMLテキストを指定する
AddHead <HEAD>タグと<BODY>タグのあいだに指定したいHTMLテキストを指定する
BodyTag <BODY>タグを変更する
Background Webページの背景色を変更する
Extension 作成されるファイルの拡張子を変更する。デフォルトは,“.html

 Table 19Table 20に示したオプションもやはり,“[統計情報名]”を付けてグループ化する。たとえば,192.168.0.33_2という統計情報名をもつグラフの横軸を2倍にしたいのであれば,次のように記述する。

XZoom[192.168.0.33_2]: 2.0

 ところで,“[統計情報名]”の部分だが,統計情報名に“_”を指定すると,すべての統計情報に関してという意味になる。たとえば,すべてのグラフを横600ドット,縦200ドットで構成したいのであれば,次のようにすればよい。

XSize[_]: 600
YSize[_]: 200

One Point![_]”の指定と似たものとして,“[^]”(以下の統計情報にこの設定が存在していなければその項目をまえに挿入),“[$]”(以下の統計情報にこの設定が存在していなければその項目をうしろに挿入)という指定もできる。


●ロードアベレージと空きメモリ容量を取得するには
 説明はこのぐらいにして,実際にsnmpdが出力するデータのうち,ロードアベレージ情報と空きメモリ情報を指定する方法を説明する。

 まずは,ロードアベレージ情報を取得する方法を考える。ロードアベレージ情報はlaTableサブツリー1.3.6.1.4.1.2021.10)のlaLoadInt1.3.6.1.4.1.2021.10.1.5.i)を通じて取得できる。laLoadIntは,ロードアベレージ値を百分率として表現した整数を保持するオブジェクトだ。


One Point!laTableサブツリーには,laLoadInt以外にもlaLoad(文字列として保存)というオブジェクトもあるが,MRTGでは文字データをグラフ化することはできない。

 先に説明したように,MRTGでは1つのデータを取得して表示するというわけにはゆかず,必ず2つのオブジェクトを指定しなければならない。そこでここでは,5分間の平均ロードアベレージ値を示す1.3.6.1.4.1.2021.10.1.5.2と15分間の平均ロードアベレージ値を示す1.3.6.1.4.1.2021.10.1.5.3の値をグラフ化することを考える。それには,cfgファイルにList 4のような行を追加すればよい。

 List 4では,ロードアベレージのグラフに“cpu”という統計情報名を付けた。そして,Target行で,5分間の平均ロードアベレージ値を示す“1.3.6.1.4.1.2021.10.1.5.2”と15分間の平均ロードアベレージ値を示す“1.3.6.1.4.1.2021.10.1.5.3”を指定している。

 ロードアベレージ値は,差を計算されたり,時間で割られたりしては困るので,Option行にgaugeabsoluteを指定をしている。また,ロードアベレージ値では,0は有効な値だからwithzerosを指定して0を無視しないように,そして,もとが百分率なのにさらにパーセント表示しても無意味なので,nopercentを指定した。なお,MaxBytes行の指定は2000(2000%,ロードアベレージ20に相当)としてある。実際にこんなにロードアベレージ値が大きくなることはないから,もっと少ない値を指定してもよい。もっとも多少大きな値を指定しても,AbsMax行の指定をしない限り,値が収まるように適時グラフが拡大縮小されるので問題ない。


One Point! とはいえパーセント表示するときには,値÷MaxBytesを百分率にしたものが併記される。よって,正しくパーセント表示したいときには,MaxBytesの値を指定しておいたほうがよい。また,MaxBytesはデータ1とデータ2の両者の最大値を設定するものだが,代わりにMaxBytes1MaxBytes2を使うと,データ1の最大値とデータ2の最大値を個別に指定することができる。

 その他のYLegendShortLegendLegend1Legend2などはグラフ軸の名前や単位を設定する部分だ。

 実際にList 4に示した文をcfgファイルに加えたのちmrtgコマンドを実行すれば,cpu.htmlファイルが(WorkDir行で指定したディレクトリに)作られる。cpu.htmlファイルをWebブラウザで表示すると,Fig.8のようになる。

Fig.8 cpu.htmlファイルを参照したところ
fig_08

 同様の方法で,空きメモリ容量をグラフ化することもできる。ここでは,実メモリの空き容量とスワップファイルの空き容量を1つのグラフにまとめてみよう。この2つの値は,memoryサブツリー1.3.6.1.4.1.2021.4)のmemAvailRealオブジェクト(1.3.6.1.4.1.2021.4.6)とmemAvailSwapオブジェクト(1.3.6.1.4.1.2021.4.4)に保存されている(どちらもキロバイト単位)。よって,cfgファイルにList 5に示すような行を追加すればよい。

 List 5の設定は,List 4とほぼ同じで,基本的には,Target行で取得するオブジェクトのOIDが違うだけだ。ここでは,統計情報名として“mem”を指定してある。


One Point!Target行では,memAvailRealmemAvailSwapのOIDのうしろに“.0”を付けている点に注意したい。memAvailRealmemAvailSwapは,配列構造ではないから,値を取得するためにOIDのうしろに“.0”を付けなければならない。

 List 5では,値の最大値をMaxBytes行ではなく,MaxBytes1行とMaxBytes2行に分け,それぞれ別の最大値を指定している。Target行では,データ1が実メモリの空き容量(memAvailRealオブジェクト),データ2がスワップファイルの空き容量(memAvailSwapオブジェクト)に指定してある。そのため,MaxBytes1行には実メモリの空き容量の最大値を,MaxBytes2行にはスワップメモリの空き容量の最大値をそれぞれ指定することになる。ここでは前者を128000(128Mバイト),後者を256000(256Mバイト)としたが,環境に合わせた容量を指定してほしい。この値は,グラフとともに表示されるパーセンテージ値の算出に使われるので,正しく設定しないと,パーセンテージ値が実際と違うものになる。

 List 5cfgファイルに加えたのちmrtgコマンドを実行すると,mem.htmlファイルが(WorkDir行で指定したディレクトリに)作られる。mem.htmlファイルをWebブラウザで表示すると,Fig.9のようになる。


One Point!Fig.9を見るとわかるように,表示されるグラフはキロバイト単位なので,やや見づらいと感ずるかも知れない。もしメガバイト単位にしたいのであれば,YTicsFactorの値に0.001を指定すればよい。つまり,“YTicsFactor[mem]: 0.001”という行を加える。そうすれば,値に0.001を乗算した結果がグラフとして表示されるので,結果としてメガバイトに換算したグラフになる。
Fig.9 mem.htmlファイルを参照したところ
fig_09

 今回は,ロードアベレージと空きメモリ容量の取得しか説明していないが,cfgファイルを変更することにより,SNMPエージェントが吐き出す任意のデータをグラフ化することができる。つまり,オブジェクトのOIDさえ指定すれば,いかなるデータもグラフ化できるということだ。

 ところで今回は,snmpdが吐き出すSNMPデータをグラフ化する方法について説明したわけだが,対象となるSNMPエージェントはどのようなものでもかまわない。たとえば,ルーターやインテリジェントハブ,ネットワークプリンタなどが吐き出すSNMPデータを取得してグラフ化することももちろんできる。ただし,その場合,SNMP対応機器のどのOIDにどのようなデータが格納されているのかを知っていることが前提となる。多くのネットワーク機器はmib-2サブツリーには対応している。よって,ほとんどの機器のトラフィック情報(interfacesサブツリーの情報)はグラフ化できる。しかしそれ以外にどのようなデータが格納されるのかは,メーカー依存の場合も多い。いくつかのメーカーは,各機器用の管理情報領域の構造を記した「MIBファイル」を提供しているので,それらを参照し,OIDを調べることになるだろう。


One Point! MIBファイルは,ASN.1という書式で記述されているので,その書式を知らなければならない。しかし,ASN.1形式はさして複雑ではないので,MIBファイルの記述内容とsnmpwatlkコマンドを使って取得できるオブジェクトの一覧とを照らし合わせれば,理解するのはそんなに難しくはない。

indexmakerコマンドによるインデックスの作成
 さて,このように作成してきたcfgファイルだが,結局,cfgファイルの“[]”内に指定した統計情報名だけのファイルに分散されるので,扱いがやや面倒だ。そこで,index.htmlファイルを作り,各統計情報のページにリンクを張っておくと便利だろう。リンクを張るには,手動でやる方法もあるが,MRTGにはindexmakerというコマンドがあるので,それを使うと簡単だ。次のようにすればよい。

# /usr/local/mrtg-2/bin/indexmaker /usr/local/mrtg-2/data/mrtg.cfg > /usr/local/mrtg-2/data/index.html

 すると,cfgファイルに含まれるグラフの日ごとのグラフが含まれ,その日ごとのグラフをクリックすると各統計情報へのページに飛ぶリンクが張られたindex.htmlファイルが作られる(Fig.10)。

Fig.10 index.htmlファイルの内容
fig_10
MRTGのまとめ
 以上,簡単だが,MRTGを使ったSNMPデータの統計処理を説明した。ここで紹介した以外にも,MRTGにはたくさんのオプションがあり,さまざまなグラフを作ることができる。それらの設定方法については,MRTGのmanを参照してほしい。

 MRTGの基本は,OIDで指定された2つのオブジェクトがもつデータをグラフ化することだけである。その点さえ理解していれば,さまざまなオプションの理解はさして難しくないだろう。

 ところでMRTGと同じ作者が,より高機能なRRDtool(Round Robin Database tool)というプログラムを作成している。RRDtoolはSNMPで取得したデータをデータベース状に格納し,さまざまな加工ができるユーティリティだ。MRTGでは,2つのデータしかグラフ化できないのに対し,RRDtoolでは,スクリプトを使ってさまざまな加工ができる(ただし高機能な分だけ扱いは複雑だ)。SNMPで取得したデータをグラフ化するだけでなく,より統計的な集計をしたいのであれば,RRDtoolの導入を検討するのもよいだろう。

icon SNMPとセキュリティ

 最後に,SNMPのセキュリティについて簡単に述べておく。

 SNMPでのセキュリティは基本的に,次の2つの項目で決定される。

  1. あらかじめ設定しておいたIPアドレスをもつホストからのアクセスであるか
  2. コミュニティ名が一致しているかどうか

 SNMPでは,このような簡単な認証方式しかサポートしていないので(SNMPv3では別の認証方式もサポートされる),インターネット上で使うのは避けたほうがよい。そもそもSNMPはUDPパケットで通信するため,データのパケットが正しくSNMPエージェントに到達したかどうか,SNMPマネージャに戻ってくるかどうかは一切保証されない。

 SNMPでは,UDPのポート161番と162番が使われる。できることならば,ルーターなどの設定でパケットフィルタリングし,この2つのパケットがインターネット側から入らずまた出ないように設定しておいたほうが安全だ。

icon まとめ

 今回は,ucd-snmpをインストールして,LinuxマシンにSNMPエージェントの機能を追加したのち,MRTGを使って,データを取得する方法について説明した。簡単ではあるが,この方法により,ネットワーク全体の情報をグラフ化することがいとも簡単にできる。

 しかしSNMPは,データを収集し,グラフ化するだけには留まらない。今回は説明しなかったが,SNMPには「SNMPトラップ」という機能があり,データがあらかじめ指定した値になったならば,特定のコマンドを実行するようなこともできる(ucd-snmpでは,SNMPトラップをサポートするためのsnmpdというデーモンが用意されている)。この機能を使えば,たとえば,システムが不調になったならば,管理者にメールを送信するとか管理者のポケベルを鳴らすといったような,障害時の報告システムを構築することができる。

 また,SNMPはさまざまなOSで使えるものであり,SNMPエージェントとSNMPマネージャのOSが違ってももちろん問題ない。たとえばWindows2000には「ネットワークモニタ」というSNMPマネージャの機能をもつソフトが用意されているので,Linuxにucd-snmpを入れ,Windows2000からネットワークモニタを使って監視するといったこともできる。つまり,用途に応じて,SNMPエージェントとSNMPマネージャは自由に組み合わせて使うことができるというわけだ。


One Point! 余談になるが,WebサーバーであるApacheにSNMPの機能を追加するmod-snmpというプログラムもある。Apacheにmod-snmpを組み込むと,SNMPマネージャを通じてApacheへのリクエスト数やエラー数などの統計情報を取得できる。またApacheの情報を取得するだけでなく,SNMPマネージャからApacheの設定を変更することもできるのだ。

 ここまで読んできて,1台のコンピュータを管理するだけであれば,わざわざSNMPを利用する価値はないと考える読者も多いと思う。しかしMRTGを使うとさまざまな情報をグラフ化できるため,たとえ1台のコンピュータであっても,ネットワークの問題点を掴むという点から見ればSNMPを導入するメリットは高い。

 たとえば,なんとなくネットワークが遅くなったと感じたときに,何が原因で,どの時間帯に遅くなるのかを掴むのは,やはり統計情報を見ないとわかりにくい。そういった意味で,SNMPを使ったネットワークモニタリングは,ネットワークにトラブルがないかどうかを調べるような監視用途としての使い方はもちろん,ネットワークのボトルネックとなっている部分はどのようなところで,もし増強するならばどの部分を増強しなければならないのか(サーバーのメモリなのかCPUなのか,それともネットワークそのもののトラフィックが増大しているのかなど)を把握するのにも役立つ。