|
|
ru.cgi.perl- RU.CGI.PERL ------------------------------------------------------------------ From : Michael Smirnov 2:5020/400 21 Mar 2001 22:55:06 To : All Subject : защита от Basic Auth атаки --------------------------------------------------------------------------------
Увидев, с какой скорость перебирает пароли по http
прога WWWHack (http://www.wwwhack.com/),
я решил сделать какую нибудь защиту от этого.
Точно подходящего решения не нашлось,
зато выяснилось что блокировать лучше не юзеров,
т.к. в этом случае легко реализовать DoS атаку,
в результате которой заблокируются все юзеры :-((.
Лучше блокировать "подозрительные" IP-адреса.
Hаиболее подошел для этого модуль SpeedLimit.pm
(http://www.modperl.com/book/source/wrapmod-code-1.02.tar.gz.),
который, проще говоря, ограничивает число http-запросов в единицу времени с
какого-либо ip-адреса.
Лучше бы найти модуль, который ограничивал бы число
именно неудачных аутентификаций с одного IP-адреса,
но за неимением лучшего........
Установил Perl5.005_03 на FreeBSD 2.2.6,
а SpeedLimit.pm требовал модуль IPC-Shareable-0.60, который требовал
Storable-1.0.11.
Пришлось установить и их.
Установил apache_1.3.19rusPL30.4:
./configure --activate-module=src/modules/perl/libperl.a \
--enable-shared=perl \
и mod_perl-1.25 как DSO:
perl Makefile.PL \
USE_APXS=1 \
WITH_APXS=/usr/local/apache/bin/apxs \
EVERYTHING=1 \
Hо SpeedLimit.pm не хочет работать: "500 Internal Server Error".
error_log:
[error] Undefined subroutine &Apache::SpeedLimit::handler called.
Может, это потому, что я просто скопировал этот модуль
в одну из директорий @INC?
Пожалуйста, посоветуйте что-нибудь в этой ситуации.
Можно ли обойтись без этого модуля,
или есть другой подходящий?
Фрагмент конфига Апача:
---------------------------------------
LoadModule perl_module libexec/libperl.so
PerlModule Apache::Registry
Alias /perl/ /usr/local/apache/perl/
<Location /perl>
SetHandler perl-script
PerlHandler Apache::Registry
Options ExecCGI
PerlSendHeader On
allow from all
PerlAccessHandler Apache::SpeedLimit
PerlSetVar SpeedLimit 61
PerlSetVar SpeedSamples 20
PerlSetVar SpeedForgive 10
</Location>
---------------------------------------
SpeedLimit.pm вроде выглядит нормально:
package Apache::SpeedLimit;
use strict;
use Apache::Constants qw(:common);
use Apache::Log ();
use IPC::Shareable ();
use vars qw(%DB);
sub handler {
my $r = shift;
return DECLINED unless $r->is_main; # don't handle sub-requests
my $speed_limit = $r->dir_config('SpeedLimit') || 10; # Accesses per
minute
my $samples = $r->dir_config('SpeedSamples') || 10; # Sampling
threshold (hits)
my $forgive = $r->dir_config('SpeedForgive') || 20; # Forgive after
this period (minutes)
my $content_type = $r->lookup_uri($r->uri)->content_type;
return OK if $content_type =~ m:^image/:i; # ignore images
tie %DB, 'IPC::Shareable', 'SPLM', {create => 1, mode => 0644}
unless defined %DB;
my($ip, $agent) = ($r->connection->remote_ip,
$r->header_in('User-Agent'));
my $id = "$ip:$agent";
my $now = time()/60; # minutes since the epoch
# lock the shared memory while we work with it
tied(%DB)->shlock;
my($first, $last, $hits, $locked) = split ' ', $DB{$id};
my $result = OK;
my $l = $r->server->log;
CASE:
{
unless ($first) { # we're seeing this client for the first time
$l->debug("First request from $ip. Initializing speed counter.");
$first = $last = $now;
$hits = $locked = 0;
last CASE;
}
if ($now - $last > $forgive) { # beyond the grace period. Treat like first
$l->debug("$ip beyond grace period. Reinitializing speed counter.");
$last = $first = $now;
$hits = $locked = 0;
last CASE;
}
# update the values now
$last = $now; $hits++;
if ($hits < $samples) {
$l->debug("$ip not enough samples to calculate speed.");
last CASE;
}
if ($locked) { # already locked out, so forbid access
$l->debug("$ip locked");
$result = FORBIDDEN;
last CASE;
}
my $interval = $now - $first;
$l->debug("$ip speed = ", $hits/$interval);
if ($hits/$interval > $speed_limit) {
$l->debug("$ip exceeded speed limit. Blocking.");
$locked = 1;
$result = FORBIDDEN;
last CASE;
}
}
$r->log_reason("Client exceeded speed limit.", $r->filename)
if $result == FORBIDDEN;
$DB{$id} = join " ", $first, $now, $hits, $locked;
tied(%DB)->shunlock;
return $result;
}
1;
__END__
--- ifmail v.2.15dev5
* Origin: Demos online service (2:5020/400)
Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.cgi.perl/272525d205de1.html, оценка из 5, голосов 10
|