Bad knowhow

Authentication failure

I have hosts, that use SSH Host-Based authentication. When I write a script like below (ssh.rb), it throws Net::SSH::AuthenticationFailed.

#!/usr/local/bin/ruby
require 'rubygems'
require 'net/ssh'
Net::SSH.start(
  'target.foo.co.jp',
  'daiba',
  :auth_methods => %w(hostbased),
  :keys => %w(/etc/ssh/ssh_host_dsa_key)
) do |ssh|
  puts ssh.exec!('hostname')
end

Investigation

First, to use "hostbased authentication", your script need to read the local host's private-key. This file is read only by root, so, you must run your script with root privilege.

$ sudo ./ssh.rb

Second, Net::SSH::Authentication::Methods::Hostbased.authenticate_with method

def authenticate_with(identity, next_service, username, key_manager)
  debug { "trying hostbased (#{identity.fingerprint})" }
  client_username = ENV['USER'] || username

checks userneme by "ENV['USER']", then your script gets client_username as 'root'. I don't know why, but my host's /etc/ssh/sshd_configuration deny 'client_username = root' access. This is the problem.

Bad knowhow

I want 'client_username == username', so change the line like below.

def authenticate_with(identity, next_service, username, key_manager)
  debug { "trying hostbased (#{identity.fingerprint})" }
#  client_username = ENV['USER'] || username
  client_username = username

And you can run your script without Net::SSH::AuthenticationFailed.

拡張子一覧を作る

サーバにはどんなファイルがある?

ファイルサーバにどんなファイルがどれだけ入ってるのか調べてくれ,と言われました.ちょっと考えたんですが,うまいやり方を思いつかなかったので地道に手作業で調べてみたのでその手順です.

準備

まずはファイルサーバをネットワークドライブとしてAdministrator権限で接続します.そのためには,

net use \\servername password /USER:Administrator@mydomain.foo.co.jp

として,サーバに管理者権限でログインしてからGUIでネットワークドライブ接続します.net useの使い方は"net use /?"で確認できますが大したことは書いてありません.次にネットワークドライブ毎にファイル名の一覧を作成します.

Z:\>dir /B /L /OE /S /-D > c:\Documents and Settings\daiba\デスクトップ\filenames.txt

これで準備できました.dirの使い方は"dir /?"で確認できます.何気なく使ってるコマンドでも色々とオプションがあってちょっとした驚きがありますね.ま,そんなことはおいといて,必要なのは解析です.普段はperlでさくっと調べるのですが,今回はluaでやってみました.

luaプログラム

始めてなのか久しぶりなのかわからないぐらい忘れていたので単純に書いてみました.行毎に正規表現で処理して,それをテーブルに挿入し内容を書き出しています.拡張子の数の多いものから出力するようなことも考えてみたんですが,面倒になったのでそれはexcelか何かでやることにしました.

io.input("filenames.txt")

suffix = {}

while true do
  line = io.read()
  if (line == nil) then
    break
  end

  for result in string.gmatch(line, "%.%w%w%w$") do
    suffix[result] = suffix[result] and (suffix[result] + 1) or 1
  end
end

for key,value in pairs(suffix) do
  out = string.format("%4s  %d",key,value)
  print(out)
end

終わりに

luaはなかなか癖がある言語だけど,使いこなせれば面白そうです.nmapにも組み込まれているので,色んなチェックツールを書けそうです.

use Moose

Jabber Channel Bot

Google waveJabberを拡張したプロトコルを使うという話もあって,またJabberが盛り上がってきそうな今日このごろ,Channel(というかチャットルームと言った方がわかりやすい気もします)に投稿するBotを作ってみました.以前IRC用に作ったスクリプトJabber版です.最近の流行に乗ってMooseを使ってみることにしました.使い方はこんな感じです.

#!/usr/local/bin/perl
use strict;
use warnings;
use MyBot;

main() unless caller();

sub main {
    my $bot = MyBot->new(
        jid      => 'bot0@jabber.foo.co.jp',
        passwd   => 'password',
        chatRoom => 'lanman@conference.jabber.foo.co.jp',
        debug    => 1
    );
    $bot->run;
}

"main() unless caller()"は何かのスクリプトで見たのをそのまま使ったので,特に深い意味はありません.というかこの使い方の意味がわかってないです.今回使用したjabberサーバはejabberdなので,デフォルトでのチャットルームのjidは,"チャットルーム名@conference.サーバのfqdn"となります.それから,"debug => 1"はAnyEvent::XMPPのdebugモードを制御していて,何もしない0がデフォルト値になります.

MyBotのソース

AnyEvent::XMPPのsampleについてきたスクリプトをほとんどそのまま使用しています.serverPortで指定したportで待っていて,ここで受け付けたテキストをChatroomに投げる仕組みです.セキュリティは勘案してなくて,ホントにテストのためにのみ作っています.

package MyBot;

use Moose;
use AnyEvent;
use AnyEvent::Handle;
use AnyEvent::Socket;
use AnyEvent::XMPP::Client;
use AnyEvent::XMPP::Ext::Disco;
use AnyEvent::XMPP::Ext::Version;
use AnyEvent::XMPP::Ext::MUC;
use AnyEvent::XMPP::Namespaces qw/xmpp_ns/;
use AnyEvent::XMPP::Util qw/node_jid res_jid/;

has 'anyeventCondvar' => (
    is         => 'rw',
    isa        => 'AnyEvent::CondVar',
    lazy_build => 1,
);

has 'chatRoom' => (
    is       => 'rw',
    isa      => 'Str',
    required => 1,
);

has 'connectMessage' => (
    is       => 'rw',
    isa      => 'Str',
    required => 1,
    default  => 'Bot started!',
);

has 'jid' => (
    is       => 'rw',
    isa      => 'Str',
    required => 1,
);

has 'passwd' => (
    is       => 'rw',
    isa      => 'Str',
    required => 1,
);

has 'presence' => (
    is       => 'rw',
    isa      => 'Str',
    required => 1,
    default  => "Bot sample",
);

has 'serverPort' => (
    is       => 'rw',
    isa      => 'Int',
    required => 1,
    default  => 34832,
);

has 'tcpServer' => (
    is  => 'rw',
    isa => 'AnyEvent::Handle',
);

has 'xmppClient' => (
    is         => 'rw',
    isa        => 'AnyEvent::XMPP::Client',
    lazy_build => 1,
);

has 'debug' => (
    is       => 'rw',
    isa      => 'Int',
    required => 1,
    default  => 0,
);

__PACKAGE__->meta->make_immutable;

no Moose;

sub _build_anyeventCondvar {
    return AnyEvent->condvar;
}

sub _build_xmppClient {
    my $self = shift;

    my $cl = AnyEvent::XMPP::Client->new( debug => $self->debug );

    my $disco   = AnyEvent::XMPP::Ext::Disco->new;
    my $version = AnyEvent::XMPP::Ext::Version->new;
    my $muc     = AnyEvent::XMPP::Ext::MUC->new( disco => $disco );

    $cl->add_extension($disco);
    $cl->add_extension($version);
    $cl->add_extension($muc);
    $cl->set_presence( undef, $self->presence, 1 );
    $cl->add_account( $self->jid, $self->passwd );

    $cl->reg_cb(
        session_ready => sub {
            my ( $cl, $acc ) = @_;
            $muc->join_room( $acc->connection, $self->chatRoom,
                node_jid( $acc->jid ) );
        },
        contact_request_subscribe => sub {
            my ( $cl, $acc, $roster, $contact ) = @_;
            $contact->send_subscribed;
        },
        connected => sub {
            $cl->send_message( $self->connectMessage, $self->chatRoom,
                $self->jid, 'groupchat' );
            0;
        },
    );

    $self->xmppClient($cl);
}

sub tcp_server_setup {
    my $self = shift;

    AnyEvent::Socket::tcp_server undef, $self->serverPort, sub {
        my ( $clsock, $host, $port ) = @_;
        $self->tcpServer(
            AnyEvent::Handle->new(
                fh       => $clsock,
                on_error => sub { print "Client connection error:\n" }
            )
        );
        $self->tcpServer->push_read(
            line => sub {
                my ( undef, $line ) = @_;
                $self->xmppClient->send_message( $line, $self->chatRoom,
                    $self->jid, 'groupchat' );
                $self->tcpServer->on_drain(
                    sub {
                        $self->tcpServer->fh->close;
                        $self->tcpServer();
                    }
                );
            }
        );
    };
}

sub run {
    my $self = shift;

    $self->tcp_server_setup;

    $self->xmppClient->start;
    $self->anyeventCondvar->wait;
}

1;

注意しないといけないのは,"$cl->send_message()"の第4引数です.チャットルームに投稿する場合,ここで指定するメッセージタイプは'groupchat'になります.

Compile Xen3.4.0 on CentOS5.3 + VMWare

