proftpd log 文件实时分析,动态封禁/解封 |
| 作者:Jinmg 来源:linuxsir (2005-03-24 10:49:06) |
|
请问下面这段程序怎实现?能告诉我实现的步骤吗?谢谢。 # proftpd log 文件实时分析,动态封禁/解封 # 用法: # tail -f /var/log/proftpd | /usr/bin/proftpdeny.pl # # 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`;#把当前日期赋值给$date chomp $date;#截去\n,这里也可以这样,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`; #把当前日期赋值给$date chomp $date; #截去\n 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 ) ; } }
(http://www.fanqiang.com)
原文链接:http://www.linuxsir.org/bbs/showthread.php?t=81013
|
|