Web - кодинг: PHP:
Как защитить сайт от тотального скачивания
Источник:
Бывают такие случаи, когда владелец сайта не желает, или не может, отдавать
свой сайт целиком своим посетителями. Приведем простой пример:
У вас есть сайт, на котором, вы публикуете обои для рабочего стола. Общий
объем сайта - 500Mb, посещаемость 7 000 хостов в сутки, примерный трафик - 300Гб
в месяц или 10 Гб в день.
Добавим к этим посетителям еще 20 человек, скачавших ваш сайт целиком.
Получаем увеличение трафика на 10Гб или в два раза. Или другими словами 0.28%
посетителей создали 50% трафика. Не совсем честно, особенно если вы оплачиваете
трафик. Способы защиты сайта от скачивания. 1. Запрет по User Agent
User Agent - так называются данные, которые каждый броузер передает серверу.
Эти данные могут содержать в себе такую информацию, как тип броузера,
операционная система, список плагинов и многое другое.
Это наиболее простой, но наименее эффективный способ. Его преимущество в том,
что ни кого лишнего вы не запретите, а недостаток в том, что практический каждый
Download агент может маскироваться под стандартные браузеры.
Пример: $agent=" ".$HTTP_USER_AGENT; if (strpos($agent,"DISCo
Pump") || strpos($agent,"Offline Explorer") || strpos($agent,"Teleport")
|| strpos($agent,"WebZIP") || strpos($agent,"WebCopier")
|| strpos($agent,"Wget") || strpos($agent,"FlashGet")
|| strpos($agent,"CIS TE") || strpos($agent,"DTS Agent")
|| strpos($agent,"WebReaper") || strpos($agent,"HTTrack")
|| strpos($agent,"Web Downloader")) { die("Access Denied"); }
2. Ограничение по количеству просмотренных страниц за определенный
промежуток времени.
Тоже достаточно спорный метод. Но надо понимать, что нормальный человек не
может просмотреть 60 страниц за 1 минуту. Но с другой стороны и Download агент
может делать паузы между скачиванием страниц.
Даже если вы не заблокируете Download агент совсем, то по крайней мере,
сильно затрудните скачивание. 3. Запрет с помощью скрытой ссылки.
Наверное, один из самых правильных методов. Вы должны сделать скрытую ссылку
на странице, по которой "живой" человек не перейдет, а Download агент и прочие
роботы сделают это. IP адрес с которого производится просмотр скрытой страницы
блокируется, скажем, на 3 минуты.
Главный недостаток - это то, что вы, таким образом, блокируете поисковых
роботов. Бороться с этим можно двумя способами:
- Проверять $HTTP_USER_AGENT. Для этого вам необходимо будет знать то, каким
образом подписываются все поисковые роботы. Кроме того, при таком способе
Download агент сможет замаскироваться под поискового робота. (см. пример 2)
- Запрещать IP адрес можно не по факту загрузки скрытой страницы, а по факту
загрузки картинки, установленной на скрытой странице. Поисковые роботы обычно
не запрашивают изображения размещенные на страницах, а Download агенты обычно
делают это.
Выводы.
Как видите, метода, который бы работал на сто процентов, нет, и вам придется
что-то (или кого-то) приносить в жертву. Ниже приведен код PHP класса, который
реализует защиту от скачивания, описанную в третьем методе. Пример PHP
класса
flooders.inc.php: <? class Flooders { var $filename;/*
Имя файла, в котором хранится список */ /* запрещенных IP адресов*/
var $timeout; /* Время, на которое производится бан IP */ /* адреса.
По умолчанию - 600 (10 минут) */
var $log; /* Имя лог-файла.*/
var $AGENTS; /* Массив - список разрешенных агентов */
/* */
/* Конструктор - в параметрах можно указать основные настройки */ /* */
/* $filename - имя файла, в котором хранится список */ /* забаненных
адресов. */ /* $timeout - время, в секундах, на которое банится IP. */
/* */ /* Пример: $f=new Flooders("ban.txt",3600);*/ /* */
function Flooders($filename="flooders.txt",$timeout=600) {
$this->filename=$filename; $this->timeout=$timeout;
$this->AGENTS=Array(); $this->log=""; }
/* */ /*
Задает имя лог-файла. Если имя файла пустое, то лог-файл*/ /* не
испольщуется */ /* */
function SetLogFileName($filename) {
$this->log=$filename; }
/* */ /* Проверка IP адреса на
нахождение в бан-листе. */ /* */ /* Если $http_errror==0, то возвращает
true, если IP адрес */ /* забанен, и false, если IP адрес разрешен. */
/* */ /* Если $http_error==404 и IP адрес забанен, то выводится */
/* стандартная страница 404 сервера Apache */ /* */ /* Если
$http_error==403 и IP адрес забанен, то выводится */ /* стандартная страница
403 сервера Apache */ /* */
function Check($http_error=0) {
GLOBAL $HTTP_SERVER_VARS;
$ip1=$HTTP_SERVER_VARS["REMOTE_ADDR"];
$ip2=$HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"];
$ip1=str_replace(":","_",$ip1); $ip2=str_replace(":","_",$ip2);
$curtime=time();
$d=@file($this->filename); if
(!is_array($d)) {print "Ошибка чтения из файла
"".$this->filename."".";return(false);}
$found=false; for
($i=0;$i<count($d);$i++) { $e=explode(" : ",$d[$i]); if ($e[1]==$ip1
&& trim($e[2])==$ip2 && $e[0]+$this->timeout>$curtime)
{$found=true;break;} } if ($http_error==404 && $found==true) {
header("HTTP/1.0 404 Not Found"); die("<!DOCTYPE HTML PUBLIC
\"-//IETF//DTD HTML 2.0//EN\">\n<HTML><HEAD>\n<TITLE>404
Not Found</TITLE>\n</HEAD><BODY>\n<H1>Not
Found</H1>\nThe requested URL ".$HTTP_SERVER_VARS["REQUEST_URI"]." was not
found on this
server.<P>\n<HR>\n".$HTTP_SERVER_VARS["SERVER_SIGNATURE"]."\n</BODY></HTML>");
} if ($http_error==403 && $found==true) { header("HTTP/1.0
403 Forbidden"); die("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML
2.0//EN\">\n<HTML><HEAD>\n<TITLE>403
Forbidden</TITLE>\n</HEAD><BODY>\n<H1>Forbidden</H1>\nYou
don't have permission to access ".$HTTP_SERVER_VARS["REQUEST_URI"]."\non this
server.<P>\n<HR>\n".$HTTP_SERVER_VARS["SERVER_SIGNATURE"]."\n</BODY></HTML>");
} return($found); }
/* */ /* Добавления IP адреса в
бан-лист */ /* */
function Ban() { GLOBAL $HTTP_SERVER_VARS;
$agent=" ".$HTTP_SERVER_VARS["HTTP_USER_AGENT"]; for
($i=0;$i<count($this->AGENTS);$i++) { if
(strpos($agent,$this->AGENTS[$i])) return; }
$ip1=$HTTP_SERVER_VARS["REMOTE_ADDR"];
$ip2=$HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"];
$ip1=str_replace(":","_",$ip1); $ip2=str_replace(":","_",$ip2);
$curtime=time();
$d=@file($this->filename); if
(!is_array($d)) {print "Ошибка чтения из файла "".$this->filename."".";}
for ($i=0;$i<count($d);$i++) { $e=explode(" : ",$d[$i]); if
($e[1]==$ip1 && trim($e[2])==$ip2) unset($d[$i]); }
if
(need_add) { if (!empty($this->log)) { $fw=fopen($this->log,"at");
if ($fw) { fputs($fw, date("Y-m-d H:i:s")."
[".$ip1."|".$ip2."]".$agent."\n"); fclose($fw); } }
$d[]=$curtime." : ".$ip1." : ".$ip2."\n"; }
$fw=@fopen($this->filename,"wt"); if (!$fw) {print "Ошибка записи
в файла "".$this->filename."".";return;}
foreach ($d as $e)
fputs($fw,$e); fclose($fw); }
function AddAlowAgent($agent) {
$this->AGENTS[]=$agent; } } ?>
Примеры использования. Пример 1.
Этот код должен быть установлен на скрытой странице: <? include
"flooders.inc.php";
$f=new Flooders(); $f->Ban(); ?>
Этот код должен быть установлен в верхней части всех страниц сайта: <?
include "flooders.inc.php";
$f=new Flooders();
$f->Check(404); ?> Пример 2 - не запрещающий известных
поисковых роботов.
Этот код должен быть установлен на скрытой странице: <?
include "flooders.inc.php";
$f=new Flooders("/tmp/ban.txt");
$f->AddAlowAgent("StackRambler"); $f->AddAlowAgent("Googlebot");
$f->AddAlowAgent("Yandex"); $f->AddAlowAgent("Aport");
$f->AddAlowAgent("msnbot"); $f->AddAlowAgent("FAST-WebCrawler");
$f->AddAlowAgent("Slurp/cat"); $f->AddAlowAgent("ASPseek/1.2.10");
$f->AddAlowAgent("CNSearch"); $f->SetLogFileName("/tmp/ban.log");
$f->Ban(); ?>
Этот код должен быть установлен в верхней части всех страниц сайта:
<? include "flooders.inc.php";
$f=new
Flooders("/tmp/ban.txt"); $f->Check(403); ?>
При перепечатке любого материала
с сайта, видимая ссылка на источник www.warayg.narod.ru
и все имена, ссылки авторов обязательны.
© 2005
|