Главная > Интернет > Поисковая оптимизация Защита веб-сайта от автоматического скачивания
Зачем массово качаются сайты? Сходу можно указать две причины. Кому-то Ваш сайт очень понравился и этот "кто-то" нашел на нем много полезной для себя информации. Вот и хочется человеку сделать себе локальное "зеркало" этого сайта, для того, чтобы не выходя в Интернет как следует изучить информацию на нем. В другом случае кто-то также нашел сайт интересным, но не в плане информативности, а в плане заработка. Такие субъекты, массово выкачивая сайты со структурой каталогов, медиа-контентом и прочим содержимым, создают потом "зеркала" этого сайта в Сети на каком-то ином хостинге, а проще говоря, крадут сайт целиком чтобы на этом потом заработать. Уверен, что ни одному владельцу сайта не будет легче ни от первой причины, ни, тем более, от второй, когда его сайт начинают копировать подчистую. Как минимум, это процесс доставляет технические неудобства. Появляется излишняя нагрузка на сервер, расходуется излишний трафик, а если трафик этот в лимите, то еще и излишние деньги за превышение лимита трафика. Обычно веб-мастера, видя как нещадно с их сайта выгружаются один за одним страницы со скоростью, с которой нормальный человек не может серфить по сайту, опускают руки и оставляют все на самотек. Ведь если посмотреть с другой стороны, как-бы если твой сайт кто-то решил скопировать, значит он у тебя действительно полезен. Можно вроде бы этим гордиться? Нет. Гордость отодвинем на второе место. Ведь мы же не станем гордиться, если у нас угонят машину, думая, какая же классная была она у нас, раз ее решили угнать. Будем пытаться защищаться. Но, от воровства контента 100% средств защиты нет И это аксиома! Хотя... Вообще, такая защита есть - Вам попросту не стоит выкладывать в Сеть то, чего опасаетесь, что у Вас украдут... Если бы все владельцы сайтов боялись кражи контента, в сети Интернет информационных веб-ресурсов не существовало бы в принципе. Идею написать материал по этой теме, а также реализовать защиту для live.daemony.org от тотального скачивания мне "подбросил" один из посетителей из сетей Укртелекома, который вчера вечером с IP адреса 92.113.86.1X3 пытался выкачать страницы этого блога программой HTTrack (судя по User-Agent). Адрес я забанил в .htaccess, но IP Укртелеком выдает динамические и такая защита - всего временная "затычка". Я отправился гуглить на тему соответствующего решения появившейся проблемы. Честно говоря, нагуглил не очень много. Готовых, действительно стоящих решений я не нашел. То ли народ проблемой выкачивания сайтов вовсе не озабочен, то ли я плохо искал. Примеры, которые я нашел, мне показались малоэффективными, а некоторые вроде "банить по User-Agent" - извините, меня глупыми. Ведь не секрет какие программы используются для скачивания сайтов. Типичные примеры - TeleportPro, Offline Explorer, ДискоКачалка, да и тот же HTTrack. Все эти программы в своих настроках позволяют переиначить агента, а многие уже по-умолчанию используют что-то типа "Internet Explorer 6.0". Потому, решил ковырять тему самостоятельно. А вдруг что-то и получится. Еще из списка предлагаемых на форумах способов запрета скачивания сайтов можно назвать установку ограничений на количество запросов к сайту в единицу времени. В принципе, решение имеет право на жизнь. Да, кстати, и у "Гугл-Карты" такая защита очень хорошо работает. При очень большом количестве запросов в какой-то момент времени на сайте появляется приглашение подтвердить, что страницы запрашивает не программа-робот, а живой человек (нужно ввести капчу). Программы, для скачивания карт "идут лесом" или по крайней мере работают не так эффективно, как планировалось. Реализация этого способа для меня показалась несколько затруднительной. С моими скудными знаниями PHP такое врядли получится сделать в короткие сроки. Остановился я на идее, которая по своей сути задействует Разобрав концовку лога сервера Apache на предмет посещения ссылки-ловушки, нам ничего не будет стоить забанить IP такого "посетителя" на определенное время или навсегда. Я хочу поделиться своим примером защиты от скачивания, который реализовал сегодня на этом сайте. Не исключено, что чем-то он может показаться Вам "кривым", в чем-то неоптимальным (я имею в виду сами скрипты). Что-ж, я буду рад выслушать в комментариях Ваши дополнения и предложения. А вот если мой пример принесет Вам практическую пользу, я за Вас порадуюсь. У меня пока что система работает в режиме тестирования. Начнем с того, что еще раз охарактеризуем нашего потенциального враждебного посетителя и последовательно поставим задачу.
Последовательность реализации
Задача поддается реализации с использованием стандартных средств ОС FreeBSD, либо другой Unix-like системы.Всего мне пришлось написать два скрипта. Первый скрипт я буду запускать по cron раз в пять минут. Он будет проверять последние, допустим, 5000 строк файла access.log на предмет "интересной" ссылки и, в случае ее нахождения, реагировать соответствующе. Второй скрипт будет вызываться раз в час (например, на 20-й минуте часа) и, в случае если за последний час был кто-то пойман, архивировать имеющиеся данные, очищать текущий список заблокированных хостов и отправлять администратору уведомление со списком забаненных. Для хранения скриптов и прочих файлов я создам отдельный каталог. Основная директория сайта у меня в папке /www/live.daemony.org Здесь у меня расположены каталоги logs/ (с логами сервера), htdocs/ (с непосредственно самими файлами сайта) а теперь еще добавится каталог, допустим, shell, в котором все и будет происходить. $ ls -la /www/daemony.org/ ... drwxrwx--- 6 daemony www 1536 17 апр 13:45 htdocs drwxr-x--- 3 daemony www 512 17 апр 11:04 leech drwxr-x--- 2 daemony www 2048 17 апр 13:35 logs drwx--x--- 2 daemony www 512 17 апр 17:35 shell ... Обратите внимание на права доступа. Я сделал каталог shell доступным для пользователя www, потому что в нем будет храниться файл с URL-ловушкой, который будет инклюдиться в PHP шаблон сайта. Создадим, собственно, сам файл и поместим в него какую-то первоначальную последовательность символов: $ cd shell /www/daemony.org/shell $ touch randurl $ echo "blablabla" > randurl Тут же можно сразу подправить шаблон сайта и сделать вставку URL-ловушки. Я вставил ее в шаблоне темы WordPress таким образом: <a title="ВНИМАНИЕ! Если Вы человек, а не робот НЕ НАЖИМАЙТЕ на эту ссылку, иначе доступ к этому сайту будет для Вас заблокирован приблизительно на 1 час." href="http://daemony.org/<?php include ('/www/daemony.org/shell/randurl'); ?>.html">©</a> Вы эту ссылку можете найти в шапке сайта под заголовком сразу же после описания. Ею обрамлен значек копирайта. Почему я поступил именно так? Потому что поисковики не любят ссылки, скрытые от глаз посетителя. Кроме того, обычному человеку вряд ли прийдет в голову ткнуть в этот копирайт. Скорее всего, он его даже не заметит. А если даже он и поднесет к нему курсор мыши, то увидит предупреждение. Следующим шагом, что я посчитал нужным сделать - это сохранить свой текущий .htaccess файл. Это оказалось не лишним, поскольку пока я экспериментировал со скриптами, обнулил свой (достаточно немаленький) .htaccess несколько раз. Собственно поэтому теперь и Вам советую: сделайте бекап .htaccess! Более того, по моей схеме постоянное содержимое .htaccess будет храниться в другом файле, а в сам .htaccess будет каждый раз записываться новая информация. $ cp /www/daemony.org/htdocs/.htaccess /www/daemony.org/shell/htaccess В принципе все готово. Приступаем к скриптам ban_mega_dl.sh [версия 1.0]#!/bin/sh
#
# Anti-website-downloaders scripts by Daemony
#
# --- Переменные ---
WORKDIR="/www/live.daemony.org" # Рабочая директория
ACCESSLOG="$WORKDIR/logs/access.log" # Путь к файлу доступа сервера Apache
BLOCKLOG="$WORKDIR/shell/blocked.log" # Путь к текущему лог-файлу забаненных хостов
BLOCKLOGTMP="$WORKDIR/shell/blocked.tmp" # Временный файл
RANDURLFILE="$WORKDIR/shell/randurl" # Файл, в котором будет храниться постоянно
# изменяющаяся часть имени URL-ловушки.
HTACCESS="$WORKDIR/htdocs/.htaccess" # Путь к нашему основному .htaccess
HTSTATIC="$WORKDIR/shell/htaccess" # "Статическая" копия нашего .htaccess.
# Получаем текущее значение изменяющейся части URL-ловушки
RANDURL=`cat $RANDURLFILE`
# Следующей командой:
# 1. Отделяем последние 5000 строк файла доступа Apache.
# 2. Пытаемся найти в этих строках переходы по URL-ловушке.
# 3. Отделяем все строки, которые были сгенерированы с хостов,
# у которых PTR записи смахивают на Google, Yandex, и все
# остальное, кого мы банить не хотим.
# ВАЖНО!
# Ваш Apache должен писать в логи не IP адреса,
# а имена хостов (директива в httpd.conf - HostnameLookups On).
# 4. Оставляем только первый столбец в выводе и отправляем
# его в лог-файл забаненных имен хостов.
tail -n 5000 $ACCESSLOG |
grep "$RANDURL" |
grep -v "googlebot.com" |
grep -v "yandex.ru" |
grep -v "yahoo.com" |
grep -v "nigma.ru" |
grep -v "rambler.ru" |
awk '{print $1}'
>> $BLOCKLOG
# 5. Лог забаненных имен хостов сортируем по алфавиту и удаляем в нем повторяющиеся записи.
# Сохраняем во временном файле.
cat $BLOCKLOG |
sort |
uniq
> $BLOCKLOGTMP
# 6. Временный файл перемещаем на место постоянного.
mv $BLOCKLOGTMP $BLOCKLOG
# Получаем в следующую переменную список попавшихся имен хостов
# в _одну_ строку через пробел.
BLOCKLIST=`cat $BLOCKLOG | xargs`
# Проверяем, есть ли что-то в списке или нет. Если есть, то:
# 1. Перезаписываем .htaccess файл нашего сайта, отправляя в него основное его содержимое,
# а также строчки со списком забаненных имен хостов.
if [ "$BLOCKLIST" != "" ];
then {
cat $HTSTATIC > $HTACCESS
echo "Deny from" $BLOCKLIST "# Banned Web-Downloaders by Daemony" >> $HTACCESS
# Затем вот этим нехитрым способом генерим новое имя ссылки URL-ловушки,
# читая последнюю строчку файла доступа Apache и отправляя эту строчку в файл.
tail -n 1 $ACCESSLOG |
awk '{print $1 $4}' |
tr '-+.?[|]:/0-9A-z' 'A-z0-9' |
tail -c 31 |
head -c 30 > $RANDURLFILE
# Если список оказался пуст, то есть роботов-хулиганов на сайте не было, просто
# генерим новое имя ссылки URL-ловушки.
} else {
tail -n 1 $ACCESSLOG |
awk '{print $1 $4}' |
tr '-+.?[|]:/0-9A-z' 'A-z0-9' |
tail -c 31 |
head -c 30 > $RANDURLFILE
}
fi
exit
blocked_log_rotate.sh#!/bin/sh # # Anti-website-downloaders scripts by Daemony # # --- Переменные --- # Переменные аналогичны WORKDIR="/www/live.daemony.org" BLOCKLOG="$WORKDIR/shell/blocked.log" BLOCKLIST=`cat $BLOCKLOG | xargs` HTACCESS="$WORKDIR/htdocs/.htaccess" HTSTATIC="$WORKDIR/shell/htaccess" # Путем проверки основного лог-файла забанненых хостов, получаем # список (в одну строчку через пробел) тех, кто попался на удочку # за последний час. BLOCKLIST=`cat $BLOCKLOG | xargs` # Список может быть пуст. Поэтому используем условие проверки. if [ "$BLOCKLIST" != "" ]; then { # Убираем все запреты за прошлый час. Перезаписываем .htaccess cat $HTSTATIC > $HTACCESS # Если список не пуст, создаем запись в архивном файле с текущей датой и временем echo "#" $(date +%Y-%m-%d) $(date +%H:%M:%S) >> $BLOCKLOG.archive # Переписываем в архивный файл список тех имен хостов, # что попали в бан за последний час echo $BLOCKLIST >> $BLOCKLOG.archive # Обнуляем основной лог-файл забаненных имен хостов cat /dev/null > $BLOCKLOG # Ну, и строчим письмо администратору с сообщением # о том, кто пытался качнуть его сайт. echo " Hello, Daemony. In last hour we got new megadownloader(s): ------------------------------------------ $BLOCKLIST -- Anti-Downloader Script " | mail -s "Banned host(s) at your site" admin@site.com # Замените admin@site.com на свой e-mail адрес. } fi exit Вот, собственно, и вся реализация. Осталось наши конфиги занести в crontab. # - Ban scripts for Web-Downloaders - 20 * * * * daemony /www/daemony.org/shell/blocked_log_rotate.sh */5 * * * * daemony /www/daemony.org/shell/ban_mega_dl.sh Касательно того, сколько последних строчек лога шерстить и с каким промежутком во времени - каждому решать индивидуально. Я взял 5000 экспериментально. Многое зависит от посещаемости Вашего сайта. А для перенаправления тех, кто попал в бан, дабы пояснить людям за что им закрыт доступ я сделал своя 403-ю страничку. Перенаправление осуществляется в htaccess таким образом: ErrorDocument 403 http://daemony.org/leech/403/ Повторюсь снова. Возможно, все это Вам покажется усложненным - я буду рад выслушать от Вас более оптимальные на Ваш взгляд варианты. А пока что, описанная здесь система работает. P.S.: Пока писал публикацию в список забаненных попало три IP адреса. Ребята с Питерского IP: елки-палки! Качать фотогалерею Даунлоуд Мастером - не слишком ли? А? P.P.S.: По мере тестирования работы скрипта и выявления ошибок, либо написания исправлений и дополнений эта публикация, возможно, будет обновляться. UPD: 2009-04-18 09.00А вот и первые грабли. Кривая реализация генерации случайной последовательности ссылки из последней строчки access.log дала о себе знать. Все, кто сегодня в промежуток с 00 часов 00 минут по Киевскому времени по 00 часов 05 минут находились на сайте (или просто держали открытой страничку в браузере) попали в бан на один час. Приношу извинения. Заметил это только утром. Почему так произошло.Я предполагаю, что скрипт при срабатывании в 00 часов 00 мин. не смог сгенерировать нормально случайное имя ссылки и в итоге оно оказалось пустым. Соответственно, в 00.05, когда произошла очередная проверка логов, все хосты, которые в нем были попали под правила поиска (по идее, искалась пустая строка, которую можно найти в любой строчке лога) и были отправлены в лог-заблокированных. Следует выбрать другой способ подстановки случайной последовательности символов... UPD: 2009-04-18 17.14Нашел красивое решение реализации простого генератора случайной последовательности заданной длины с использованием заданных символов. Скрипт немного переделал под себя, чтобы он выдавал только одно случайное значение, а не несколько. Используется старый, добрый awk. rand.sh#!/usr/bin/awk -f BEGIN { # Здесь указываем, какие символы будут использоваться для генерации # случайной последовательности. s="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" srand() code="" # В цикле замените цифру 10 на другую, если Вам необходимо # сгенерировать строку больше, чем из 10-ти символов. for (j=1;j<=10;j++) code = code""substr(s,int(rand()*62)+1,1) print code } Теперь порядок. Кладем скрипт в папку shell/ и придаем скрипту ban_mega_dl.sh следующий вид: ban_mega_dl.sh [версия 2.0]#!/bin/sh # # Anti-website-downloaders scripts by Daemony # WORKDIR="/www/live.daemony.org" ACCESSLOG="$WORKDIR/logs/access.log" BLOCKLOG="$WORKDIR/shell/blocked.log" BLOCKLOGTMP="$WORKDIR/shell/blocked.tmp" RANDURLFILE="$WORKDIR/shell/randurl" RANDGEN="$WORKDIR/shell/rand.sh" HTACCESS="$WORKDIR/htdocs/.htaccess" HTSTATIC="$WORKDIR/shell/htaccess" RANDURL=`cat $RANDURLFILE` tail -n 5000 $ACCESSLOG | grep "$RANDURL" | grep -v "googlebot.com" | grep -v "yandex.ru" | grep -v "yahoo.com" | grep -v "nigma.ru" | grep -v "rambler.ru" | awk '{print $1}' >> $BLOCKLOG cat $BLOCKLOG | sort | uniq > $BLOCKLOGTMP mv $BLOCKLOGTMP $BLOCKLOG BLOCKLIST=`cat $BLOCKLOG | xargs` if [ "$BLOCKLIST" != "" ]; then { cat $HTSTATIC > $HTACCESS echo "Deny from" $BLOCKLIST "# Banned Web-Downloaders by Daemony" >> $HTACCESS `$RANDGEN > $RANDURLFILE` } else { `$RANDGEN > $RANDURLFILE` } fi exit Вот. Другое дело. Для генерации случайной последовательности, мы больше не привязаны к логу access.log. Строка, которую генерит awk всегда будет уникальна. Тестируем дальше. UPD: 2009-04-20 13.47Третий день, полет нормальный. За это время попало в ловушку три хоста и ручной анализ логов говорит о том, что не просто так - действительно с заблокированных хостов предпринимались попытки автоматического скачивания страниц сайта. Новых поисковых ботов (кроме тех, что уже внесены в исключения) не выявлено. Немного усовершенствовал скрипт, дабы не плодить лишние 404-е ошибки поисковыми ботами из-за отсутствующих страниц - URL-ловушек. Теперь в системе будет постоянно существовать страница со случайным именем. Приводим скрипт blocked_log_rotate.sh к такому виду: ban_mega_dl.sh [версия 3.0]#!/bin/sh # # Anti-website-downloaders scripts by Daemony # WORKDIR="/www/live.daemony.org" ACCESSLOG="$WORKDIR/logs/access.log" BLOCKLOG="$WORKDIR/shell/blocked.log" BLOCKLOGTMP="$WORKDIR/shell/blocked.tmp" RANDURLFILE="$WORKDIR/shell/randurl" RANDGEN="$WORKDIR/shell/rand.sh" HTACCESS="$WORKDIR/htdocs/.htaccess" HTSTATIC="$WORKDIR/shell/htaccess" RANDURL=`cat $RANDURLFILE` TRAPPAGE="$WORKDIR/htdocs/$RANDURL.html" # Имя файла с именем URL-ловушки tail -n 5000 $ACCESSLOG | grep "$RANDURL" | grep -v "googlebot.com" | grep -v "yandex.ru" | grep -v "yahoo.com" | grep -v "nigma.ru" | grep -v "rambler.ru" | awk '{print $1}' >> $BLOCKLOG cat $BLOCKLOG | sort | uniq > $BLOCKLOGTMP mv $BLOCKLOGTMP $BLOCKLOG BLOCKLIST=`cat $BLOCKLOG | xargs` if [ "$BLOCKLIST" != "" ]; then { cat $HTSTATIC > $HTACCESS echo "Deny from" $BLOCKLIST "# Banned Web-Downloaders by Daemony" >> $HTACCESS `$RANDGEN > $RANDURLFILE` RANDURL=`cat $RANDURLFILE` mv $TRAPPAGE $WORKDIR/htdocs/$RANDURL.html } else { `$RANDGEN > $RANDURLFILE` RANDURL=`cat $RANDURLFILE` mv $TRAPPAGE $WORKDIR/htdocs/$RANDURL.html } fi exit Естественно, сразу же после правки скрипта следует создать в системе пустой файл с именем $RANDURL.html, где $RANDURL - будет текущее случайное значение имени URL-ловушки. В файл $RANDURL.html можно написать какую-нибудь предупреждающую инструкцию для качальщиков. Это уже на Ваше усмотрение. ДОПОЛНЕНИЕВам надоели люди, которые размещают картинки, опубликованные на вашем сайте - на своих ресурсах, тем самым расходуя ваш траффик и создавая ненужную нагрузку на ваш хостинг? Данный код, размещенный в конца вашего файла .htaccess, позволит предотвратить загрузку ваших изображений - сторонними сайтами. Options +FollowSymlinks Главная > Интернет > Поисковая оптимизация |