网上找的旧的但属精典的代码(帮忙分析)

网上找的旧的但属精典的代码(帮忙分析)

#!/usr/bin/perl -w

#

# proftpd log 文件实时分析,动态封禁/解封

# 用法:

# tail -f /var/log/proftpd | /usr/bin/proftpdeny.pl

#

# Zhuohuan Li 《zixia@zixia.net

# Beijing 2003-02-23

#


use Time::HiRes qw(gettimeofday);


# 封禁时间,以秒为单位

$DENY_PERIOD=600;

# 对最近多久的日志进行统计

$EVAL_PERIOD=60;

# 在 EVAL_PERIOD 中的最多连接次数

$DENY_TIMES=5;


# 数组,记录 IP/最后登陆时间/重试次数

%BADLIST = ();
%DENIED_IP = ();

init_iptables();

while (《STDIN》){
chomp $_;
$line = $_;

$badip = get_bad_ip($line) ;

if (! $badip ) {
next;
}

#print STDERR "badip: $badip\n";


# 删除 BADLIST 中的过期 IP

refresh_bad_ip();

# 添加multi login的ip到BADLIST

add_bad_ip( $badip );

# 把平均每秒连接次数 》 $DENY_RETRY_TIMES_PER_SEC 的 IP 封掉

check_bad_ip();

# 将封禁时间 》 $DENY_PERIOD 的ip解封

undeny_bad_ip();
}

exit(0);

##############################

sub get_bad_ip
{
local( $line );
$line = $_[0];
return undef if ( ! $line );

if ( $line =~ /ftp\.zixia\.net \((\d+\.\d+\.\d+\.\d+)\[[^\]]+\]\) -
Connection refused \(max clients per host \d+\)\./ ) {
return $1;
} else {
return undef;
}
}

sub add_bad_ip
{
local ( $badip );
$badip = $_[0];
die "add_bad_ip() take no param err" unless $badip;

($seconds, $microseconds) = gettimeofday;

$BADLIST{$badip}{$seconds . '.' . $microseconds} = 1; ######这段具体是什么意思?二维散列?表示的意思是企么样的,没有想通,请大家帮帮忙

#print STDERR "add_bad_ip: $badip, $seconds\n";

}

sub refresh_bad_ip
{
foreach $ip ( keys %BADLIST ){                    ######这段具体是什么意思?二维散列?表示的意思是企么样的,没有想通,请大家帮帮忙!

foreach $secmic ( keys %{$BADLIST{$ip}} ){
if ( $secmic =~ /^(\d+)\.(\d+)$/ ){
$seconds = $1;

if ( time - $seconds 》 $EVAL_PERIOD ){
delete $BADLIST{$ip}{$secmic} ;
#print STDERR "refresh_bad_ip: delete badlist $ip $secmic\n";

}
}
}
$num = keys %{$BADLIST{$ip}};
if ( 0==$num ) {
delete $BADLIST{$ip};
}
}
}

sub check_bad_ip
{
foreach $ip ( keys %BADLIST ){
$login_num = keys ( %{$BADLIST{$ip}} ); ######这段具体是什么意思?二维散列?表示的意思是企么样的,没有想通,请大家帮帮忙!


#print STDERR "check_bad_ip: ip $ip has $login_num times login attampts..\n";



if ( $login_num 》 $DENY_TIMES ) {
deny_bad_ip ( $ip ) ;
delete $BADLIST{$ip};
}
}
}

sub deny_bad_ip
{
local $ip;
$ip = $_[0];

die "deny_bad_ip no ip err" unless $ip;

foreach ( keys %DENIED_IP ){
return if ( /^$ip$/ )
}

$cmd = "iptables -A ftpDeny -p tcp -s $ip -j REJECT --reject-with
tcp-reset";
#print STDERR "sys cmd: $cmd\n";

system ( $cmd );
$DENIED_IP{$ip} = time;

$date = `date`;
chomp $date;
system ( "printf \"%s %-16s denied.\n\" \"$date\" $ip 》》/var/log/proft
pd.deny" )
}

sub undeny_bad_ip
{
foreach $ip ( keys %DENIED_IP ){
if ( time - $DENIED_IP{$ip} 》 $DENY_PERIOD ) {
$line_number = `iptables -nL ftpDeny --line-number |
grep $ip | awk {'print \$1'}`;
chomp $line_number;
$cmd = "iptables -D ftpDeny $line_number";

system ( $cmd );
delete $DENIED_IP{$ip};

$date = `date`;
chomp $date;
system ( "printf \"%s %-16s undenied.\n\" \"$date\"
$ip 》》/var/log/proftpd.deny" )

}
}
}

sub init_iptables
{
$cmd1 = "iptables -F ftpDeny 》 /dev/null 2》&1";
$cmd2 = "iptables -X ftpDeny 》 /dev/null 2》&1";
$cmd3 = "iptables -N ftpDeny 》 /dev/null 2》&1";

$cmd4 = "iptables -I INPUT -p tcp --dport 59000:60000 -j ftpDeny";
$cmd5 = "iptables -I INPUT -p tcp --dport 20:21 -j ftpDeny";

$exist = `iptables -nL INPUT | grep ftpDeny | wc -l | awk {'print
\$1'}`;


system( $cmd1 );
system( $cmd2 );
system( $cmd3 );

if ( 0==$exist ) {
system( $cmd4 ) ;
system( $cmd5 ) ;
}
}
是二维散列, 大概这样的一个数据结构:
%BADIP = {
        ip地址1 => {
                "秒.毫秒" => 1,
                "秒.毫秒" => 1,
                ...
        },
        ip地址2 => {
                "秒.毫秒" => 1,
                ...
        },
        ...
}

落叶季节,思念季节


QUOTE:
原帖由 con 于 2008-10-4 23:08 发表
是二维散列, 大概这样的一个数据结构:
%BADIP = {
        ip地址1 => {
                "秒.毫秒" => 1,
                "秒.毫秒" => 1,
                ...
        },
        ip地址2 => {
                "秒.毫秒" => 1,
                ...
        },
        ...
}

高手啊~~
看得头晕呀。