パスワードを忘れた? アカウント作成
171937 journal

Ab.の日記: munin で windows 機を snmp__if_ する

日記 by Ab.
Windows7 機を snmpwalk していたら IF-MIB::ifAlias なんてものを見つけてしまいました。
うちではNIC2枚差し3枚差し当たり前で、コントロールパネルのネットワークからNICの名前をLANとかWANとか付けるのが普通だったので気づいたのですが、ここにはそっちの方の名前が出てきます。
これは munin に使える!
というのは、えー、説明すると長くなりますが、まず windows 機を snmpwalk で IF-MIB::ifDescr あたりを見てみると分かるのですが、物理インターフェースとそのサブレイヤーが同等にインターフェースとして並べられている上にネットワークに潜り込むアプリケーション(アンチウィルスとか仮想化ソフトとか)がインストールされるとインターフェースが増えるし、同じチップのネットワークカードを挿したときの区別なんか付かないしで、特定のネットワークカードを追いかけようにも別のスロットに差し直したりとかそういう操作で簡単に違う番号にアサインされてしまう予感がひしひしとします。
そして munin に付いてくる snmp 経由で network interface の traffic を拾ってくる plugin の snmp__if_ はインターフェース番号でデータを集計し、グラフをプロットするのです。
というか SNMP である以上そうするしかない、のでしょう。
でもまぁこちとら自作派でい!てやんでいべらんめい寿司食いねえ!ってな訳でどう考えても何かある度にインターフェース番号を調べて設定を直すのも嫌だし、かといって全部列挙すると munin-node-configure-snmp で10個以上出てくるインターフェースすべてのグラフを作るのとか絶対ゴメンだという事で今まで snmp__if_ はガン無視だった訳ですが、 ifAlias をキーにしてしまえば差し替えようが何しようが roll に応じて alias を付けておけば munin の方はメンテナンス不要じゃないかという事で alias 名で NIC をトラッキングする munin plugin をでっち上げてみました。
自分でやっているのは alias を引いてインターフェース番号を割り出して環境変数に突っ込むだけで、後は本家の snmp__if_ プラグインを呼び出して処理を任せてしまっています。

#!/usr/bin/env perl
# snmp__ifbyalias_ を snmp_<マシン名>_ifbyalias_<alias名> に symbolic link して使います

my $host      = $ENV{host}      || undef;
my $community = $ENV{community} || "public";
my $ifname    = $ENV{ifname}    || undef;

if ($0 =~ /^(?:|.*\/)snmp_([^_]+)_if_byalias_(.+)$/) {
    $host  = $1;
    $ifname = $2;
    if ($host =~ /^([^:]+):(\d+)$/) {
        $host = $1;
        $port = $2;
    }
}elsif (!defined($host)) {
    die;
}

open my $pipe, '-|', 'snmpwalk', '-c', $community, '-v2c', $host, 'IF-MIB::ifAlias'
    or die;
while (<$pipe>) {
    chomp;
    m/^IF-MIB::ifAlias\.(\d+)\s+=\s+STRING:\s*(.*)$/;
    if ($2 eq $ifname) {
        close $pipe;
        $ENV{host} = $host              if ($host);
        $ENV{community} = $community    if ($community);
        $ENV{port} = $port              if ($port);
        $ENV{interface} = $1;
        exec '/usr/local/share/munin/plugins/snmp__if_', $ARGV[0];
    }
}
die "alisa $ifname not found.";

本当は Net::SNMP 使って自分で叩くべきなんでしょうけどとりあえず面倒なので snmpwalk 呼んじゃってます。
ちなみに Windows7, Small Business Server 2008 では動きましたが Windows Home Server では ifAlias の項がなかったので駄目でした。
恐らく Vista 以前も駄目かな?

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

海軍に入るくらいなら海賊になった方がいい -- Steven Paul Jobs

読み込み中...