Как прибить дятла?

Главные вкладки

Аватар пользователя Onza Onza 23 ноября 2009 в 18:11

Добрый вечер, возникла проблема. Некий дятел из сети Ukrtelecom постоянно долбит поисковую форму на сайте сгенерированными поисковыми запросами, т.е. по сути идет атака через друпаловскую поисковую форму - один запрос в секунду, в две, в три секунды и т.д. Видно, что работает машинка, перебирая укртелекомовские ip-адреса по какому-то там своему алгоритму. Может например исчезнуть на несколько дней, потом снова появляется. Цель этих действий мне, честно говоря, совершенно непонятна, поскольку вызвать этим какие-либо ощутимые проблемы у сайта вряд ли возможно. Думаю, единственный расчет здесь может быть, что если сайт на шареде, то можно вызвать превышение нагрузки и хостер в конце концов отключит сайт. В моем случае сайт на впс и хостер не отключит, ip мы блочим, но не всегда уследишь и это не панацея. Все равно есть нежелательная нагрузка на сервер и так или иначе, хотелось бы отсечь прилипчивого урода. К сожалению, рецептов по друпалу не нашел. Например, в форумных движках для предотвращения подобных атак через поисковую форму есть встроенные функции ограничения частоты поисковых запросов. В друпале, насколько я знаю, такого типа модули вообще отсутствуют, но буду рад если ошибаюсь. Поскольку у дятла нет реферера, возникла мысль как-то отсечь его по этому признаку через htaccess, скажем задать в нем правило блокировать доступ к директории search для всех запросов GET без реферера. Это возможно или я несу ерунду?

Комментарии

Аватар пользователя Onza Onza 23 ноября 2009 в 18:59

T-34 wrote:
Captcha + hidden_captcha

Капчу для поиска не могу ставить по идеологическим соображениям, наша аудитория активно (очень активно) пользуется поисковой формой и не хотелось бы осложнять ей жизнь.

Аватар пользователя Onza Onza 23 ноября 2009 в 20:50

T-34 wrote:
Со скрытой капчей никаких осложнений не возникает.

Спасибо, счас почитаю, просто никогда не использовал скрытую капчу Smile

Аватар пользователя Onza Onza 23 ноября 2009 в 20:11

RxB wrote:
По какой ссылке у вас поиск расположен и сколько запросов хотите разрешить в единицу времени?

RxB, поиск стандартный друпаловский, расположен тоже стандартно, в директории /search, далее там /search/node, /search/user и /search/taxonomy_search
Подумал сейчас что вариант с ограничением кол-ва запросов в единицу времени вряд ли отсечет, хотя нагрузку конечно снизит. Когда смотрел логи, было видно, что после того как блокируется какой-либо ip, с которого идут запросы, робот продолжает долбить и дальше, хотя получает 403. Таким образом, если включить ограничение частоты запросов, он будет так же отправлять запрос в поисковую форму (только будет это делать раз в разрешенную единицу времени).

Аватар пользователя Azerot Azerot 23 ноября 2009 в 19:13

1. Смените параметры формы, робот по идее должен на этом попухнуть на какое-то время. Ну то есть чтобы вызывался скажем не тот поисковый скрипт который сейчас а скрипт с другим именем, делающий тоже самое.
2. Повестьте JavaScript на кнопку "Искать" и/или на нажатие Enter, который генерит какой-либо добавочный параметр к поиску, без которого он работать не будет.

Аватар пользователя Onza Onza 23 ноября 2009 в 20:17

Azerot wrote:
1. Смените параметры формы, робот по идее должен на этом попухнуть на какое-то время. Ну то есть чтобы вызывался скажем не тот поисковый скрипт который сейчас а скрипт с другим именем, делающий тоже самое.
2. Повестьте JavaScript на кнопку "Искать" и/или на нажатие Enter, который генерит какой-либо добавочный параметр к поиску, без которого он работать не будет.

Azerot, спасибо за идею, если я правильно понял - сменить параметры поисковой формы лучше в template.php правда не знаю насколько это у меня получится, кроме того на сайте еще работают модули, использующие стандартный поиск.

Аватар пользователя gorr gorr 23 ноября 2009 в 19:52

