Ключевые слова:apache, limit, security, log, (найти похожие документы)
From: Eugene Grosbein <Eugene.Grosbein@f1.n5006.z2.fidonet.org.>
Newsgroups: fido7.ru.unix
Date: Mon, 21 May 2001 16:59:23 +0400
Subject: Защита от подбора паролей в mod_auth
У login'а есть фича по увеличению таймаута при вводе нескольких
неправильных паролей - особенно не поподбираешь. По понятным причинам
у апачевских mod_auth* такого нет. А все-таки нужно и набросал я
скриптик для "realtime" контроля логов на атаки типа wwwhack'а.
Может, кому сгодится. Критика приветствуется.
#!/usr/bin/perl -w
# httprot.pl, "request for comments" version
# run as: tail -f /usr/local/apache/logs/access_log | ./ httprot.pl
# Configuration starts here
# for "combined" apache log format, unauthorized request
my $AUTH_REQ='^([^ ]+) ([^ ]+) ([^ ]+) \[([^\]]+)\] "([^"]+)" 401';
# host ident user date request authrequired
my $threshold=5; # allow $threshold unauthorized requests
my $interval=5; # within $interval seconds without alerting
my $syslog_facility='auth'; # when alerting, use these
my $syslog_priority='alert'; # facility and priority
# Configuration finishes here
use strict;
use Date::Parse;
use Date::Format;
use Sys::Syslog;
my %hit=();
my %sum=();
my ($host,$date,$time,$request);
openlog("httprot","pid",$syslog_facility);
$SIG{INFO}=\&print_hit;
$SIG{ALRM}=\&cleanup;
alarm $interval;
# main loop
while(<>) {
chomp;
next unless /$AUTH_REQ/;
$host=$1;
$date=$4;
$time=str2time($date);
$request=$5;
# $hit{$time}{$host} is number of bad requests from $host
# within second numbered $time ("unixtime")
if(defined($hit{$time})) { $hit{$time}{$host}++; }
else { $hit{$time}{$host}=1; }
# $sum{$time}{$host} is number of bad requests from $host
# within last $interval sec (roughly)
if(defined($sum{$host})) { $sum{$host}++; }
else { $sum{$host}=1; }
&block if($sum{$host}>=$threshold);
}
# for testing purposes: hit Ctrl-t to see current stats
sub print_hit {
my $rest=alarm(0); # avoid race condition with SIGALRM
# and try to reduce time leak...
print "Current state:\n";
my ($time,$host);
my %list;
foreach $time (keys(%hit)) {
print time2str('%x %T',$time),":\n";
%list=%{$hit{$time}};
foreach $host (keys(%list)) {
printf "\t$host: $hit{$time}->{$host}\n";
}
}
print "Summary:\n";
foreach $host (keys(%sum)) {
print "$host: $sum{$host}\n";
}
alarm($rest); # ...but will leak up to 1 second per SIGINFO
}
# free memory - throw away expired stats every $interval seconds
sub cleanup {
my ($h,$s);
my %hosts;
my $limit=time()-$interval;
foreach $s (keys(%hit)) {
if($s<$limit) { # entries older whan $limit have expired
%hosts=%{$hit{$s}};
foreach $h (keys(%hosts)) { # correct sum when expiring stats
$sum{$h}-=$hit{$s}->{$h};
delete $sum{$h} unless $sum{$h}>0; # free memory
}
delete $hit{$s}; # again, free memory
}
}
alarm $interval; # restart timer
}
# site dependent action; this example is harmless
sub block {
syslog($syslog_priority,
"$sum{$host} unauthorized requests from $host, last: $request");
}
Атаку с одного IP ловит моментально, если через кучу быстрых прокси,
то не поймает. Как улучшить?