Как защитить сайт от тотального скачивания
Бывают такие случаи, когда владелец сайта не
желает, или не может, отдавать свой сайт целиком своим посетителями.
Приведем простой пример:
У вас есть сайт, на котором, вы публикуете обои для рабочего
стола. Общий объем сайта - 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); ?>
Автор: Mike
Источник: www.codenet.ru
|