nadare.net保守日記

«前の日記(Mon Jan 31, 2005) 最新 次の日記(Sat Feb 05, 2005)» 編集

ここはyamagが {powder|white|tdiary}.nadare.netと自宅のLinuxBoxをいぢくった時のメモを書いておく場所なので、見てもつまんないと思いまっせ ;-)

ツッコミランキング1.satoshis(4) 2.TrackBack(2) 3.globe term life insurance(1) 4.xzhcrumw oksmcr(1) 5.online payday loan service(1)

Wed Feb 02, 2005 [長年日記]

#1 [Linux] Brute Force 攻撃防御

インターネットにサーバを晒していると、当然のことながら攻撃を受けるわけで、sshd 向けに絨毯爆撃しかけてくる連中を排除すべく、ちょっとしたスクリプトを書いて仕掛けました。

#!/usr/bin/perl
 
$LogDir="/var/log";
$MsgFile="secure";
$DenyCnf="/etc/hosts.deny";
 
$Pattern="^([A-Z][a-z][a-z]) ([ 0-9][0-9]) ([0-9][0-9]:[0-9][0-9]:[0-9][0-9]) .+ sshd\[[0-9]+\]: Failed password for illegal user ([^\S]+) from ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)";
 
$fsdev=0;
$ino  =1;
$mode =2;
$nlink=3;
$owner=4;
$group=5;
$dev  =6;
$size =7;
$atime=8;
$mtime=9;
$ctime=10;
$bsize=11;
$blks =12;
 
$need_seek=0;   # for DEBUG
#$need_seek=1;
$DEBUG=1;
 
open(CNF, "< $DenyCnf") || die "file open error. $!\m";
while ()
{
    if ($_ =~ "^ALL:(.*)")
    {
        $denylist{$1}='1';
    }
}
close(CNF);
 
print "--denylist--\n";
foreach $deny ( keys(%denylist) )
{
    print "$deny\n";
}
print "--denylist--\n";
                                                                                 
while (true)
{
    open(IN, "< $LogDir/$MsgFile") || die "file open error. $!\n";
    if ($need_seek == 1)
    {
        seek(IN, 0, 2);
        $need_seek=0;
    }
    $rec_ptr=tell(IN);
    # print "DEBUG start pointer $rec_ptr\n";
    while (true)
    {
        @w_fstat=stat("$LogDir/$MsgFile");
        @c_fstat=stat(IN);
        # print "DEBUG size $w_fstat[$size] ptr $rec_ptr\n";
        while ($c_fstat[$size] > $rec_ptr)
        {
            # print "DEBUG size $w_fstat[$size] ptr $rec_ptr\n";
            $line=;
            if ($line =~ $Pattern)
            {
                if (! exists $denylist{$5})
                {
                    print "catch  $1_$2_$3_$4_$5\n";
                    $newdeny{$5}++;
                    if ($newdeny{$5} > 5 || $4 eq "test" || $4 eq "guest" ||
                        $4 eq "admin"    || $4 eq "user" )
                    {
                        print "insert $1_$2_$3_$4_$5\n";
                        $denylist{$5}='1';
                        open(OUT,">> /etc/hosts.deny") || die "file open error.
$!\n";
                        print OUT "ALL:$5\n";
                        close(OUT);
                    }
                }
            }
            $rec_ptr=tell(IN);
        }
        last if ($c_fstat[$ino  ] != $w_fstat[$ino  ]);
        # print "DEBUG current ino %$c_fstat[$ino]%, file ino %$w_fstat[$ino]%\n" if ($DEBUG == 1);
        last if ($c_fstat[$size ] < $w_fstat[$size ]);
        sleep(1);
    }
    close(IN);
    $DEBUG=0;
    # print "DEBUG change log file";
}


このスクリプトは、sshでのログイン認証の失敗数をカウントしており、一定回数以上間違っていた場合や、testとかadminとか、明らかにアタックと判断されるアクセスがあった場合、自動的に deny.host リストにアドレスを追加して、攻撃をブロックするというものです。

ここ数日、このスクリプトを実行していますが、何件か引っかかったアホがおります。

catch  Jan_29_12:17:28_patrick_61.100.6.70
catch  Jan_29_12:17:31_patrick_61.100.6.70
catch  Jan_29_12:17:50_rolo_61.100.6.70
catch  Jan_29_12:17:53_iceuser_61.100.6.70
catch  Jan_29_12:17:56_horde_61.100.6.70
catch  Jan_29_12:17:59_cyrus_61.100.6.70
insert Jan_29_12:17:59_cyrus_61.100.6.70
catch  Feb_ 1_02:10:19_test_65.33.111.160
insert Feb_ 1_02:10:19_test_65.33.111.160
catch  Feb_ 1_09:50:10_test_67.108.93.195
insert Feb_ 1_09:50:10_test_67.108.93.195
catch  Feb_ 2_07:09:54_test_218.65.87.12
insert Feb_ 2_07:09:54_test_218.65.87.12
catch  Feb_ 2_09:50:28_patrick_195.70.36.86
catch  Feb_ 2_09:50:33_patrick_195.70.36.86
catch  Feb_ 2_09:51:03_rolo_195.70.36.86
catch  Feb_ 2_09:51:08_iceuser_195.70.36.86
catch  Feb_ 2_09:51:13_horde_195.70.36.86
catch  Feb_ 2_09:51:18_cyrus_195.70.36.86
insert Feb_ 2_09:51:18_cyrus_195.70.36.86
catch  Feb_ 2_16:15:13_test_67.70.221.189
insert Feb_ 2_16:15:13_test_67.70.221.189
本日のツッコミ(全3件) [ツッコミを入れる]
1 satoshis (Fri Feb 04, 2005 14:13)

 攻撃に対して、自動的に対応するって良いですね。メールサーバへのSPAMアタックにもこういうの作れないかな…。

2 satoshis (Thu Feb 10, 2005 01:47)

とりあえず、都度ログ全部なめてbadmailfromに突っ込むとこまではできました。ダサい…。

3 satoshis (Mon Feb 14, 2005 20:02)

 メール版作りました。使用するログがとあるウイルスチェックソフトのなんで公開できないのが残念ですが。<br>○ seek (IN,0,1); で、end-of-fileエラーをリセットできるとかなり幸せ。(cf.プログラミングPerl 関数seek解説)<br>○use FileHandle;.... ; OUT->autoflush(1);で、バッファ無しで即時追加。<br>○真似して、<br>last if ($inode != (stat($infile))[1]);<br>とやって、ログローテートしたときに、openし直すようにしてみたけどうまく行かなかったんで、cronで一分後に再起動。ダサいのが残ってしまいました。

本日のTrackBacks(全2件) []
ヒビノアワ:まるでゴキブリほいほいのように (Sun Nov 13, 2005 18:11)

先日、自宅サーバの設定をいろいろ見直してみた。 で、今まで使っていたLogwat...

雑多なメモ:[その他技術]ssh向けBrute Force攻撃防御 (Thu Mar 09, 2006 02:17)

やろうやろうと思いつつ、今頃になってしまいました。実際、自宅サーバに仕込んでみましたが、これ良いですね。 ちなみに、自分の環境では、$Patternを(メッセージの部分だけですが)書き換える必要がありました。 結果次第ではdoyouphp.jpにも採用決定、ということで。


2003|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|
«前の日記(Mon Jan 31, 2005) 最新 次の日記(Sat Feb 05, 2005)» 編集