А если банально в index.php перед бутстрапом вставить наподобие такого, то отсечете всех без реферера, даже друпал не подгружая
if(!$_SERVER['HTTP_REFERER'] && key(explode('/', $_GET[q]) == 'search'))) exit;

Аватар пользователя Onza Onza 24 ноября 2009 в 1:27

gorr wrote:
А если банально в index.php перед бутстрапом вставить наподобие такого, то отсечете всех без реферера, даже друпал не подгружая
if(!$_SERVER['HTTP_REFERER'] && key(explode('/', $_GET[q]) == 'search'))) exit;

gorr, спасибо, любопытный способ (там правда лишняя скобка у Вас), наверное он бы мне подошел, но что-то не так, вылазят ошибки:

Warning: key() [function.key]: Passed variable is not an array or object in /public_html/index.php on line 12
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /public_html/index.php:12) in /public_html/includes/bootstrap.inc on line 939
Warning: Cannot modify header information - headers already sent by (output started at /public_html/index.php:12) in /public_html/includes/bootstrap.inc on line 569
Warning: Cannot modify header information - headers already sent by (output started at /public_html/index.php:12) in /public_html/includes/bootstrap.inc on line 570
Warning: Cannot modify header information - headers already sent by (output started at /public_html/index.php:12) in /public_html/includes/bootstrap.inc on line 571
Warning: Cannot modify header information - headers already sent by (output started at /public_html/index.php:12) in /public_html/includes/bootstrap.inc on line 572

да, размещал код на 12 строке в index.php

Аватар пользователя Onza Onza 23 ноября 2009 в 20:09

Ильич Рамирес Санчес wrote:
"Onza" wrote:
Некий дятел из сети Ukrtelecom

ну как... западные коллеги укртеловские сетки уже тупо банят.
я кстати тоже потихоньку начинаю банить. запарили хрумероводы.

Да, я почитал, на Ukrtelecom много кто жалуется. Но это конечно не выход, из-за одного урода банить украинскую аудиторию.

Аватар пользователя Ильич Рамирес Санчес Ильич Рамирес Санчес 23 ноября 2009 в 20:20

да вот и ... сетки то разные киевские, запорожские, меня вон с хмельницка какой то запросми седня долбил... с кривого рога лезли

причем укртелеком потому этим и славен что урод там явно не один. в россии тоже есть. но мало. в основном дятлы на дешевых VDS.

Аватар пользователя theСанитар theСанитар 23 ноября 2009 в 20:37

Старый добрый (местами) Trottle.

Throttle: Поддерживает механизм авто-регулятора для контроля нагрузки на сайт.

И говорим "большая нагрузка -- отключить поиск".

Минус: страдают нормальные юзера, конечно.

Аватар пользователя Onza Onza 24 ноября 2009 в 1:26

cristobal-junta wrote:
Мне интересно, а пробовали банить по IP-адресу вот здесь: /admin/user/rules/add ?
Или этот способ не подходит.

Мы блочим ip не через движок, а через фаервол, но вообще если вас решили взять на измор этот способ подходит лишь как временная мера. Представляете, сколько ip-адресов в модемном пуле укртелекома? К тому же, не всегда можно сразу отследить, что тебя начали долбить.

Аватар пользователя IrinaStasuk IrinaStasuk 24 ноября 2009 в 0:45

Я переодически баню, но появляются новые дятлы. Кстати, часто перебирают номера юзеров. Вылавливаю - запрещаю. Но не будешь же постоянно следить за тем, что происходит на сайте.

Аватар пользователя kyky kyky 24 ноября 2009 в 7:13

Таких лучше банить по хидерам:
реффер -- как посоветовал Гор
юзер-агент -- если пустой|не(ие|фокс|опера|хром|сафари) тогда гуд-бай

Аватар пользователя gorr gorr 24 ноября 2009 в 11:32

Да, ошибся малость, не там скобку надо поставить, вот правильно:
if(!$_SERVER['HTTP_REFERER'] && key(explode('/', $_GET[q])) == 'search') exit;
Посмотрел, у меня в 12 строке в index.php комментарии идут, вот прямо после них и надо вставить. С заголовками - странно, если в самом начале exit делаем, то еще ничего в браузер не должно было отослаться.

