Главная страница


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)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 защита от Basic Auth атаки   Michael Smirnov   21 Mar 2001 22:55:06 
Архивное /ru.cgi.perl/272525d205de1.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional