Офис НП AMWAY в Ярославле
Офис Амвей в Ярославле
На карте Офис AMWAY в ЯрославлеПрием и выдача заказов, презентация продукции Амвей, мастер–классы, вопросы по бизнесу Amway:
Адрес: улица Валентины Терешковой, дом 1 (Вход со двора)
Телефон: +7 (920) 112-00-91
Email: matyxho@mail.ru
Сайт: https://www.amway.ru/user/lebedem
Визитка: http://yar.meweb.ru
Иерархия статей
Статьи » Программирование » Автобан по IP
Сниппет
В данной статье расскажу и покажу, как реализовать защиту от DoS (не путать с DDoS!) атак, а также от брутфорса (подбора паролей методом грубой силы). Возможно даже, что данный php- скрипт сможет защитить от подбора каптчи.
Автобан по IP
Опубликовал  Pisatel Pisatel Добавлено  22-08-2013 20:39 22 Август 2013 20:39:34 4168  Прочтений 4168 Прочтений
 printer
Давно я ничего не публиковал, но были на то причины, поверь.

Совсем недавно по сети прокатилась волна взломов сайтов, причем делалось это весьма грубо: путем брутфорса (подбор паролей методом грубой силы). И посетила меня мысль сделать хотя бы пассивную защиту от подобного рода вредностей. Чуть погуглив, нашел я скрипт, который банит по IP через .htaccess, если было большое количество вызовов страницы/страниц за небольшой промежуток времени. Чуть ниже- сам скрипт, в который я внес небольшие изменения для увеличения быстродействия (оптимизация кода).

Что ж, приступим к реализации. Для начала создадим две таблицы, вот их структура

Код: SQL
# таблица all_visits



visit_id MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,

visit_ip VARCHAR(45) NOT NULL DEFAULT '',

visit_agent VARCHAR(100) NOT NULL DEFAULT '',

visit_datestamp INT(11) UNSIGNED NOT NULL DEFAULT '0',

PRIMARY KEY (visit_id)





#таблица black_list_ip



ban_id MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,

ban_ip VARCHAR(45) NOT NULL DEFAULT '',

ban_datestamp INT(11) UNSIGNED NOT NULL DEFAULT '0',

PRIMARY KEY (ban_id)




Далее нам нужно либо создать отдельный файл и инклудить его на все страницы сайта (что есть оптимально!), либо в каждую страницу добавлять следующее (что есть полный бред)

Код: PHP
// узнаем IP посетителя всеми доступными способами

if (isset($_SERVER['HTTP_CLIENT_IP']))

$ip = $_SERVER['HTTP_CLIENT_IP'];

elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']))

$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];

else $ip = $_SERVER['REMOTE_ADDR'];



// проверяем USER AGENT посетителя, если это поисковый бот- игнорируем его



if (isset($_SERVER['HTTP_USER_AGENT'])){

$agent[] = $_SERVER['HTTP_USER_AGENT'];

$bots = array('yandex', 'google', 'msnbot', 'bingbot', 'mail', 'yahoo', 'rambler', 'aport');

foreach($bots as $value){

if (stristr($agent[0], $value)){

$bot = 'bot';

break;

} else {

$bot = $_SERVER['HTTP_USER_AGENT'];

}

}

} else {

$bot = 'Unknown';

}



// пишем ip и user agent в базу (поисковые боты игнорируются)



if ($bot != 'bot'){

$bot = htmlspecialchars($bot);

$result = mysql_query("INSERT INTO all_visits (visit_ip, visit_agent, visit_datestamp) VALUES ('".$ip."', '".$bot."', '".time(true)."')");



// считаем количество записей/вызовов страниц с 1 ip



$result = mysql_query("SELECT COUNT(visit_id) FROM all_visits WHERE (visit_ip='".$ip."' and visit_datestamp > '".(time(true)-10)."') LIMIT 1");

$count_visit = mysql_fetch_array($result);



// если вызовов больше 10 в течении 10 секунд- записываем ip в блеклист



if ($count_visit[0]>10) {

$result = mysql_query("INSERT INTO black_list_ip (ban_ip, ban_datestamp) VALUES ('".$ip."', '".time(true)."')");



// добавляем забаненный ip в .htaccess



$file_htaccess="http://www.meweb.ru/.htaccess";

//обязательно указываем полный путь, иначе .htaccess может создаться в любой директории! Можно использовать суперглобальные переменные

$start_line = 0;

$lines = file($file_htaccess);

for ($n = 0; $n <= count($lines);

$n++)

if (!empty($lines[$n]) && $lines[n] == "<Limit GET POST>\r\n")

$start_line = $n;

if ($start_line != 0) for ($n = 0; $n < $start_line; $n++) $lines_htaccess[] = $lines[$n];

else $lines_htaccess = $lines;



$lines_htaccess[] = "<Limit GET POST>\r\n";

$lines_htaccess[] = "order allow,deny\r\n";

$result = mysql_query("SELECT ban_ip FROM black_list_ip ORDER BY INET_ATON(ban_ip)");

$number = mysql_num_rows($result);

for ($n = 1;

$n <= $number;

$n++) {

$htaccess_ip = mysql_fetch_array($result);

$lines_htaccess[] = "deny from ".$htaccess_ip['ban_ip']."\r\n";

}

$lines_htaccess[] = "allow from all\r\n";

$lines_htaccess[] = "</Limit>\r\n";

file_put_contents($file_htaccess, array_unique($lines_htaccess), LOCK_EX);

}

}




