Здесь представлены некоторые мои разработки на PHP. Это в, основном, служебные скрипты, которые работают в составе других скриптов и не могут быть протестированы здесь непосредственно.
Connie писал(а):Я так понимаю в коде Вашего скрипта нужно ввести какой то флаг, а уже в функции редиректа проверять установлен ли он и только тогда писать во временный каталог
Как раз наоборот. При редиректе флаг (файл специального имени) устанавливается, а при работе скрипта он проверяется. И если он стоит, то скрипт пропускает этого пользователя.
Нет, я имею ввиду, что эта функция редиректа будет вызываться и из других файлов. Защиту я хочу поставить в файл viewtopic.php А такие файлы как: viewforum.php, index.php оставить без изменений, но дело в том, что эти два скрипта так же используют функцию редиректа и я опасаюсь, что во временном каталоге будут созданы файлы, которые удалять будет некому, т.е. не будет происходить в этом случае очистки.
Поэтому я и думаю, что в файле защиты (antiddos.php) нужно установить какой то флажок, а уже в функции редиректа проверять его, если установлен, то делаем запись во временный каталог, а если не установлен или не определен, то ничего не делаем и работаем как обычно.
Такой финт позволит, в случае необходимости, отключить защитный скрипт и не нужно будет изменять файл functions.php
Т.е. мне нужно в файле antiddos.php определить какую то переменную, которая будет видна в файле functions.php (в функции redirect)
Сам подход в принципе неверный, потому что все действия производятся в файле antiddos.php, и именно там надо решать, выполнять действия или нет. Соответственно, "действие" не должно происходить, когда идёт внутренний редирект.
А почему Вы не хотите поставить вызов скрипта во все файлы?
Есть ещё вариант, сделать в описании функции редиректа ещё один параметр со значением по умолчанию:
После этого, во все вызовы редиректа из viewtopic.php повставлять вторым параметром true. Тогда файл будет создаваться лишь в нужных случаях. Но здесь тоже может быть проблема: возможно есть какие-то общие модули, которые загружаются из разных файлов и из которых идёт редирект. И получится накладка. Мне кажется, что лучше бы было ставить этот модуль на все запускаемые файлы.
function send_redirect($url){ // always close the session session_write_close();
//Изменение скрипта от DDos атаки if (defined('AD_DIRNAME')){ $f_name = AD_DIRNAME . '/r' . $_SERVER['REMOTE_ADDR']; $f = fopen($f_name, 'w'); fclose($f); } //Конец изменеия скрипта // check if running on IIS < 6 with CGI-PHP if( isset($_SERVER['SERVER_SOFTWARE']) && isset($_SERVER['GATEWAY_INTERFACE']) && (strpos($_SERVER['GATEWAY_INTERFACE'],'CGI') !== false) && (preg_match('|^Microsoft-IIS/(\d)\.\d$|', trim($_SERVER['SERVER_SOFTWARE']), $matches)) && $matches[1] < 6 ){ header('Refresh: 0;url='.$url); }else{ header('Location: '.$url); } exit; }
Т.е. если я уберу включение Вашего скрипта или же вызов этой функции произойдёт из какого то файла, не имеющего включение скрипта защиты, то мне не потребуется лезть изменять эту функцию
А вот на форуме никак не получается его прикрутить, проблема в том, что у меня все работает на разных системах, компьютерах, IP, а у некоторых юзеров упрямо появляется 503
Connie писал(а):Т.е. если я уберу включение Вашего скрипта или же вызов этой функции произойдёт из какого то файла, не имеющего включение скрипта защиты, то мне не потребуется лезть изменять эту функцию
Всё правильно. Хитро!
Connie писал(а):проблема в том, что у меня все работает на разных системах, компьютерах, IP
Это как? В пределах одного сайта?
Connie писал(а):а у некоторых юзеров упрямо появляется 503
А Вы сами можете инициировать эту ошибку, чтобы проверить, где и в каких случаях она вылазит?
/*** Выводить или не выводить сообщение об ошибке ***/ if ($ad_before_trying > 1) { /* Если обращение было недавно, то выводим сообщение об ошибке */ header ('HTTP/1.0 503 Service Unavailable'); ...
Я обратил внимание, что файлы создаваемые во временном каталоге имеют всегда на конце 1, т.е. одно обращение, теперь если более 2 обращений, то выводится ошибка, вроде, судя по отзывам тех, у кого не работало, сейчас работает, но будут тестировать еще.
Попробовал с своего компа качнуть сайт - получил 503-ю, так что думаю нормально, время покажет верно ли я все сделал.
if (!$ad_IsRobot && не редирект) { /*** Чтение каталога и удаление старых файлов ***/ $ad_dir = opendir(AD_DIRNAME) or die('Отсутствует директория для временных файлов'); $ad_now = time(); $ad_forbid = $ad_now - AD_DELAY; /* IP-адрес в имени файла, начинающегося на букву a, а время обращения - время изменения файла */ $ad_before_trying = 0;
while (false !== ($ad_FName = readdir($ad_dir))) { $ad_fileage = $ad_now - @ filemtime(AD_DIRNAME . '/' . $ad_FName); if ($ad_fileage > AD_FILE_STORE_TIME ) @ unlink(AD_DIRNAME . '/' . $ad_FName);//удаляем старые файлы elseif (ereg('^a[1-9]', $ad_FName)) { //Если мы пришли с того же ip, что и был записан //тогда считаем кол-во обращений
if ( ereg('^a' . str_replace('.', '\\.', $_SERVER['REMOTE_ADDR']) . '_([0-9]+)$', $ad_FName, $ad_match ) ){ //ip тот же! Если время файла менее необходимого, то считаем кол-во обращений if ($ad_fileage < AD_DELAY){ $ad_before_trying = intval($ad_match[1]); } @ unlink(AD_DIRNAME . '/' . $ad_FName);//файл при совпадении имени и ip удаляется в любом случае } } }
возросло кол-во файлов соответствующих ip реальным посетителям во временном каталоге, ранее новый пользователь очищал временный каталог, а потому и не было возможности поймать качальщика, т.е. во временном каталоге у меня было 1-2 файла. Вместе с тем теперь возможно увеличение "забытых" файлов, поэтому я сделал удаление их по прошествии AD_FILE_STORE_TIME, сейчас это 12 часов, но я думаю поставить около 1 часа, хватит?
Сейчас нас как раз долбит кто то, скачивает форум, вот и проверю, как теперь скрипт работает.
Покритикуйте я ведь в php не мастак, может напортачил чего?
А Вы сами можете инициировать эту ошибку, чтобы проверить, где и в каких случаях она вылазит?
если бы! У меня все четко работает.
Посмотрите по логам. Будет видно, куда человек ходил. Хотя, если у Вас не стоят SEO-моды на форуме, то логи дадут лишь файлы скриптов без параметров.
Connie писал(а):Я обратил внимание, что файлы создаваемые во временном каталоге имеют всегда на конце 1, т.е. одно обращение, теперь если более 2 обращений, то выводится ошибка, вроде, судя по отзывам тех, у кого не работало, сейчас работает, но будут тестировать еще.
В общем, конечно, вариант... Пропускать первый раз... Лучше бы, конечно, разобраться, в каких случаях это вылазит, чтобы устранить суть проблемы.
Добавлено спустя 4 минуты 54 секунды:
Connie писал(а):ранее новый пользователь очищал временный каталог, а потому и не было возможности поймать качальщика
Совершенно нет необходимости ловить качальщика. После указанного числа попыток качальщик банится окончательно в .htacces, а Вам приходит письмо на электронную почту о том, что забанен такой-то товарищ (для проверки, не бот ли это полезный. У меня в день по паре таких красавцев вылазит. Правда я вычищаю htaccess через пару месяцев. Ибо за это время, пока сайт для них недоступен, они забывают о том, что он им был нужен. А если качальщик сильно хитрый, что не доводит до бана, то можно, опять-таки, в логах его посмотреть.
Добавил задержку в выдаче страницы роботам. К сожалению, не все роботы корректно читают сайт и обращают внимание на соответствующие директивы файла robots.txt. Поэтому пришлось просить их подождать несколько секунд перед тем, как они получат страницу.
И ещё, список подсетей поисковых роботов постоянно обновляется. Следите за номером версии скрипта!
Здравствуйте! Успешно использую Ваш скрипт и несколько его модифицировал (сразу уточно что имена почти всех переменных я изменил, так что не стоит этот кусок кода вставлять в оригинальный скрипт):
//Получаем хост (в некоторых логах он может быть вместо ip $host = gethostbyaddr($_SERVER['REMOTE_ADDR']);
/* Лучше использовать оператор сравнения. Он выполняется быстрей, нежели конкретное сравнение значений. $i = 0; Плохо: if ($i != 0) Хорошо: if ($i > 0)
Вместо сравнения строки со строкой, для выявления ее пустоты, также можно использовать сравнение с нулем, которые выполнится быстрее.
Используйте одинарные кавычки там где это возможно и пользуйтесь оператором "." для склейки строк, вместо прямой подстановки переменный в строку, заключенную в кавычки. Лучший вариант(самый быстрый): echo 'Вес равен: '.$weight;
// Сообщение не будет отсылатся, если переменные типа . $_SERVER['REMOTE_ADDR'] . ставить после переменных типа . $realIp . // В начале и конце сообщения обязательно ставить ''.
//Выполняем запрос к логам. Нужно указать путь и имя лог-файла /* exec('cat /home/your_dir/logs/access_log | egrep \'(' . str_replace('.', '\\.', $_SERVER['REMOTE_ADDR']) . ')|(' . str_replace('.', '\\.', $host) . ')\' | sort -k 4 >' . DIRTMP . '/dump.txt'); $mess .= file_get_contents(DIRTMP . '/dump.txt'); @ unlink(DIRTMP . '/dump.txt'); */
//Выполняем запрос к логам. Нужно указать путь и имя лог-файла /* exec('cat /home/your_dir/logs/access_log | egrep \'(' . str_replace('.', '\\.', $_SERVER['REMOTE_ADDR']) . ')|(' . str_replace('.', '\\.', $host) . ')\' | sort -k 4 >' . DIRTMP . '/dump.txt'); $mess .= file_get_contents(DIRTMP . '/dump.txt'); @ unlink(DIRTMP . '/dump.txt'); */
Я так понимаю нам в сообщении приходит информация из лога апача. Но что там особенно полезного? Мне кажется, что на эту обработку уходит приличное количество процессорного времени. Логи могут достигать десятки мегабайт. Или я не прав?
4. Не знаю как у кого, но у меня на сервере скрипт работает, если на папку tmp_path выставлены права 777, а на файл .htaccess - 666.