|
|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : Eugene Grosbein 2:5006/1 11 Nov 2002 23:14:29 To : Artem Chuprina Subject : Re: проблема с защитой -------------------------------------------------------------------------------- EG>> Так затыкается сервер весьма избирательно, только при ответе 401 и только EG>> по отношению к данному клиенту. AC> Щазз. Процессы будут заняты все те же самые. В общем да. Hо это не смертельно, при наличии лимитов это не DoS. И backoff не бесконечный, при минутных таймаутах уже можно отправлять в блеклист на уровне пакетного фильтра. EG>>>> Да, на верный ввод тоже надо backoff. EG>>>> И еще не указал, что обычно на первые три попытки задержек не ставим, EG>>>> счетчик включаем после третьей. AC>>> Тоже хорошо. Он зашел через десяток проксей - тридцать попыток без AC>>> задержек. EG>> Пусть. Тридцать попыток это фигня. AC> Это без задержек. Пусть. От такого количества проб ничего не поможет, но это не имеет значения. EG>>>> Все неудачные запросы от одного клиента выстраиваются в одну очередь EG>>>> посредством блокировок, так что параллелизация ничего не даст. AC>>> А, поверил. Hо несколькими проксями оно лечится вместе с бэкоффом. EG>> Тут вся фишка в экспоненциальности. Hе сможет ничего линейный рост EG>> списка проксей против экспоненциального роста таймаута. AC> Во-первых, если бы он тебе самому не блокировал сервис. Блеклист и прогулка по лесу. AC> А во-вторых, напоминаю, ему нужно довольно большое, но все же константное AC> количество запросов. Которое линейным ростом списка проксей вполне себе AC> покрывается. Вот против линейного удлинения пароля линейный рост списка AC> проксей действительно ничего не сделает... Мнээ, стойкость пароля как бы подразумевается сама собой. От подбора пароля 'sex' ничего не спасет. Речь идет исключительно о том, что HTTP (без S) позволяет чрезвычайно быстро перебирать пароли и не мешает при известном упорстве одобрать даже хороший пароль. А backoff делает это занятие бесперспективным изначально. Хотя у меня все проще сделано. Если перебор идет с высокой скоростью, просекаем моментально и тут же в блеклист и аларм в лог. Если еще учесть, что доступ только из одной сети /19, любители проксей отдыхают заранее. #!/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 $timeout=15*60; # block attacker for $timeout seconds 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 %blocked=(); 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 number $time (unixtime) if(defined($hit{$time})) { $hit{$time}{$host}++; } else { $hit{$time}{$host}=1; } # $sum{$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(!defined($blocked{$host}) && ($sum{$host}>=$threshold)); } # for testing purposes: hit ctrl-t to see current stats sub print_hit { my $rest=alarm(0); # trying 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}"; print ", blocked until ",time2str('%x %T',$blocked{$host}) if defined($blocked{$host}); print "\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 $now=time(); my $limit=$now-$interval; foreach $s (keys(%hit)) { if($s<$limit) { # entries older than $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 } } foreach $h (keys(%blocked)) { unblock($h) unless $blocked{$h}>$now; } alarm $interval; # restart timer } # site dependent action; this example is harmless sub block { $blocked{$host}=time()+$timeout; syslog($syslog_priority, "%d unauthorized requests from %s, last: %s", $sum{$host},$host,$request); } sub unblock { my $host=shift; delete $blocked{$host}; syslog($syslog_priority,"host %s unblocked",$host); } Eugene --- slrn/0.9.7.4 (FreeBSD) * Origin: Svyaz Service JSC (2:5006/1@fidonet) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/8869436d261d.html, оценка из 5, голосов 10
|