Xen

最近Xen関係のトラブルにはまってます.ぐぐってもよくわからないし,ここは心機一転,ソースからコンパイルして,仕組みを勉強してみようと思いました.なんとかDom0が動くようになったので,そこまでのまとめです.

Install CentOS5.3

CentOS-5-3-i386-netinstall.isoをダウンロードしてVMWare上にインストールしました.このインストーラが聞いてくるパッケージのダウンロード元には

サーバ パス
ftp.riken.jp Linux/centos/5.3/os/i386

を指定しました.CentOS5.3ではbaseパッケージグループがデフォルトで指定されているようなので,パッケージグループ選択の際には何も指定しません.これでCentOS5.3が動く所までできました.この後,パッケージのアップデートと追加のインストールを行います.以下の作業は新規にアカウントを作成せずにrootアカウントで実行しました.

# yum update
# yum groupinstall 'Development Tools'
# yum groupinstall 'X Software Development'
# yum install openssl-devel
# yum install nucrses-devel
# yum install python-devel
# yum install bridge-utils

Download & Compile Xen3.4.0

Xenをダウンロードしてコンパイルします.

# wget http://bits.xensource.com/oss-xen/release/3.4.0/xen-3.4.0.tar.gz
# tar xvfz xen-3.4.0.tar.gz
# cd xen-3.4.0
# make

makeを実行すると,途中でいくつか質問がでてきます.取りあえず初回なのですべてDefault値を採用しました.以下のようになります.

PCI Device Reservation for Passthrough (PCI-GUESTDEV) [Y/n/?] Y
PCI IOV support (PCI_IOV) [N/y/?] N
Intel(R) 82575 Gigabit Ethernet support (IGB) [N/m/y/?] N
Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support (E1000E) [N/m/y/?] N
Intel(R) 10GbE PCI Express adapters support (IXGBE) [N/m/y/?]N

USB backend driver (XEN_USB_BACKEND) [M/n/?] M
USB frontend driver (XEN_USB_FRONTEND) [M/n/?] M
Taking the HCD statistics (for debug) (XEN_USB_FRONTEND_HCD_STATS) [Y/n/?] Y

しばらくするとコンパイルが終了します.よく見てると,最後に

WARNING: Package 'latex' is required to build Xen documentation

と出てきますが,これは気にしない.ここまでできたらInstallします.

# cd dist
# ./install.sh

このコマンドを実行すると,最終的に以下のような出力がでます.すべてOKとなっているか確認してください.なっていなければ何かが足りません.

Xen CHECK-INSTALL Tue May 26 04:47:22 JST 2009
Checking check_brctl: OK
Checking check_crypto_lib: OK
Checking check_curl: unused, OK
Checking check_iproute: OK
Checking check_python: OK
Checking check_python_xml: OK
Checking check_udev: OK
Checking check_xml2: unused: OK
Checking check_zlib_lib: OK
All done.

これでプログラム作成が終了しました.この後は,boot用の設定を作ることになります.

Setup Grub.conf

ここら辺からは,ここらへんを参考にしながら試行錯誤しました.なぜそれを実行しないといけないかがよくわかっていないので,これから調べます.まず,depmondを実行します.

# /sbin/depmond 2.6.18.8-xen

次にmkinitrdを実行しますが,最新のmkinitrd-5.1.19.6-44にはバグがあるので,/sbin/mkinitrdを以下のように編集します.

1306   if [ "$withdmraid" == "1" ]; then
1307       findmodule -dm-mem-cache
1308       findmodule -dm-region_hash
1309       findmodule -dm-message
1310       findmodule -dm-raid45
1311   fi

左端の数字は行数です.足すのはdm-mem-cache/dm-region_hash/dm-member/dm-raid45の前にある-です.編集したら,コマンドを実行します.

/sbin/mkinitrd /boot/initrd-2.6.18.8-xen.img 2.6.18.8-xen

この後,/boot/grub/grub.confにXen用の設定を追加します.

title xen
root (hd0,0)
kernel /xen.gz
module /vmlinuz-2.6.18.8-xen ro root=/dev/VolGroup00/LogVol00
module /initrd-2.6.18.8-xen.img 2.6.18.8-xen

ここまで設定してリブートすれば,なんだかものすごく時間がかかるのですが,XenをサポートしたDom0が起動します.でも,

Currently emulating unsupported memory accesses in /lib/tls glib libraries. The emulation is slow. To ensure full performance you should install a 'xen-freindly' (nosegneg) version of the library, or disable tls support by executing the following as root:
mv /liv/tls /lib/tls.disabled
Offending process: modprobe (pid=914)

