mt-comment.cgi 及び mt-tb.cgi を自動的に renameする

相変わらずコメントスパムだの、トラックバックスパムだのに悩まされています。

対策として、「TrackBack Auto-Discovery の記述をテンプレートから取っ払ってしまうのが有効だ!」「そもそもトラックバックって要るの?」などといわれている昨今ですが、個人的にはとても違和感を感じています。だって便利なものは便利なわけで、それを心無いスパム業者の為に使うのを止めるって、何だか悔しいじゃないですか。

というわけで、前々から考えていた対策を施すことにしました。簡単に言えば、このエントリのタイトル通りのことをしました。

スパム対策には、mt-comment.cgi 及び mt-tb.cgi をリネームしてあげることが有効です。これらをリネームした後、mt-config.cgi の CommentScript 及び TrackbackScript でその名前を指定し、リビルドしてあげます。

しかし、その有効期間は意外と短いですね。一週間くらいでしょうか?「亜細亜ノ蛾」でもそのようなことが書かれていますね。この「Junk slowdown」というスクリプトは今回の対策を行ってから知ったのですが、まぁ、今回の対策で効果が無かったら連携してみようかしら。

話は逸れましたが、リネームしてスパム業者がコメント先、トラックバック先を見失っても、一週間ほどでそれは修正され、新しい住所にスパムがやってくるようになります。そこで再度リネームをしたりするわけですが、毎度毎度これを実行するのは結構面倒くさいです。

そこで、これらの作業を自動的にやってもらうようにしました。具体的には以下のようなスクリプトを書いて、cron に食わせています。いつも通り、とりあえず動けばいいやでやっているので、かなり汚いスクリプトだとは思いますが。たぶん右端が切れてると思うので、ちゃんと読みたいという酔狂な方はこちらをどうぞ。→ファイルをダウンロード


#!/usr/bin/perl

use strict;
use Data::Dumper;

# ----- Setting start ----- #
my $mt_dir = '/path/to/mt/';
my $from = 'from@hogehoge.com';
my $to = 'to@hogehoge.com';
my $sendmail_path = "/path/to/sendmail";
# ------ Setting end ------ #

# ----- Added library.
unshift @INC, $mt_dir . 'lib';
unshift @INC, $mt_dir . 'extlib';

# ----- Make random number.
my $new_cm_script = 'mt-comment-'.&create_random_string().'.cgi';
my $new_tb_script = 'mt-tb-'.&create_random_string().'.cgi';

# ----- Path to config file.
my $cfg_file = $mt_dir . 'mt-config.cgi';

# ----- Rewrite script name.
my @cfg;
my $old_cm_script;
my $old_tb_script;
open(IN,"< $cfg_file") or die "Can't open ".$cfg_file." : $!";
flock(IN, 1) or die "Can't flock  : $!";
while (<IN>) {
    if ($_ =~ /(^CommentScript )(.*)\n/) {
        push @cfg, $1.$new_cm_script."\n";
        $old_cm_script = $2;
    } elsif ($_ =~ /(^TrackbackScript )(.*)\n/) {
        push @cfg, $1.$new_tb_script."\n";
        $old_tb_script = $2;
    } else {
        push @cfg, $_;
    }
}
close(IN);
open(OUT, "+< $cfg_file");
flock(OUT, 2);
seek(OUT, 0, 0);
for my $str (@cfg) {
    print OUT $str;
}
truncate(OUT, tell(OUT));
close(OUT);

# ----- Rename Script.
rename($mt_dir.$old_cm_script, $mt_dir.$new_cm_script);
rename($mt_dir.$old_tb_script, $mt_dir.$new_tb_script);

# ----- Get MT object.
require MT;
my $mt = MT->new( Config => $cfg_file, Directory => $mt_dir );

# ----- Mail String.
my $mstr;
$mstr .= ' * Old comment script name: '.$old_cm_script."\n";
$mstr .= ' * New comment script name: '.$new_cm_script."\n";
$mstr .= ' * Old trackback script name: '.$old_tb_script."\n";
$mstr .= ' * New trackback script name: '.$new_tb_script."\n";
$mstr .= "\n";

# ----- Get weblog.
require MT::Blog;
my @blogs = MT::Blog->load( undef, {unique => 1} );
# sort.
@blogs = sort {$a->id <=> $b->id} @blogs;
for my $blog (@blogs) {
    # Rebuild welog.
    $mstr .= ' * Rebuild start blogID "'.$blog->id.'".'."\n";
    $mt->rebuild( BlogID => $blog->id )
        or $mstr .= '   * Rebuild error! blogID "'.$blog->id.'".'."\n".$mt->errstr;
    $mstr .= ' * Rebuild end blogID "'.$blog->id.'".'."\n\n";
}

# ----- Send mail.
my $subject = '[info] The rename script was running.';
open(SENDMAIL, "|$sendmail_path -t");
print SENDMAIL <<END;
From: $from
To: $to
Subject: $subject

$mstr
END
close(SENDMAIL);

sub create_random_string {
    srand();
    my @charset = ('a'..'z','A'..'Z','0'..'9');
    my $pwd = '';
    for (my $i=0; $i<8; $i++){
        $pwd .= $charset[int(rand(62))];
    }
    return $pwd;
}

やっていることは、以下の通り。

  1. ランダムな8文字の文字列を取得し、mt-comment-xxxxxxxx.cgi、mt-tb-xxxxxxxx.cgi とファイル名を決定
  2. mt-config.cgi を書き換え
  3. cgi ファイルをリネーム
  4. MT をリビルド
  5. 結果をメール送信

僕のところでは、一週間に一度これを動かすようにしてみました。早朝のアクセスが少ない時間帯に走らせます。毎日やるのが効果が高いんでしょうが、フルリビルドが走るのでなるべく頻度を低くした方が良いのかと。その辺はスパム来襲の具合を見て調整ですかね。

ただし、これでまったくスパムが来なくなるというわけではないことに注意してください。スパム業者には酔狂な輩がいて、明らかに手動で送信しているだろ!的なケースも多々有り、それは防げません。防げるのはあくまでも、機械的に大量にスパムを送りつけてくる、サーバーに著しく負荷をかけるようなケースだけです。ま、それで十分有効ですよね。