SNMPによるネットワークモニタリング
|
SNMPとは,ネットワークに接続された機器類をネットワーク経由で監視するためのプロトコルだ。このプロトコルはRFC1157で定義されている。
SNMPに対応する機器類には,その機器の情報を保持するための「管理情報領域」と呼ばれる領域が用意されている。たとえばルーターであれば,そのルーターを流れたデータのバイト数,ネットワークプリンタであれば,プリンタのステータス,用紙情報,トナー残量などが管理情報領域に格納されている。管理情報領域にどのような情報が保存されているのかは,機器によって異なる。
SNMPに対応する機器内には,ネットワークを通じて管理情報領域にアクセスするためのインタフェースが用意される。このインタフェースは「SNMPエージェント」と呼ばれる。SNMPエージェントはUDPを使ってネットワーク通信するモジュールだ。
SNMPに対応する機器——つまりSNMPエージェントが搭載された機器——の情報を得るには,サーバーやクライアントなどのホストに「SNMPマネージャ」と呼ばれるソフトをインストールする。SNMPマネージャは,SNMPエージェントと通信し,SNMPに対応する機器類内にある管理情報領域の情報を,取得したり設定する機能を持つ。つまりネットワーク管理者は,SNMPマネージャを使うことで,ネットワーク上に配置されたネットワーク機器の情報を1か所で管理できるようになる(Fig.1)。
SNMPエージェントは,インテリジェントハブやルータ,ネットワークプリンタなどに搭載されている。よってSNMPに対応したそれらの機器を管理するのであれば,LinuxマシンにSNMPマネージャをインストールするだけでよい。
また,LinuxマシンにSNMPエージェントとなるソフトをインストールすると,そのLinuxマシンを別のLinuxマシンからSNMPマネージャを使って管理することができる。LinuxマシンがSNMPエージェントとして機能するようになると,ネットワーク上に複数のLinuxマシン(Linuxサーバー)が存在するとき,SNMPマネージャを使って,それらのLinuxサーバーの情報を集中管理できて便利だ(Fig.2)。
本稿では,まず,SNMPエージェントとなるソフトをLinuxマシンにインストールし,Linuxマシン自身をSNMP対応機器に仕立て上げてしまう方法を説明する。
そして次に,SNMPマネージャを(ネットワーク管理者がネットワーク管理に使う)Linuxマシンにインストールし,SNMPに対応した機器(SNMPエージェントをインストールしたLinuxマシンも含む)を管理する方法を説明する。
もちろん読者のなかには,LinuxマシンをSNMPで管理する必要はなく,SNMPに対応したネットワーク機器だけをLinuxマシンからSNMPで集中管理できればよいという人もいるだろう。その場合には,LinuxマシンにSNMPエージェントをインストールする作業は不要なので,その部分は飛ばし,LinuxマシンにSNMPマネージャをインストールするところから読み進めてもらってかまわない。
LinuxにインストールすることができるSNMPエージェントとなるソフトには,いくつかの種類がある。本稿では,比較的よく使われている「ucd-snmp」を使うことにする。ucd-snmpは,SNMPエージェントといくつかの簡単なコマンドライン形式のSNMPマネージャを含むSNMP統合パッケージだ。ちなみにucd-snmpは,Linux以外にも,FreeBSDやSolarisなどさまざまなUNIX系のOSで動作する。
ucd-snmpのインストール
ucd-snmp-4.2.1.tar.gzをインストールするには,次のようにする。
(1)ucd-snmp-4.2.1.tar.gzをダウンロードする$ tar xzvf ucd-snmp-4.2.1.tar.gz |
(3)環境設定する
$ 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 |
この作業にはしばらく時間がかかる。
(5)インストールする
$ su Password: rootユーザーのパスワードを入力する |
次にumaskコマンドを次のように実行し,インストールするときにコピーされるファイルが,rootユーザー以外によって不正に書き換えられないようにする。
# umask 022 |
次にmake installとし,ucd-snmpをインストールする。
# make install |
以上でucd-snmpのインストールは完了だ。exitコマンドを実行し,rootユーザーから一般ユーザーに戻る。
# exit |
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ファイルに必要な設定項目を説明する。
●コミュニティの設定
# 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/24(192.168.0.0/255.255.255.0と同じ)のネットワークからSNMPマネージャを使って,このマシンを管理できるようにするには,設定を次のように変更する。
# sec.name source community com2sec local localhost private com2sec mynetwork 192.168.0.0/24 public |
もちろんネットワーク全体ではなく,特定のホストからしかSNMPマネージャを使った管理を行わせたくないこともあるだろう。その場合には,そのホストのアドレスを指定すればよい。たとえば次のようにすると,192.168.0.100というIPアドレスをもつホストもしくはlocalhost(SNMPエージェントが動作しているマシン自身)以外からは,SNMPエージェントに接続できなくなる。
# sec.name source community com2sec local localhost private com2sec mynetwork 192.168.0.100 public |
# 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 |
# incl/excl subtree mask 80 view all include .1 80 |
この設定は,すべての情報を見せるという設定だ。詳しくは「SNMPにおける情報取得の基礎」にて説明するが,管理情報領域は階層構造をもつツリー構造になっている。この設定を変更すると,一部の階層以下しか公開しない設定にすることができる。
LANから利用する場合には,すべての管理情報領域を公開するというデフォルトの設定で問題ない。
●アクセス権限の設定
# 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 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ファイルができたところで,SNMPエージェントを動かしてみよう。
SNMPエージェントを動かすには,rootユーザーとしてログインし,snmpdを実行すればよい。
$ su Password: rootユーザーのパスワードを入力する # snmpd # exit |
これで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にログ情報が書き出されるので,もしうまく動作しなかった場合には,ログ情報を参照して原因を調べていただきたい。
snmpdが正しく動作したならば,そのLinuxマシンがSNMPエージェントとして動作したことになる。つまり,別のホストからSNMPマネージャを使って,snmpdを動作させたLinuxマシンの情報を取得するというネットワークモニタリングが可能となる。
つまり,あとは何らかのSNMPマネージャをインストールし,その設定方法や利用方法を理解すればよいわけだ。
しかしSNMPマネージャを使って情報を監視するためには,SNMPエージェントが保持する管理情報領域にどのようなデータがどのような構造で格納されているのかを知っていなければならない。
そこで本格的なSNMPマネージャをインストールするまえに,ucd-snmpに付属するSNMPマネージャとして動作する簡単なコマンドを使いながら,管理情報領域の構造を説明する。
OIDツリー
どのOIDが割り当てられたオブジェクトにどのような情報が格納されているのかは,あらかじめ定められている。たとえば,“1.3.6.1.2.1.1.4”は管理者のメールアドレス,“1.3.6.1.2.1.1.6”はシステムの場所情報を示すといった具合だ。
SNMPは,SNMPマネージャからSNMPエージェントに対し,OIDを送ると,そのOIDが割り当てられたオブジェクトに格納されている値が返されるという単純な仕組みで構成される(Fig.4)
すなわち,SNMPを使う上ではどのようなOIDをもつオブジェクトに,どのような情報が格納されているのかを知ることが重要となる。それが分かれば,SNMPエージェントを通じて機器のさまざまな情報を取得できるのだ。
逆にいえば,どのOIDをもつオブジェクトにどのような情報が格納されているのかを知らなければ,SNMPは何の意味もなさない。たとえば,SNMPを使ってネットワークのトラフィック情報を取得したい場合,ネットワークのトラフィック情報がどのOIDが割り当てられたオブジェクトに格納されているのかを知らなければ,いくらSNMPエージェントとSNMPマネージャが正しく動作していたとしても,トラフィック情報を取得できない。
ucd-snmpが対応する管理領域情報は,次の4種類だ。
RFC1213で定義されるmib-2サブツリー
ucd-snmpが独自に定義するucdavisサブツリー
RFC1514で定義されるHost Resourceの初期化情報(内容は空)
RFC2571〜RFC2976で定義されるSNMPv3のMIB
これらの管理領域情報は,数がかなり多く,到底ここで紹介することはできない。そこで本稿では,よく使われる1.と2.のみを説明する。
●OIDツリーの一覧を得るucd-snmpには,特定の階層ツリー以下のオブジェクトを一覧表示するsnmpwalkというコマンドが用意されている。snmpwalkコマンドは,次の書式で用いる
snmpwalk ホスト名コミュニティ名OID |
ホスト名には接続したいSNMPエージェントのホスト名またはIPアドレスを,コミュニティ名には接続に使うコミュニティ名を指定する。ここで指定するコミュニティ名は,snmpd.confファイル内のcom2sec行で指定したものだ。OIDには,取得したい階層ツリーとなるオブジェクトのOIDの先頭に“.”(ピリオド)を付けて指定する。すべてのオブジェクトを取得したければ,OIDとして単に“.”を指定すればよい。もし特定のツリー以下を表示したいのであれば,そのツリーのオブジェクトのOIDを指定する。たとえばFig.3に示したmib-2サブツリー以下を取得したいのであれば,“.1.3.6.1.2.1”というOIDを指定する。
たとえば,localhost(自分自身)に対して,コミュニティ名privateで接続し,全ツリーの一覧を取得するには,次のようにする。
$ snmpwalk localhost private . |
すると,次のように,全ツリーの一覧が表示される。
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 …以下略… |
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”のようになる。
以下,各サブツリーを解説する。
|
|
○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”といった数値を付けてオブジェクトそのものを差すのだ。
このような決まりは,値が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)
|
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)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サブツリーは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/24(192.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に設定されているということがわかる。
などといろいろ説明してきたが,小規模なシステムでは,静的なルーティングが設定されることが多く,あまりルーティング情報を監視したい場面はないだろう。
それよりネットワーク監視として重要なのは,ipInHdrErrors(1.3.6.1.2.1.4.4)やipInAddrErrors(1.3.6.1.2.1.4.5)といった壊れたり宛先不明となっているパケット数だ。あまりにこれらの数が多いようだと,ネットワークがハードウェア的に不安定であったり,第三者があえて壊れたIPパケットを送信して攻撃を仕掛けているといった状況が考えられるからだ。
●icmpサブツリー(1.3.6.1.2.1.5)とはいえ,あまりにも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 |
|
|
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 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)
$ 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 |
|
●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メッセージが届いた総数——いい換えれば認証に失敗したメッセージ——を取得したいのであれば,snmpInBadCommunityNames(1.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 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から監視したいプロセス名を,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)。
|
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ファイルの設定であれば,次のような動作をすることになる。
mountdプロセスが1つも存在しない場合
1.3.6.1.4.2021.2.1.100.1の値が1。1.3.6.1.4.2021.2.1.101.1の値がそのエラーメッセージ。
ntalkdプロセスが4つ以上存在する場合
1.3.6.1.4.2021.2.1.100.2の値が1,1.3.6.1.4.2021.2.1.101.2の値がそのエラーメッセージ。
sendmailプロセスが1つも存在しないか10個以上存在する場合
1.3.6.1.4.2021.2.1.100.3の値が1,1.3.6.1.4.2021.2.1.101.3の値がそのエラーメッセージ。
このようにproc行を指定するとプロセスの状態が監視できるので,SNMPを通じて,特定のプロセスが何らかのトラブルにより消滅してしまったり,処理の増加により予想以上に増えてしまったりしたときの情報を取得できるというわけだ。
proc行をどのように設定すればよいのかは,Linux上で動作しているどのプロセスを監視したいのかによる。たとえば,デフォルトの設定をすべてコメントアウト(先頭に“#”を挿入する)し,sendmail,httpd,named,syslogdの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コマンドを実行したときに,sendmailとsyslogdは動いているけれどもhttpdとnamedは動いていないという状況を示したものだ。この結果を見るとわかるように,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 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に示したように,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行の設定では,任意のプログラムを実行できるので自由度が高い反面,セキュリティには十分注意していただきたい。snmpdはrootユーザーで動作するため,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 調査するパス名最小容量またはパーセンテージ |
調査するパス名の部分には,調査したいディレクトリパスを指定する。そして,空白(またはタブ)で区切って,エラー扱いとしたい容量またはパーセンテージを指定する。容量の場合には,キロバイト単位で,パーセント値の場合には,“80%”とか“90%”といったように数字の後ろに“%”記号を伴って指定する。
デフォルトのsnmpd.confファイルでは,次の指定となっており,/ディレクトリの空き容量が10000キロバイト——すなわち10Mバイト——以下にになったならば,それをエラー扱いとする設定になっている。
disk / 10000 |
disk行にて指定したディスクの調査結果は,dskTableサブツリー(1.3.6.1.4.1.2021.9)以下に,配列の形で格納される(Table 12)。
|
デフォルトの設定では,/ディレクトリの空き容量が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.confのdisk行を上記のようにしておくと,先頭の項目から順にインデックス番号が1,2,3と割り当てられる。よって,次のような動作になる。
/ディレクトリの空き容量が20%を切ったとき
1.3.6.1.4.1.2021.9.1.100.1が1になる。
/homeディレクトリの空き容量が10%を切ったとき
1.3.6.1.4.1.2021.9.1.100.2が1になる。
/homeディレクトリの空き容量が30%を切ったとき
1.3.6.1.4.1.2021.9.1.100.3が1になる。
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)。
|
laTableサブツリーは,1分間の平均値,5分間の平均値,15分間の平均値に,それぞれ1,2,3というインデックス番号が割り当てられ,配列のように格納される。たとえば1分間ロードアベレージに関する情報は1.3.6.1.4.1.2021.10.1.1.1,1.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 監視するファイル名 エラー扱いとするファイルサイズ |
エラー扱いとするファイルサイズはキロバイト単位で指定する。省略した場合には,無限大が設定されたものとみなされる。
デフォルトの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)。
|
上に挙げた/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行の指定を使って呼び出すような手法をとることになる。
●設定せずに参照できる値○memoryサブツリー
|
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サブツリーの配下に含まれるオブジェクトはすべて配列構造ではなく単一の値だ。よって,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 |
snmperrsサブツリー(1.3.6.1.4.1.2021.101)
snmpdのエラー情報が格納される。
versionサブサリー(1.3.6.1.4.1.2021.100)
snmpdのバージョン情報が格納される。
mrTableサブツリー(1.3.6.1.4.1.2021.102)
snmpdはあとからモジュールを加えることで,機能拡張ができるようになっている。このmrTableサブツリーには,追加されたモジュールのそれぞれの情報が格納される。本稿では,モジュールについての説明は割愛する。
ucdDemoMIBサブツリー(1.3.6.1.4.1.2021.14)
snmpdのデモンストレーション用のサブツリー。
本稿では,これらのサブツリーについての説明は割愛する。詳細は,snmpdのmanや/usr/loacl/share/snmp/mibsディレクトリにあるUCD-SNMP-MIB.txtファイルなどを参照してほしい。
snmpdのまとめいままでの説明では,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が自動的に起動するようになる。
SNMPを使ってネットワークモニタリングする場合,ucd-snmpに含まれるsnmpgetコマンドやsnmpwalkコマンドを使ってもかまわないが,それらのコマンドは高機能なものとはいえない。そこで何らかのより使いやすいSNMPマネージャが欲しいところだ。
SNMPマネージャとしてよく使われているのが,MRTG(Multi Router Traffic Grapher)というソフトだ。MRTGは,数値の統計をとってグラフ化するためのソフトで,SNMPマネージャの機能をもっている。そのため,MRTGを使えば定期的にSNMPエージェントに接続し,その統計データをグラフ化することがいとも簡単にできる。
以下,MRTGを使ってsnmpdに接続し,snmpdが保持する各種データをグラフ化する方法を説明する。
MRTGのインストールMRTGを動作させるためには,Table 17に示すソフトがインストールされていなければならない。
|
幸い,Red Hat Linux 6.2には,Table 17に示したすべてのソフトがインストールされているので,とくにこれらのソフトをインストールする必要はない。
なおMRTGは,先に説明したucd-snmpとの関連性はまったくない。よって,管理者が操作するホストにはMRTGだけをインストールすればよく,ucd-snmpとMRTGの両方をインストールする必要はない。つまり,SNMPエージェントとして動作させたいホスト(主にサーバー)にはucd-snmpを,SNMPマネージャとして動作させたいホスト(管理者が操作するコンピュータ)にはMRTGを,それぞれインストールすればよいということになる。
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で出力されるファイルは,統計をとりたい分野ごとに,GIF形式またはPNG形式の画像ファイルとそれを含むHTMLファイルとで構成される。
これらのファイルは1つのディレクトリに配置されるので,まず,これらのファイルを格納するディレクトリを用意する。ここでは,仮に/usr/local/mrtg-2/dataというディレクトリを作ることにする。
# mkdir /usr/local/mrtg-2/data |
データ保存先のディレクトリを作ったならば,次に設定ファイルを作る。設定ファイルをいちから作ってもよいのだが,それは面倒だ。そこで,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ファイルの設定WorkDirには,MRTGを実行したときに画像ファイルやHTMLファイルなどを書き出すディレクトリを指定する。今回は,/usr/local/mrtg-2/dataディレクトリにそれらを書き出そうと思うので,cfgファイル(/usr/local/mrtg-2/data/mrtg.cfgファイル)の先頭に,次のような文を挿入する。
WorkDir: /usr/local/mrtg-2/data |
以上で,とりあえずの設定は完了だ。
●MTRGの実行/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にあるように,デフォルトで表示されるのは,各インタフェースのトラフィック情報だ。いまは実行したばかりなので,グラフの値は,とくにない。しかし,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)。
MRTGは,cfgファイルの構成次第で,さまざまな情報をグラフ化することができる。極端な話,SNMPデータ以外のデータをグラフ化することもできるのだが,それらについては割愛し,今回は,snmpdが吐き出すCPUの負荷情報と空きメモリ容量の2つの情報を書き出す設定を説明する。
●MRTGではどのようなグラフを作成できるのかそして,データは,日にちごと,週ごと,月ごと,年ごとに集計され,全部で4つのグラフが作られる。
すぐあとに説明するが,MRTGでは,SNMPエージェント内にある管理情報領域のオブジェクトのOIDを指定することで,特定のオブジェクトがもつ任意の値をグラフ化できる。しかし1つのグラフ上には,2つの数値を示すことしかできず,3つ以上の数値を1つのグラフにまとめることができないばかりか,1つの数値のみをグラフ化することもできない。あくまでも1つのグラフに表示できるのは,2つの数値のペアに限られる。
●cfgファイルの構成これらの4つの要素が1組としてグループ化され,1つの統計情報(1つのHTMLファイル)が構成される。これらの4つの要素は必須であり,省略することはできない。情報をグループ化するためには,各オプションの後ろに“[統計情報名]”を付ける。“[]”内に指定された統計情報名が,作成されるHTMLファイル名にもなる。
たとえばcfgファイルが,List 3のようになっていたとする。これは,IPアドレス192.168.0.33のホストに対してcfgmakerコマンドを実行して得たcfgファイルだ。
List 3の設定の意味は,次のようになる。
統計情報名
ここでは,各項目に対し,“[192.168.0.33_2]”という指定がされている。よって,統計情報名は192.168.0.33_2となり,mrtgコマンドを実行したときには,192.168.0.33_2.htmlというファイル名のHTMLファイルが(WorkDirで指定したディレクトリに)作成されることになる。
統計対象
Targetでは192.168.0.33のIPアドレスをもつSNMPエージェントのデータを取得している。ここでは取得すべきデータの値も設定しているのだが,その意味はすぐあとに説明する。
最大値
MaxBytesにて1250000が設定されており,取得するデータがとりうる最大値は1250000に設定されている。 この最大値は,パーセンテージを計算するときに使われる。
タイトル
Titleには,作成されるWebページのタイトル(<TITLE>タグの内容)が示されている。
ページ
PageTop以下の指定は,Webページの先頭に書き出されるHTMLテキスト。Fig.6やFig.7と照らし合わせてみるとわかるが,これはただのHTML文字列でしかない。
List 3のcfgファイルに,Target,MaxBytes,Title,PageTopの各設定を変更したり,さらに追加したりすれば,MRTGを使ってさまざまなデータをグラフ化できるようになる。
○Targetの設定方法Targetでは,SNMP以外のデータも設定できるために,やや複雑な文法になっている。ここでは,(1)インタフェースの転送速度を得る方法,(2)指定したOIDをもつオブジェクトのデータを取得する方法の,2つに限って説明する。
(1)指定したインタフェースのデータを取得する方法
まず1つ目の指定方法は,もっとも簡単な方法で,SNMPエージェントと通信し,指定したインタフェースのトラフィック情報を取得する方法だ。これには,次の書式を使う。
Target[統計情報名]: インタフェース番号:コミュニティ名@SNMPエージェントのIPアドレス |
すると,指定されたインタフェース番号の転送の受信バイト数と送信バイト数がグラフ化される。List 3では,インタフェース番号が2である送受信バイト数をグラフ化しているという意味になる。より詳しくいえば,interfacesサブツリーのIfInOctets(1.3.6.1.2.1.2.2.1.10.x)とIfOutOctet(1.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ファイルで指定できるオプションというのは,デフォルトの設定では,取得したデータを送受信バイト数とみなし,次の計算によりネットワークの転送速度としてグラフ化するためだ。
前回取得したデータから今回取得したデータの差をとる(特定の時間内に何バイト送受信したのかを算出する)
その結果を時間で割る(時間で割ることで転送速度(bps)を出す)
たとえば,メモリの空き情報をグラフ化する場合,勝手にメモリの空き容量の差がとられてしまって,さらに時間で割られてしまうとグラフは意味不明なものとなる。よって,そのようなデータをグラフ化するには,グラフの描画オプションを変更しなければならない。
グラフのオプションを変更するには,Optionsの設定を使う。
Options[統計情報名]: オプション |
オプションには,Table 18に示す項目をカンマで区切って指定する。たとえば,差をとらずにかつ時間で割らないようにするには,次のように設定すればよい。
Options[統計情報名]: absolute, gauge |
|
また,Table 19に示すいくつかのオプションを指定すると,グラフの拡大率や表示方法などを変更することができる。そして,Table 20に示すいくつかのオプションを指定すると,出力されるHTMLファイルをカスタマイズすることができる。
|
|
XZoom[192.168.0.33_2]: 2.0 |
ところで,“[統計情報名]”の部分だが,統計情報名に“_”を指定すると,すべての統計情報に関してという意味になる。たとえば,すべてのグラフを横600ドット,縦200ドットで構成したいのであれば,次のようにすればよい。
XSize[_]: 600 YSize[_]: 200 |
まずは,ロードアベレージ情報を取得する方法を考える。ロードアベレージ情報はlaTableサブツリー(1.3.6.1.4.1.2021.10)のlaLoadInt(1.3.6.1.4.1.2021.10.1.5.i)を通じて取得できる。laLoadIntは,ロードアベレージ値を百分率として表現した整数を保持するオブジェクトだ。
先に説明したように,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行にgaugeとabsoluteを指定をしている。また,ロードアベレージ値では,0は有効な値だからwithzerosを指定して0を無視しないように,そして,もとが百分率なのにさらにパーセント表示しても無意味なので,nopercentを指定した。なお,MaxBytes行の指定は2000(2000%,ロードアベレージ20に相当)としてある。実際にこんなにロードアベレージ値が大きくなることはないから,もっと少ない値を指定してもよい。もっとも多少大きな値を指定しても,AbsMax行の指定をしない限り,値が収まるように適時グラフが拡大縮小されるので問題ない。
その他のYLegendやShortLegend,Legend1,Legend2などはグラフ軸の名前や単位を設定する部分だ。
実際にList 4に示した文をcfgファイルに加えたのちmrtgコマンドを実行すれば,cpu.htmlファイルが(WorkDir行で指定したディレクトリに)作られる。cpu.htmlファイルをWebブラウザで表示すると,Fig.8のようになる。
同様の方法で,空きメモリ容量をグラフ化することもできる。ここでは,実メモリの空き容量とスワップファイルの空き容量を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”を指定してある。
List 5では,値の最大値をMaxBytes行ではなく,MaxBytes1行とMaxBytes2行に分け,それぞれ別の最大値を指定している。Target行では,データ1が実メモリの空き容量(memAvailRealオブジェクト),データ2がスワップファイルの空き容量(memAvailSwapオブジェクト)に指定してある。そのため,MaxBytes1行には実メモリの空き容量の最大値を,MaxBytes2行にはスワップメモリの空き容量の最大値をそれぞれ指定することになる。ここでは前者を128000(128Mバイト),後者を256000(256Mバイト)としたが,環境に合わせた容量を指定してほしい。この値は,グラフとともに表示されるパーセンテージ値の算出に使われるので,正しく設定しないと,パーセンテージ値が実際と違うものになる。
List 5をcfgファイルに加えたのちmrtgコマンドを実行すると,mem.htmlファイルが(WorkDir行で指定したディレクトリに)作られる。mem.htmlファイルをWebブラウザで表示すると,Fig.9のようになる。
今回は,ロードアベレージと空きメモリ容量の取得しか説明していないが,cfgファイルを変更することにより,SNMPエージェントが吐き出す任意のデータをグラフ化することができる。つまり,オブジェクトのOIDさえ指定すれば,いかなるデータもグラフ化できるということだ。
ところで今回は,snmpdが吐き出すSNMPデータをグラフ化する方法について説明したわけだが,対象となるSNMPエージェントはどのようなものでもかまわない。たとえば,ルーターやインテリジェントハブ,ネットワークプリンタなどが吐き出すSNMPデータを取得してグラフ化することももちろんできる。ただし,その場合,SNMP対応機器のどのOIDにどのようなデータが格納されているのかを知っていることが前提となる。多くのネットワーク機器はmib-2サブツリーには対応している。よって,ほとんどの機器のトラフィック情報(interfacesサブツリーの情報)はグラフ化できる。しかしそれ以外にどのようなデータが格納されるのかは,メーカー依存の場合も多い。いくつかのメーカーは,各機器用の管理情報領域の構造を記した「MIBファイル」を提供しているので,それらを参照し,OIDを調べることになるだろう。
# /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)。
MRTGの基本は,OIDで指定された2つのオブジェクトがもつデータをグラフ化することだけである。その点さえ理解していれば,さまざまなオプションの理解はさして難しくないだろう。
ところでMRTGと同じ作者が,より高機能なRRDtool(Round Robin Database tool)というプログラムを作成している。RRDtoolはSNMPで取得したデータをデータベース状に格納し,さまざまな加工ができるユーティリティだ。MRTGでは,2つのデータしかグラフ化できないのに対し,RRDtoolでは,スクリプトを使ってさまざまな加工ができる(ただし高機能な分だけ扱いは複雑だ)。SNMPで取得したデータをグラフ化するだけでなく,より統計的な集計をしたいのであれば,RRDtoolの導入を検討するのもよいだろう。
最後に,SNMPのセキュリティについて簡単に述べておく。
SNMPでのセキュリティは基本的に,次の2つの項目で決定される。
SNMPでは,このような簡単な認証方式しかサポートしていないので(SNMPv3では別の認証方式もサポートされる),インターネット上で使うのは避けたほうがよい。そもそもSNMPはUDPパケットで通信するため,データのパケットが正しくSNMPエージェントに到達したかどうか,SNMPマネージャに戻ってくるかどうかは一切保証されない。
SNMPでは,UDPのポート161番と162番が使われる。できることならば,ルーターなどの設定でパケットフィルタリングし,この2つのパケットがインターネット側から入らずまた出ないように設定しておいたほうが安全だ。
今回は,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マネージャは自由に組み合わせて使うことができるというわけだ。
ここまで読んできて,1台のコンピュータを管理するだけであれば,わざわざSNMPを利用する価値はないと考える読者も多いと思う。しかしMRTGを使うとさまざまな情報をグラフ化できるため,たとえ1台のコンピュータであっても,ネットワークの問題点を掴むという点から見ればSNMPを導入するメリットは高い。
たとえば,なんとなくネットワークが遅くなったと感じたときに,何が原因で,どの時間帯に遅くなるのかを掴むのは,やはり統計情報を見ないとわかりにくい。そういった意味で,SNMPを使ったネットワークモニタリングは,ネットワークにトラブルがないかどうかを調べるような監視用途としての使い方はもちろん,ネットワークのボトルネックとなっている部分はどのようなところで,もし増強するならばどの部分を増強しなければならないのか(サーバーのメモリなのかCPUなのか,それともネットワークそのもののトラフィックが増大しているのかなど)を把握するのにも役立つ。