У меня есть вопрос, я построил этот маленький скрипт, чтобы проверить, не заражен ли какой-либо IP-адрес моим сайтом. Когда это произойдет, я запрещаю ip в файле .htaccess. Мой вопрос в том, может ли кто-нибудь сказать мне, является ли этот скрипт совершенно бесполезным или стоит попробовать … Сценарий вызывается в файле конфигурации, поэтому он запускается на каждой странице.
<?php #get the visitor ip $ip = $_SERVER["REMOTE_ADDR"]; #start the session @session_start(); #check if the ip is banned if( $_SESSION['~b'] ){ #check if we can open htaccess $fp = @fopen('./.htaccess','a'); if($fp){ #add the ip to htaccess @fwrite($fp,"\r\ndeny from $ip"); #close @fclose($fp); #destroy the session @session_destroy(); @mail("my-email","IP Banned","Ip: $ip"); } #let the user know why we deny him or her access die('To many requests.'); } #get the filename and location $f = './log/'.@ip2long($ip); #check if the file exists if ( @is_file($f) ) { #get the last filetime $a = @filemtime($f); #touch the file, give a new filetime @touch($f,time()); #the ip is not banned $_SESSION['~b'] = false; #add the time diff $_SESSION['~r'] += @time()-$a; #add the latest hit $_SESSION['~h'] += 1; }else{ #create the file if it doesn't exist @file_put_contents($f,''); #size: 0kb #if touch() doesn't work #chmod($ipfile,0755); } #calculate the diff after 10 hits, and ban when the avg is smaller than 0.25 seconds if( $_SESSION['~h'] > 10 && ($_SESSION['~r']/$_SESSION['~h']) < 0.25 ) $_SESSION['~b'] = true; ?>
Просто следуйте советам, чтобы избежать SESSIONS, поэтому я сделал это на основе файлов, не завися от файлов cookie и сеанса:
<?php # get the visitor ip $i = $_SERVER["REMOTE_ADDR"]; # get the filename and location $f = './log/'.ip2long($i).'.dat'; # check if the file exists and we can write if ( is_file($f) ) { # get the last filetime $a = filemtime($f); # get the file content $b = file_get_contents($f); # create array from hits & seconds $d = explode(':',$b); # calculate the new result $h = (int)$d[0] + 1; $s = (int)$d[1] + (time()-$a); # add the new data tot text file file_put_contents($f,"$h:$s",LOCK_EX); unset($d); }else{ # create the file if it doesn't exist hits:seconds file_put_contents($f,"1:1",LOCK_EX); #size: 3kb # to make sure we can write # chmod($f,0755); # set the hits to zero $h = 0; } # create a result var $r = $h > 10 ? (float)$s/$h : (float)1; # calculate the diff after 10 hits, and ban when the avg is smaller than 0.20 seconds (5 hits per second) if( $r < 0.20 ) { # check if we can open htaccess $fp = @fopen('./.htaccess','a'); if($fp){ # add the ip to htaccess @fwrite($fp,"\r\ndeny from $i"); # close @fclose($fp); # mail the admin @mail("email","IP Banned","Ip: $i with $r sbh (Seconds Between Hits)"); } # let the user know why we deny him or her access die('To many requests.'); # remove the file unlink($f); } # if the user leaves, reset if( $r > 30 ) { unlink($f); } echo 'Result: '.$r.'sbh (Seconds Between Hits)'; ?>
с<?php # get the visitor ip $i = $_SERVER["REMOTE_ADDR"]; # get the filename and location $f = './log/'.ip2long($i).'.dat'; # check if the file exists and we can write if ( is_file($f) ) { # get the last filetime $a = filemtime($f); # get the file content $b = file_get_contents($f); # create array from hits & seconds $d = explode(':',$b); # calculate the new result $h = (int)$d[0] + 1; $s = (int)$d[1] + (time()-$a); # add the new data tot text file file_put_contents($f,"$h:$s",LOCK_EX); unset($d); }else{ # create the file if it doesn't exist hits:seconds file_put_contents($f,"1:1",LOCK_EX); #size: 3kb # to make sure we can write # chmod($f,0755); # set the hits to zero $h = 0; } # create a result var $r = $h > 10 ? (float)$s/$h : (float)1; # calculate the diff after 10 hits, and ban when the avg is smaller than 0.20 seconds (5 hits per second) if( $r < 0.20 ) { # check if we can open htaccess $fp = @fopen('./.htaccess','a'); if($fp){ # add the ip to htaccess @fwrite($fp,"\r\ndeny from $i"); # close @fclose($fp); # mail the admin @mail("email","IP Banned","Ip: $i with $r sbh (Seconds Between Hits)"); } # let the user know why we deny him or her access die('To many requests.'); # remove the file unlink($f); } # if the user leaves, reset if( $r > 30 ) { unlink($f); } echo 'Result: '.$r.'sbh (Seconds Between Hits)'; ?>
Если вы хотите, чтобы случайный пользователь мог отправлять слишком много запросов за определенное время, тогда да , сценарий может работать. Поднимите экран catpcha, и вы в бизнесе.
НО
Реальный ответ – нет .
Основная ошибка с этим кодом зависит от сеанса для определения частоты активности пользователя. «Хороший» злоумышленник может нагрузить ваш сервер запросами с отключенными cookie, а также обмануть свой IP-адрес.
Один из способов остановить атаки – перейти на серверный уровень и установить iptables. Фактически, iptables поставляется с большинством дистрибутивов linux. Он нуждается в небольшой конфигурации и хорошо работает.
Другой способ, если у вас есть root-доступ к вашему серверу, заключается в перемещении сеанса в Memcached. Он имеет функцию, называемую управлением потоком, которая является довольно BOSS.
Еще один способ предотвращения DDOS – от сторонних сервисов, таких как blockdos http://www.blockdos.net/
Роскошно, но это может сработать для вас.
Но PHP сам по себе не может быть настроен для обработки DDOS-атак. Вам нужно поставить какой-то прибор или брандмауэр перед всеми запросами, которые нужно проверить, прежде чем переходить к вашим скриптам PHP.
Мои два цента. Это хорошая идея, однако вы можете прекратить доступ законных пользователей к вашему сайту. Это также будет проблемой для таких ботов, как бот Google. Поэтому я был бы осторожен. Возможно, также проверьте агент пользователя, и если он появится, как Google, то разрешите его независимо от других условий. Конечно, это открывает новое отверстие для злонамеренных пользователей. Обычно такие вещи выполняются на веб-сервере, а не с помощью PHP-кода. Другим подходом является система токенов. Тем не менее, я думаю, что с некоторой дополнительной доработкой вы могли бы столкнуться с чем-то с вашим подходом.
Также вы видели .htaccess или код защиты PHP от множества вопросов с быстрым запросом ? Это говорит о том, что то, что вы проектируете, было проверено ранее. Это говорит о том, что вы, вероятно, движетесь в правильном направлении.
Смягчение DDoS путем установки правил блокировки IP-адресов, основанных на запросах, всегда будет заканчиваться плохо, потому что:
Это справедливо и для IPTables. Вы можете узнать больше об этом здесь: http://www.incapsula.com/ddos/ddos-protection-service#iptables-ddos-protection
Решение весьма полезно. Между тем, в связи с вопросом, заданном @lopata, вы можете скорее комментировать функции unlink () в скрипте и настроить cron-задание, которое будет разблокировать IP-адреса из htaccess и удалять файлы через некоторое время.
<?php function unban_ip($ip){ $filename='.htaccess'; $line="deny from $ip"; file_put_contents($filename, str_replace("\r\n".$line, "", file_get_contents($filename))); $f = './log/'.@ip2long($ip); if(@is_file($f))unlink($f); return true; } $time=time(); $path='./log'; $handle=@opendir($path); $x=0; while(($file=@readdir($handle))!==false){ if($file=='.'||$file=='..')continue; $filepath="$path/$file"; if(is_file($filepath)){ $ftime=@filemtime($filepath); if($time-$ftime>600){ //unban after 10 minutes $ip=long2ip($file); unban_ip($ip); $x++; } } } echo "$x IPs Unbanned";
в<?php function unban_ip($ip){ $filename='.htaccess'; $line="deny from $ip"; file_put_contents($filename, str_replace("\r\n".$line, "", file_get_contents($filename))); $f = './log/'.@ip2long($ip); if(@is_file($f))unlink($f); return true; } $time=time(); $path='./log'; $handle=@opendir($path); $x=0; while(($file=@readdir($handle))!==false){ if($file=='.'||$file=='..')continue; $filepath="$path/$file"; if(is_file($filepath)){ $ftime=@filemtime($filepath); if($time-$ftime>600){ //unban after 10 minutes $ip=long2ip($file); unban_ip($ip); $x++; } } } echo "$x IPs Unbanned";