Ну вот почти все готово. Есть одно "но": таблица распухнет до безобразия за несколько дней, поэтому нам ее нужно будет чистить. Делать это можно по крону или вручную- кому как удобнее. У меня это- отдельный плагин, в котором я могу контролировать и размер базы данных, и сам файл .htaccess. Для очистки базы можно воспользоваться следующей кнопкой:

Код: PHP
   if ((isset($_GET['action']) && $_GET['action'] == "delete")) {

$result = mysql_query("DELETE FROM all_visits");

}



echo "<a href='yorpage.php&amp;action=delete' onclick=\"return confirm('Вы уверены, что хотите очистить таблицу всех визитов?');\">Очистить таблицу</a>";




Ну и вот тебе еще кусок кода, дабы быть всегда в курсе размера таблицы:

Код: PHP
  $tablesize = mysql_query("SHOW TABLE STATUS LIKE 'all_visits'");

$item = mysql_fetch_array($tablesize);

$sum = $item['Data_length'] + $item['Index_length'];



echo "Размер таблицы: <strong>".$sum."</strong>";




Функцию для перевода байтов в килобайты ищи где-то здесь, была она в статьях...

В коде, который я нашел в сети, были ошибки, которые я устранил (например, все ip, содержащиеся в таблице black_list_ip дублировались столько раз, сколько раз обновлялся файл .htaccess, так же была ошибка с пустотой переменных), однако автору за идею- спасибо! Если он пожелает здесь видеть ссылку на себя- пиши на мыло.

Пробуй, экспериментируй. Будут вопросы- спрашивай. Всех благ, здоровья и удачи!
Понравилась статья?
Метки для данной статьи
Поделиться:   
Последние активные темы форума
  Темы Просмотров Ответов Последние сообщения
folder Вопрос по переделке bb-кода
PHP, MySQL
18982 5 Pisatel
26. мая 2017
folder Вопросы по Ajax форме обратной связи
CMS PHP Fusion
52346 48 Ditrin
19. февраля 2017
folder BBCode YouTube Video Colorbox mod
CMS PHP Fusion
13280 2 Pisatel
10. декабря 2016
folder Как лучше создать собственную страницу?
CMS PHP Fusion
15513 17 Pisatel
11. мая 2016
folder Небольшие вопросы по скриптам магазина и катало...
PHP, MySQL
113682 80 Pisatel
11. января 2016
folder BBCode Code mod
CMS PHP Fusion
12018 0 Pisatel
31. августа 2015
folder Ajax Like Dislike Article Panel
CMS PHP Fusion
19084 16 Pisatel
07. июля 2015
folder Хлебные крошки / BreadCrumbs SEO Panel
CMS PHP Fusion
22003 17 Pisatel
04. июля 2015
folder Abbr Description BBCode
CMS PHP Fusion
6631 0 Pisatel
15. июня 2015
folder Плагин Email рассылки Mail To All by Pisatel
CMS PHP Fusion
31455 32 Pisatel
26. апреля 2015
folder Подозрительный трафик и прочие страшилки
Всякая хрень
10376 2 Ditrin
23. апреля 2015
folder Мод Newsletter - рассылка писем пользователям с...
CMS PHP Fusion
16081 13 Pisatel
10. апреля 2015
folder Мод отправки писем PHPMailer для PHP-Fusion
CMS PHP Fusion
102369 113 Ditrin
06. апреля 2015
folder Появление неизвестного файла subscriptions.php
CMS PHP Fusion
7842 2 Pisatel
06. апреля 2015
folder Autoban on IP
CMS PHP Fusion
21331 13 Pisatel
03. апреля 2015