というメッセージが最後に出ています./lib/tlsはなかったと思うので,これが何を意味しているのかよくわかりません.この後は,

# chkconfig --add xend

とやれば,起動時にXendが動くので,

# xm list

とコマンドした時にDom0が動いてるのが確認できます.

終わりに

現段階では起動にえらく時間がかかります.これがTLS(Thread Local System)に起因する問題なのか,Kernelコンパイル時の設定に依存した問題なのかがまだわかりません.DomUもまだ動かしていないのでちゃんと動くかどうかこれからです.

Capistrano事始め

インストールするまで

サーバを沢山管理することになりました.それらのサーバではrubyを使っていたので,rubyベースのdeployツールCapistranoを使ってみる事にしました.Capistranoは2009/2に作者がもうメンテナンスしないぜと宣言したプロダクトです.とはいっても,コミュニティがメンテすることになるだろうから今後も問題ないだろうなと思ってます.それはそれとして,CapistranoをインストールするにはRubyGemsが必要なのでまずはそこからインストールします.RubyGems の使い方 - WebOS Goodiesを見ながらwgetでファイルをダウンロードして,

# ruby setup.rb

でインストールします.Capistrano

$ sudo gem install capistrano

でインストールできます.

秘密鍵の管理

普段色々鍵を使っていてdefaultの".ssh/id_dsa"とかを使うようにはしたくなかったので,明示的に鍵を指定するようにしました.もしかしたら,.ssh/configが使えたのかもしれないですが,調べてないです…

role :test1, "sv100.foo.co.jp"

task :hostname, :roles => :test1 do
  run "hostname"
end

ssh_options[:keys] = %w(/home/daiba/.ssh/capistrano)
ssh_options[:auth_methods] = %w(publickey)

これで,test1というロールで指定したホスト群に対して,/home/daiba/.ssh/capistranoという秘密鍵sshして,hostnameを実行し,その結果を表示します.

メニュー化

Capistranoはdefaultでcapfileという名前のファイルを選んで,その上で定義したルールを実行しますが,-fオプションを付けるとファイルを指定することもできます.

$ cap hostname
$ cap -f CAPFILE hostname

ロールを沢山作った時にロールが覚えられなくなるだろうと思ったので,menuというロールを作って,そこから選択できるようにしてみました.

role :test1, "sv100.foo.co.jp"

desc "menu list"
task :menu do
  Capistrano::CLI.ui.say("\nThis is with a oneline menu layout...")
  Capistrano::CLI.ui.choose do |menu|
    menu.layout = :one_line

    menu.header = "Execute"
    menu.prompt = "Application?  "

    menu.choice :hostname do
      hostname
    end
    menu.choice :whoami do
      whoami
    end
    menu.choices(:skip, :exit) do
      Capistrano::CLI.ui.say("Choose not to run..")
    end
  end
end

task :hostname, :roles => :test1 do
  run "hostname"
end
task :whoami, :roles => :test1 do
  run "whoami"
end

この場合だと,hostnameとwhoamiが選択できます.

sudoでパスワードを入力

sshするだけではなく,別ユーザになってコマンドを実行したいときがあります.この場合はsudoを利用するわけですが,そのときはこんな感じに使います.

role :test1, "sv100.foo.co.jp"

set :sudo_password, 'Password:'

task :whoami do
  run "#{sudo :as => 'oops'} whoami", roles => :test1 do |channel, stream, data|
    if stream == :out
      puts channel[:host] + ': ' + data
    end
  end
end

"set :sudo_pasword, 'Password:'"はsudoプログラムが出力する文字列を指定しているので,システムによっては変更する必要があるでしょう.defaultでは"sudo password: "が割り当てられています.これで,sudoになる時のパスワードがキャッシュされていなければCapistranoが質問してきます.sudo変数を使うのでなければ,以下のような使い方もできます.

role :test1, "sv100.foo.co.jp"

set(:my_password) { Capistrano::CLI.password_prompt("My password: ") }

task :whoami do
  run "sudo -u ops whoami", :roles => :test1 do |channel, stream, data|
    if data =~ /^Password:/
      channel.send_data "#{my_password}\n"
    end
    if stream == :out
      puts data
    end
  end
end

dynamicにロールのターゲットを作成

