6月 162011
 

さてさて。このブログでは過去三回ほど、MRTG の IPv6 化と言うか対応について書いたことがあります。

mrtg が IPv6 で動作しない。
net-snmpd+mrtg の IPv6 化とその他もろもろ。(2)
net-snmpd+mrtg の IPv6 化とその他もろもろ。

今回は過去に検証したものについて、再度の検証を行い、実際にはどういう動作になったのかを確認してみたいと思います。

と、言うのも最近の perl は 5.14.0 になって IPv6 回りに改良が加えられました。 Socket モジュールがちょっと変更になったんですね。そして、mrtg 自体も以前からはバージョンが上がっているので IPv6 回りに改修が入ったのではないかと思い、再度の検証とするのであります。

今回利用するのは最新の ports-current です。このエントリーの一日前に csup したものを利用します。mrtg が動作するのに必要なものは以下辺りでしょうかねぇ。

    perl-5.14.0
    p5-IO-Socket-INET6-2.67
    p5-Net-SNMP-6.0.1
    p5-SNMP_Session-1.13
    p5-Socket6-0.23
    mrtg-2.17.1
    net-snmp-5.5_4

今回の検証はこれで試してみました。ports の net-mgmt/mrtg は WITH_IPV6=true で make config します。すると関連性で net/p5-IO-Socket-INET6 と net/p5-Socket6 がインストールされ、IPv6 Ready な mrtg となります。

IPv6 の機器に対応した設定ファイルである mrtg.cfg を書いて、早速 env LANG=C mrtg mrtg.cfg とかを実行します。が・・。エラーが出て動作しませんでした。

一個目は SNMP_Session.pm が以下のメッセージを出力します。長いので改行してあります。

% env LANG=C mrtg mrtg.cfg
Subroutine SNMP_Session::pack_sockaddr_in6 redefined at \
/usr/local/lib/perl5/5.14.0/Exporter.pm line 67. at\
/usr/local/lib/perl5/site_perl/5.14.0/SNMP_Session.pm line 149
Subroutine SNMPv1_Session::pack_sockaddr_in6 redefined at \
/usr/local/lib/perl5/5.14.0/Exporter.pm line 67. at\
/usr/local/lib/perl5/site_perl/5.14.0/SNMP_Session.pm line 608

 
このメッセージはエラーだと思い込んでいたのですが、ただのワーニングメッセージなので一応は mrtg は問題なく動作するようです。

しかし、インストールした mrtg コマンド、つまり /usr/local/bin/mrtg のほうが別のエラーを出力してまともに動作してくれません。エラーメッセージは以下の通り。

% env LANG=C mrtg mrtg.cfg
Undefined subroutine &main::AF_UNSPEC called at /usr/local/bin/mrtg line 2247.
Undefined subroutine &main::AF_UNSPEC called at /usr/local/bin/mrtg line 2247.

 
AF_UNSPEC が無い。と言われるんですね。このメッセージは本当にエラーなので、 mrtg はまともに動作しないので問題を取り除く必要があります。

僕は以下のように改修しました。

--- mrtg.orig   2011-06-16 15:40:42.000000000 +0900
+++ mrtg        2011-06-16 17:22:07.000000000 +0900
@@ -2244,7 +2244,7 @@
my @res;
my ($too,$port,$otheropts) = split(':', $$target{SnmpOpt}, 3);
$port = 161 unless defined $port;
-            @res = getaddrinfo($hostname, $port, AF_UNSPEC(), SOCK_DGRAM());
+            @res = getaddrinfo($hostname, $port, &Socket::AF_UNSPEC(), &Socket::SOCK_DGRAM());
if (scalar (@res) < 5) {
warn "$NOW: WARNING: Skipping host $hostname as \
it does not resolve to an IPv4 or IPv6 address\n";
return 'DEADHOST';

 
AF_UNSPEC がどこにあるのか解らないみたいなので、明示的に Socket モジュールの中のを利用するように記述しました。あと、SOCK_DGRAM も「&main には無いよ。」と言われるのでこっちも直します。しかし、他にもっと美しい改修の方法があるんでしょうなぁ。とは思いますが・・f(^^;;。

これで実行すると無事に mrtg が動作するようになりました。良かったです。

さてさて。ここまでで一応 mrtg コマンドは動作しました。実は順番が逆になっているかもしれないのですが、続いて mrtg.cfg のほうを見ていきたいと思います。

以前の「net-snmpd+mrtg の IPv6 化とその他もろもろ。(2)」のエントリーのところで Target 節のパラメータに ifIndex しか指定できない。などと書いたのですが、この点は結構重要になってきます。

ifIndex と NIC なんてのは増設すると同期が取れなくなるので ifIndex で mrtg は取得してくないですよね。今回試したのは以下の四パターン。

Target[server_bge0]: 1:public@[2001:3e0:a71::f:10]:::::2
Target[server_bge1]: \bge1:public@ipv6.running-dog.net:::::2
Target[router_gi01]: 32:public@2001:3e0:a71::f:1]:::::2
Target[router_gi02]: \GigabitEthernet0/1:public@cisco.running-dog.net:::::2

 
ふむ。以前試した時は ifDescription では mrtg で情報が取得ができず ifIndex でのみしかダメだったのですが、今回は無事に上のどのパータンでもトラフィック情報を取得することができました。インターフェースだけでなく、フツーの MIB も IPv6 アドレスでも FQDN でもどちらでもきっちり取れるようになりました。これは非常に嬉しいことですね。

あと、MRTG の公式サイト http://oss.oetiker.ch/mrtg/doc/mrtg-ipv6.en.html を見れば色々書いてありますが、FQDN で問い合せた時、当該機器の snmp が IPv6 に対応していない場合 IPv4 に fall back せずにそのまま終わってしまう件ですが、

1. EnableIPv6: yes の設定で
2. Target: 節に FQDN を書いていて
3. その機器は IPv4 にしか対応していない場合は mrtg が取れない。
4. そんな時は IPv4Only: 節を利用すると良いですよ。

と、言うことらしいです。つまりは IPv4Only: 節がある機器の場合は最初から IPv4 で mrtg が動作するみたいです。これは良かった;-)。

Target[macosx_en0]: \en0:public@mac.running-dog.net:
IPv4Only[macosx_en0]: yes

 
こんな感じで mrtg.cfg を書けば IPv4 にしか対応していない MacOSX SL の snmpd に対しても無事に mrtg が取得できます。

過去、何回かこのブログに書いた mrtg ですが、これで多分は全部大丈夫っぽいかなぁ。

いやぁ。良かった良かった。それにしても CentOS 5.6 では IPv6 対応の mrtg がまともに動作していなんだよなぁ。今回は FreeBSD で検証したんだけど、CentOS の Final でも再度検証が必要かなぁ。

と、おもーちょります。