Аватар пользователя Onza Onza 25 ноября 2009 в 2:29

gorr wrote:
Да, ошибся малость, не там скобку надо поставить, вот правильно:
if(!$_SERVER['HTTP_REFERER'] && key(explode('/', $_GET[q])) == 'search') exit;
Посмотрел, у меня в 12 строке в index.php комментарии идут, вот прямо после них и надо вставить. С заголовками - странно, если в самом начале exit делаем, то еще ничего в браузер не должно было отослаться.

gorr, к сожалению этот вариант не работает. Результат - пустая белая страница. Через html-код видно, что получил браузер:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=utf-8"></HEAD>
<BODY></BODY></HTML>

В журнале/логах никаких записей об ошибках нет.

Аватар пользователя Химический Али Химический Али 24 ноября 2009 в 11:23

Некоторые поисковики прощупывают поисковые механизмы сайта чтобы самим не напрягаться. Достоверно, не раз наблюдал на нескольких своих ресурсах (правда, не друпал). Тоже думал спамботы какие-нибудь, посмотрел в логи - поисковые боты! и айпишники соответствуют.

Аватар пользователя gorr gorr 25 ноября 2009 в 11:17

А если так?
<?php
if(!$_SERVER['HTTP_REFERER'] && key(explode('/', $_GET[q])) == 'search') {
if (!headers_sent($filename, $linenum)) {
header(HTTP/1.1 404 Not found');
exit;
} else {
echo "Headers already sent in $filename on line $linenum\n";
exit;
}
}
?>

Аватар пользователя Onza Onza 25 ноября 2009 в 11:58

gorr wrote:
А если так?
<?php
if(!$_SERVER['HTTP_REFERER'] && key(explode('/', $_GET[q])) == 'search') {
if (!headers_sent($filename, $linenum)) {
header(HTTP/1.1 404 Not found');
exit;
} else {
echo "Headers already sent in $filename on line $linenum\n";
exit;
}
}
?>

Выдается синтаксическая ошибка:

Parse error: syntax error, unexpected T_LNUMBER in /public_html/index.php on line 13

На 13-й строке у меня было: header(HTTP/1.1 404 Not found');

Аватар пользователя gorr gorr 25 ноября 2009 в 12:22

<?php
if(!$_SERVER['HTTP_REFERER'] && key(explode('/', $_GET[q])) == 'search') {
if (!headers_sent($filename, $linenum)) {
header('HTTP/1.1 404 Not found');
exit;
} else {
echo "Headers already sent in $filename on line $linenum\n";
exit;
}
}
?>
Кавычки забыл.

Аватар пользователя Onza Onza 27 ноября 2009 в 3:03

gorr wrote:
<?php
if(!$_SERVER['HTTP_REFERER'] && key(explode('/', $_GET[q])) == 'search') {
if (!headers_sent($filename, $linenum)) {
header('HTTP/1.1 404 Not found');
exit;
} else {
echo "Headers already sent in $filename on line $linenum\n";
exit;
}
}
?>
Кавычки забыл.

gorr, чего-то не так, теперь выдается 404 (страница не найдена).

Аватар пользователя Onza Onza 26 ноября 2009 в 14:57

gorr wrote:
Ну так было задумано, чтобы 404 выдавалось для тех, у кого нет реферера.

Пока только проверял с двух разных компов у себя, мне по всему сайту выдается 404. Вечером, когда народу меньше будет, еще попробую потестировать.

Аватар пользователя gorr gorr 26 ноября 2009 в 17:41

Переделал, потестил, вот так идет:
<?php
if(isset($_GET[q]) && !isset($_SERVER['HTTP_REFERER']) && strpos($_GET[q], 'search') === 0) {
header('HTTP/1.1 404 Not found');
exit();
}
?>

Аватар пользователя Onza Onza 27 ноября 2009 в 3:10

gorr, огромное спасибо! Потестировал, в общем - то что нужно. Минус данного решения вижу только один: если пользователь вставляет url страницы поиска в адресную строку, то обламывается. Но вряд ли кто-то так будет делать, как правило в поиск всегда приходят уже с какой-либо страницы сайта.

ЗЫ: чего-то не могу сообразить, как добавить в заголовок темы [Решено]?