role対象のホストを一個づつ書くのは面倒なので,スクリプトをそこに書きたくなります.ターゲットは"hostA, hostB, hostC"のような文字列か,配列を与えることができるので,こんな使い方ができます.

role(:servers) do
  hosts = Array.new
  100.upto 200 do |x|
    hosts.push('sv' + String(x) + '.foo.co.jp')
  end
  hosts
end

task :hostname, :roles => :servers, :max_hosts => 10 do
  run "hostname"
end

[5/20追加]1000台のマシンに対して実行したらプロセスがうんともすんとも言わなかったので調べてみたら,defaultではsshセッションの上限が設定されてないようでした.そのため,大量のホストにコマンドを実行する際には,":max_hosts"で一度に張るセッションの上限を設定する必要があります.":max_hosts"は将来なくなるかもしれないオプションのようです.

scpでファイル配布(書くのを忘れてたので追加)

ファイル配布にはsftpとscpが使えます.普段scpを使ってるのでそっちしか試してません.設定は以下のようになるのですが,

role :test1, "sv100.foo.co.jp"

desc "upload file"
task :upload!, :roles => :test1  do
  upload("target_file.txt", "/tmp", :via => :scp)
end

uploadはローカルマシンからターゲットマシンへの転送,逆方向の場合はdownloadになります.

さて

苦労した割にはtipsが溜まらなかったです.ここでやっているようなことをArcher - yet another deployment tool - metacpan.orgでやり直すかどうかを悩んでいるところ.

Xenの話

4gb seg fixup

Xenを使ってる人が,DomU上で"4gb seg fixup"というメッセージが大量にでるという話をしていました.調べてみると,XenのFAQに載っていて,

These messages are from a glibc that was built with negative GS register offsets. Xen can run with negative GS register references, but it must "trap and emulate" this condition, which is relatively resource intensive, and quite slow.

という状態にあることがわかりました.ところが,ここからリンクされてるページを見て,コマンドを叩いてみると

# ldconfig -v -p 2>&1 | grep libc.so
 libc.so.6 (libc6, hwcap: 0x0018000000000000, OS ABI: Linux 2.6.9) => /lib/i686/nosegneg/libc.so.6
 libc.so.6 (libc6, OS ABI: Linux 2.6.9) => /lib/libc.so.6

となるので,設定は正しいらしいのです.エラーを吐いているのはどうやらrubyスクリプトで,当人がコンパイルしたものだということなので,もう一度コンパイルしなおすか,という話に.ちなみに,nosegnegってのがよくわからずに見つけたのがこのページ

+ * We supply "nosegneg" as the fake capability, to indicate that we
+ * do not like negative offsets in instructions using segment overrides,
+ * since we implement those inefficiently.

ということで,Xen用に作られたオプションらしいです.

イメージコピー

コンパイルしたrubyを今までとは違うパスに入れてテストするか,と言っていた時に,DomUなんだからイメージをまるごとコピーしたインスタンスを作ってそこで試せばいいってことに気づきました.調べて見つけたのがこのページ.マニュアルのサンプルを見ると,要は

# virt-clone \
    --original demo \
    --name newdemo \
    --file /var/lib/xen/images/newdemo.img

こんな感じ.uuidとかmacアドレスとかは勝手に設定してくれます.もしそれらの設定も自分でやりたければ,このページが役に立ちます.

xircd

twitter APIが変わったのにCPANcodereposのコードが進化しない今日この頃,githubで開発されていることを知りました.んで,落としてきてmake testしてみたら通らない.

