1 1 1 1 1 1 1 1 1 1 Рейтинг: 3.00 - 1 отзыв

Ваш сайт превышает предельную нагрузку на хостинге? Тогда этот совет именно вам. Зачастую подобную нагрузку создают всевозможные боты и сервисы, сканирующие или скачивающие ваш сайт. Оптимальней всего попросту забанить их по IP, но как сделать это в автоматическом режиме?

Эта статья расскажет о том, как обеспечить автоматический бан по IP.

Как забанить IP превышающий частоту обращений к сайту

денежный трактор

Наша работа состоит из 2 частей.

 

1. Создаем дополнительные таблицы в MySQL (в своей базе sql).

Нужно создать две новые таблицы: all_visits и black_list_ip с одинаковым содержимым.

Как забанить IP превышающий частоту обращений к сайту

ВАЖНО. Галочку напротив AUTO_INCREMENT необходимо ставить сразу при создании таблицы. Потом, при изменении, вам этого сделать не удастся.

Теперь в таблице all_visits будут писаться все IP посетителей. А в black_list_ip IP тех, кто в течении 10 секунд более 10 раз обращался к вашему сайту (это не поведение обычного посетителя, согласитесь).

 

2. В файл index.php шаблона вашего сайта, в самый верх пишем код, заменяя ("localhost","логин","пароль","имя_бд"), своими данными.

 

<?php
$bot
='';
$ip=$_SERVER['REMOTE_ADDR'];

if (
strstr($_SERVER['HTTP_USER_AGENT'], 'Yandex')) $bot='Yandex';
elseif (
strstr($_SERVER['HTTP_USER_AGENT'], 'Google')) $bot='Google';
elseif (
strstr($_SERVER['HTTP_USER_AGENT'], 'Yahoo')) $bot='Yahoo';
elseif (
strstr($_SERVER['HTTP_USER_AGENT'], 'Mail')) $bot='Mail';

if (
$bot=='') {
$db=mysqli_connect("localhost","логин","пароль","имя_бд");

 
$res=mysqli_query($db,"INSERT INTO all_visits (ip,date) VALUES
     (INET_ATON('"
.$ip."'),'".time()."')");
 
$res=mysqli_query($db,"SELECT count(id) FROM all_visits WHERE
     (ip=INET_ATON('"
.$ip."') and date>'".(time()-10)."') LIMIT 1");
 
$count_visit=mysqli_fetch_array($res);

 if (
$count_visit[0]>10) {
 
$res=mysqli_query($db,"INSERT INTO black_list_ip (ip,date) VALUES
     (INET_ATON('"
.$ip."'),'".time()."')");

 
$start_line=0;
 
$lines='';
 
$ln_hta='';

 
$fh=fopen(".htaccess""a+");
 
flock($fhLOCK_EX);
 
fseek($fh0);
 while (!
feof($fh)) $lines.=fread($fh,2048);
 
$lines=explode("\n"$lines);

  for (
$n=0$n<=count($lines); $n++) {
   if (
strstr($lines[$n],"Order Allow,Deny")) $start_line=$n;
  }
  if (
$start_line!=0) for ($n=0$n<$start_line$n++) $ln_hta[]=$lines[$n];
  else 
$ln_hta=$lines;

  
$ln_hta[]="Order Allow,Deny";
  
$ln_hta[]="Allow from all";

  
$res=mysqli_query($db,"SELECT INET_NTOA(ip) AS ip,date FROM black_list_ip
      ORDER BY INET_ATON(ip)"
);
  while (
$bad_ip=mysqli_fetch_array($res)) {
   if (
time()<($bad_ip[date]+900))$ln_hta[]=" deny from ".$bad_ip[ip];
  }

  
$ln_hta=implode("\n",$ln_hta);
  
ftruncate($fh0);
  
fwrite($fh$ln_hta);
  
flock($fhLOCK_UN);
  
fclose($fh);
 }
}
?>

 

Теперь заблокированные IP буду дописываться в файле htaccess и соответственно блокироваться.

3. Чтобы не загромождать базу, ее нужно чистить время от времени от внесенных в нее IP. Для этого на хостинге создаем cron с файлом например ip-ban, со следующим содержимым. Так же заменяем ("localhost","логин","пароль","имя_бд") своими данными.

 

<?php
$db
=mysqli_connect("localhost","логин","пароль","имя_бд");

$res=mysqli_query($db,"DELETE FROM black_list_ip WHERE date<".(time()-900)."");
$res=mysqli_query($db,"DELETE FROM all_visits WHERE date<".(time()-900)."");

$start_line=0;
$lines='';
$ln_hta='';

$fh=fopen(".htaccess""a+");
flock($fhLOCK_EX);
fseek($fh0);
while (!
feof($fh)) $lines.=fread($fh,2048);
$lines=explode("\n"$lines);

for (
$n=0$n<=count($lines); $n++) {
 if (
strstr($lines[$n],"Order Allow,Deny")) $start_line=$n;
}
if (
$start_line!=0) for ($n=0$n<$start_line$n++) $ln_hta[]=$lines[$n];
else 
$ln_hta=$lines;

$ln_hta[]="Order Allow,Deny";
$ln_hta[]="Allow from all";

$res=mysqli_query($db,"SELECT INET_NTOA(ip) AS ip,date FROM black_list_ip
    ORDER BY INET_ATON(ip)"
);
while (
$bad_ip=mysqli_fetch_array($res)) {
 if (
time()<($bad_ip[date]+900))$ln_hta[]=" deny from ".$bad_ip[ip];
}

$ln_hta=implode("\n",$ln_hta);
ftruncate($fh0);
fwrite($fh$ln_hta);
flock($fhLOCK_UN);
fclose($fh);
?>

 

Cron у меня заработал с такой командой: /usr/bin/wget -O /dev/null -q "сайт/ban.php"

Теперь заблокированные IP будут разблокироваться через время, указанное в cron. Для больших сайтов лучше ставить 5 минут. А небольшие, где не так много посетителей, могут чиститься раз в 1 час или вообще раз в сутки.

 

Посмотреть хорошее видео

Добавить комментарий

Защитный код
Обновить