Intereting Posts
Насколько хороша производительность PHP? Отправить значение кнопки отправки при отправке формы Удалите все специальные символы из строки Не найдено ни одного результата для запроса, хотя ожидалась хотя бы одна строка преобразовать массив в отдельные строки OAuth2.0 Серверный стек, как использовать состояние для предотвращения CSRF? для draft2.0 v20 Отключить родной класс Soap в PHP5 и использовать nuSoap? Постоянное соединение или объединение пулов в PHP54 + Nginx + PHPFPM + MongoDB Можно ли передавать параметры по ссылке с помощью call_user_func_array ()? Автоматическое распознавание лиц с использованием API Picasa для извлечения отдельных изображений Ошибка кодирования в PHP-файле XML Сравнить объект с свойствами datetime без микросекунд Как я могу использовать «Injection Dependency» в простых функциях php, и должен ли я беспокоиться? Кажется, что значения POST теряются при использовании .htaccess RewriteRule. Значения GET в порядке. Как исправить? Подготовленное заявление для сессий

PHP, .htaccess, защита от DDoS и быстрого запроса

У меня есть вопрос, я построил этот маленький скрипт, чтобы проверить, не заражен ли какой-либо 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-адресов, основанных на запросах, всегда будет заканчиваться плохо, потому что:

  1. такие правила будут влиять на законных пользователей (ложные срабатывания)
  2. для 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";