xt/98_perlcritic.t .. 1/11 
#   Failed test 'Test::Perl::Critic for "lib/XIRCD.pm"'
#   at /usr/local/lib/perl5/site_perl/5.8.8/Test/Perl/Critic.pm line 99.
# 
# Perl::Critic had errors in "lib/XIRCD.pm":
#       The TestingAndDebugging::RequireUseStrict policy doesn't take a "equivalent_modules" option.
xt/98_perlcritic.t .. 2/11 
#   Failed test 'Test::Perl::Critic for "lib/XIRCD/Base.pm"'
#   at /usr/local/lib/perl5/site_perl/5.8.8/Test/Perl/Critic.pm line 99.
# 
# Perl::Critic had errors in "lib/XIRCD/Base.pm":
#       The TestingAndDebugging::RequireUseStrict policy doesn't take a "equivalent_modules" option.
xt/98_perlcritic.t .. 3/11 
#   Failed test 'Test::Perl::Critic for "lib/XIRCD/Component.pm"'
#   at /usr/local/lib/perl5/site_perl/5.8.8/Test/Perl/Critic.pm line 99.
# 
# Perl::Critic had errors in "lib/XIRCD/Component.pm":
#       The TestingAndDebugging::RequireUseStrict policy doesn't take a "equivalent_modules" option.
xt/98_perlcritic.t .. 4/11 
#   Failed test 'Test::Perl::Critic for "lib/XIRCD/Role.pm"'
#   at /usr/local/lib/perl5/site_perl/5.8.8/Test/Perl/Critic.pm line 99.
# 
# Perl::Critic had errors in "lib/XIRCD/Role.pm":
#       The TestingAndDebugging::RequireUseStrict policy doesn't take a "equivalent_modules" option.
xt/98_perlcritic.t .. 5/11 
#   Failed test 'Test::Perl::Critic for "lib/XIRCD/Server.pm"'
#   at /usr/local/lib/perl5/site_perl/5.8.8/Test/Perl/Critic.pm line 99.
# 
# Perl::Critic had errors in "lib/XIRCD/Server.pm":
#       The TestingAndDebugging::RequireUseStrict policy doesn't take a "equivalent_modules" option.
xt/98_perlcritic.t .. 6/11 
#   Failed test 'Test::Perl::Critic for "lib/XIRCD/Component/RSS.pm"'
#   at /usr/local/lib/perl5/site_perl/5.8.8/Test/Perl/Critic.pm line 99.
# 
# Perl::Critic had errors in "lib/XIRCD/Component/RSS.pm":
#       The TestingAndDebugging::RequireUseStrict policy doesn't take a "equivalent_modules" option.
xt/98_perlcritic.t .. 7/11 
#   Failed test 'Test::Perl::Critic for "lib/XIRCD/Component/Rejaw.pm"'
#   at /usr/local/lib/perl5/site_perl/5.8.8/Test/Perl/Critic.pm line 99.
# 
# Perl::Critic had errors in "lib/XIRCD/Component/Rejaw.pm":
#       The TestingAndDebugging::RequireUseStrict policy doesn't take a "equivalent_modules" option.
xt/98_perlcritic.t .. 8/11 
#   Failed test 'Test::Perl::Critic for "lib/XIRCD/Component/Time.pm"'
#   at /usr/local/lib/perl5/site_perl/5.8.8/Test/Perl/Critic.pm line 99.
# 
# Perl::Critic had errors in "lib/XIRCD/Component/Time.pm":
#       The TestingAndDebugging::RequireUseStrict policy doesn't take a "equivalent_modules" option.
xt/98_perlcritic.t .. 9/11 
#   Failed test 'Test::Perl::Critic for "lib/XIRCD/Component/Twitter.pm"'
#   at /usr/local/lib/perl5/site_perl/5.8.8/Test/Perl/Critic.pm line 99.
# 
# Perl::Critic had errors in "lib/XIRCD/Component/Twitter.pm":
#       The TestingAndDebugging::RequireUseStrict policy doesn't take a "equivalent_modules" option.

#   Failed test 'Test::Perl::Critic for "lib/XIRCD/Component/Wassr.pm"'
#   at /usr/local/lib/perl5/site_perl/5.8.8/Test/Perl/Critic.pm line 99.
# 
# Perl::Critic had errors in "lib/XIRCD/Component/Wassr.pm":
#       The TestingAndDebugging::RequireUseStrict policy doesn't take a "equivalent_modules" option.
xt/98_perlcritic.t .. 11/11 
#   Failed test 'Test::Perl::Critic for "lib/XIRCD/Role/Dedup.pm"'
#   at /usr/local/lib/perl5/site_perl/5.8.8/Test/Perl/Critic.pm line 99.
# 
# Perl::Critic had errors in "lib/XIRCD/Role/Dedup.pm":
#       The TestingAndDebugging::RequireUseStrict policy doesn't take a "equivalent_modules" option.
# Looks like you failed 11 tests of 11.
xt/98_perlcritic.t .. Dubious, test returned 11 (wstat 2816, 0xb00)
Failed 11/11 subtests 

これってもしかしたら,Mooseを使ってるときにはequivalent_modulesオプションで何か指定してやらないと行けないってことなのかな?思いついただけなので,明日起きたら試す.zZZ

追加:2009/04/23

equivalent_modulesオプションがサポートされたのは,Perl::Critic 1.094からなんだけど,これにはバグがあって1.096で修正されたみたい.最新のバージョンは1.098でこれにupgradeしたらtestが通った.