Методы защиты сайтов
Защита сайта
Спасибо автору Давиду Туманову http://mycrimea.su/partners/web/access/
Наверное, многие web-мастера, которые не ленятся отслеживать логи посещений своих сайтов, задаются вопросом: «Как заблокировать доступ к сайту по IP адресам и отвадить надоедливых ботов и хакеров?» Собственно, проблема заключается не в том, каким способом запретить доступ к сайту. На помощь web-мастеру всегда придет конфигурационный файл .htaccess. Проблема в другом — в поиске списка диапазонов IP адресов, распределенных по географическому признаку.
Большинство моих сайтов рассчитаны на русскоязычную аудиторию. Географически — для Беларуси, России, Украины. Поэтому однозначно можно заблокировать IP адреса стран Африки, Юго-Восточной Азии и Южной Америки. Смотрите список IP адресов стран на ipdeny.com →
Оптимальное решение для запрета доступа к сайтам по выбранным IP адресам — использовать в файле .htaccess директиву Deny. Важно правильно установить порядок обработки правил — Allow,Deny или Deny,Allow:
- При Allow,Deny сначала обрабатываются разрешающие правила Allow, затем запрещающие Deny. Действия, не подпадающие ни под одну из директив Allow или Deny, будут запрещены по умолчанию — Deny имеет приоритет над Allow. Я рекомендую использовать для общего запрета данный порядок обработки правил — с Deny from all.
- При Deny,Allow сначала обрабатываются запрещающие правила Deny, затем разрешающие Allow. Действия, не подпадающие ни под одну из директив Deny или Allow, будут разрешены по умолчанию — Allow имеет приоритет над Deny. Я рекомендую использовать данный порядок обработки правил при выборочном запрете.
Если перечислять все диапазоны IP адресов выбранных стран, список получается слишком длинным. Чтобы избежать этого, я решил заблокировать блоки IP адресов, отличающихся первым октетом (ХХХ.0.0.0/8). Получился совсем небольшой список, охватывающий большинство диапазонов IP адресов: AfriNIC (Африка), APNIC (Юго-Восточная Азия) и LACNIC (Южная Америка и страны Карибского бассейна). Из списка я исключил блоки IP адресов ARIN (Северная Америка) и RIPE (Ближний Восток, Европа и Центральная Азия) — смотрите его здесь →
Блокировка IP адресов директивой Deny
Разрешаем только методы GET, HEAD, POST:
<LimitExcept
GET HEAD POST>
Order Allow,Deny
Deny from all
</LimitExcept>
Запрещаем доступ к сайту для всех методов с IP адресов AfriNIC, APNIC, LACNIC:
Order
Deny,Allow
# AfriNIC:
Deny from 41 102 105 197
# APNIC:
Deny from 1 14 27 36 39
Deny from 42.0.0.0/7
Deny from 49
Deny from 58.0.0.0/7
Deny from 60.0.0.0/7
Deny from 101 103 106
Deny from 110.0.0.0/7
Deny from 112.0.0.0/5
Deny from 120.0.0.0/6
Deny from 124.0.0.0/7
Deny from 126 133 175 180
Deny from 182.0.0.0/7
Deny from 202.0.0.0/7
Deny from 210.0.0.0/7
Deny from 218.0.0.0/7
Deny from 220.0.0.0/6
# LACNIC:
Deny from 177 179 181
Deny from 186.0.0.0/7
Deny from 189
Deny from 190.0.0.0/7
Deny from 200.0.0.0/7
# Networks:
Deny from 3 6 9 11 13 15
Deny from 16.0.0.0/6
Deny from 20.0.0.0/7
Deny from 22 25 26
Deny from 28.0.0.0/7
Deny from 30 33
Deny from 34.0.0.0/7
Deny from 38 40 44 47 48
Deny from 51
Deny from 52.0.0.0/6
Deny from 56.0.0.0/7
Deny from 214.0.0.0/7
Данным правилом я запретил доступ к сайту для IP адресов стран Африки, Юго-Восточной Азии, Южной Америки и Карибского бассейна, а также некоторых корпораций и учрежний типа министерства обороны страны, скорый кирдык которой предрекал герой Сергея Бодрова в фильме «Брат». Обратите внимание, что в этом списке отсутствуют IP адреса из смешанных зон, которые можно найти на сайтах AfriNIC, APNIC, LACNIC и RIPE. Однако данные диапазоны отсекают основной объем паразитного трафика. IP адреса ARIN блокировать не рекомендуется, иначе роботы поисковых систем Bing, Google, Yahoo не смогут заходить на ваш сайт.
Я умышленно задал порядок обработки правил Deny,Allow, а не наоборот, чтобы иметь возможность добавить ниже разрешающие правила исключений для некоторых IP-адресов из заблокированных диапазонов. Однако имейте ввиду, что и другие запрещающие правила для этих IP-адресов, касающиеся, например, запрета на использование определенных символов в URL, могут не действовать — будут разрешены любые URL-запросы. Кстати, в случае использования порядка обработки правил Allow,Deny рекомендуется прописать в самом начале разрешающее правило для всех Allow from all, но это не самое удачное решение — лучше его не использовать, если вы собираетесь устанавливать выборочно запрещающие правила.
Примечание: для отображения сообщения об ошибке 403 (доступ запрещен) лучше использовать не собственную страницу, а короткое сообщение, уменьшая тем самым нагрузку на сервер (какая вам разница, что увидят китаец или румын, пытавшиеся попасть на ваш сайт). Например, послать всех по известному адресу:
ErrorDocument
403 "Fuck you!
Обратите внимание на то, что в строке прописана только одна кавычка (для Apache 1.3). Для Apache 2.0 необходимо обязательно ставить закрывающую кавычку.
Блокировка IP адресов модулем Mod Rewrite
Используя модуль mod_rewrite, список IP адресов можно существенно сократить. В этом помогут регулярные выражения. Главное удобство модуля mod_rewrite в данной задаче — возможность использования правил исключений.
Блокировка IP адресов стран Северной Америки модулем Mod Rewrite
Задача: необходимо заблокировать IP адреса ARIN (стран Северной Америки), оставив доступ к сайтам для поисковых ботов Bing, Google, Yahoo. При этом на хостинге размещены несколько сайтов, один из которых предназначен для американской аудитории.
Для этого в корневой директории своего хостинга размещаем файл .htaccess, в котором прописываем следующее правило:
<IfModule
mod_rewrite.c>
# Включаем модуль mod_rewrite:
RewriteEngine on
# Для файла .htaccess, расположенного в корневой директории сайта
RewriteBase /
RewriteCond %{REMOTE_ADDR}
^(?:7|23|45|50|6[3-9]|7[1-6]|9[6-9]|1(?:0[0478]|7[2-4]|84|99)|2(?:0[4-9]|16))\..*$
RewriteCond %{HTTP_HOST} !^(?:www\.)?my_english_site\.com$ [NC]
RewriteCond %{HTTP_USER_AGENT} !bingbot [NC]
RewriteCond %{HTTP_USER_AGENT} !(?:Googlebot|gsa-crawler) [NC]
RewriteCond %{HTTP_USER_AGENT} !Slurp [NC]
RewriteRule ^.*$ - [F,L]
</IfModule>
Данное правило модуля mod_rewrite блокирует IP адреса стран Северной Америки, если имя хоста не содержит my_english_site.com, и строка User Agent не содержит имена поисковых ботов Bing, Google, Yahoo. Правило действует на все сайты, размещенные на хостинге, за исключением домена my_english_site.com. Если нужно исключить все поддомены этого сайта, пишем:
RewriteCond
%{HTTP_HOST} !^(?:.+\.)?my_english_site\.com$ [NC]
При использовании в файлах .htaccess, размещенных во вложенных директориях, правил модуля mod_rewrite не забудьте добавить наследование указанных правил, иначе они работать не будут:
<IfModule
mod_rewrite.c>
RewriteEngine on
RewriteOptions
inherit
RewriteBase /путь_к_директории_с_файлом_.htaccess_от_корня_сайта/
…
</IfModule>
Обязательно указывайте в RewriteBase путь к директории, в которой размещен файл .htaccess, от корня сайта. Все преобразования ссылок осуществляются относительно той директории, в которой расположен файл .htaccess. При этом унаследованные правила модуля mod_rewrite работают также относительно этой директории, то есть как бы копируются в новый файл. Если файл .htaccess расположен в директории /partners/web/access/, как данная статья, то:
RewriteBase
/partners/web/access/
Интересную статью о том, как работает mod_rewrite, читайте на habrahabr.ru →
Использование общего файла .htaccess для всех сайтов возможно не на всех хостингах. В противном случае вам придется прописывать данные правила для каждого сайта в отдельности, что неудобно при редактировании (придется вносить изменения в файлы .htaccess каждого сайта).
Блокировка всех IP адресов, кроме стран СНГ, Bing, Google, Yahoo
Правило, блокирующее доступ к сайту со всех IP адресов, за исключением стран СНГ (включая Балтию) и поисковых ботов Bing, Google, Yahoo:
<IfModule
mod_rewrite.c>
RewriteEngine on
RewriteBase /
# Запретить все IP, кроме СНГ, Bing, Google, Yahoo:
RewriteCond %{REMOTE_ADDR}
!^(?:2|3|5|3[17]|46|62|7[7-9]|8[0-9]|9[0-5]|1(?:09|28|3[046]|4[1569]|5[189]|64|7[168]|8[58]|9[2-5])|21[237])\..*$
RewriteCond %{HTTP_USER_AGENT} !bingbot [NC]
RewriteCond %{HTTP_USER_AGENT} !Googlebot [NC]
RewriteCond %{HTTP_USER_AGENT} !Slurp [NC]
RewriteRule ^.*$ - [F,L]
</IfModule>
В данное правило включены диапазоны IP адресов по первому октету, в которые входят IP адреса всех бывших республик СССР (включая Латвию, Литву и Эстонию). Данное правило не блокирует IP адреса других европейских стран, которые также входят в данный диапазон. Правило удобно применять для сайтов, ориентированных исключительно на аудиторию СНГ. Правда, если в будущем список IP-адресов, закрепленных за странами СНГ, расширится, новые адреса окажутся в числе запрещенных.
Защита сайта с помощь модуля mod_setenvif
Модуль mod_setenvif, позволяющий использовать регулярные выражения, на мой взгляд, представляет наиболее удобный способ защиты сайта.
<IfModule
mod_setenvif.c>
# Устанавливаем переменную post, разрешающую метод POST для следующих
URL:
SetEnvIf Request_URI ^URL_1$ post
SetEnvIf Request_URI ^URL_2$ post
# Разрешаем метод POST только для URL_1 и URL_2:
<Limit POST>
Order Deny,Allow
Deny from env=!post
</Limit>
# Блокировка ботов по User
Agent:
SetEnvIfNoCase User-Agent "(?:Accoona|antabot|Ask
Jeeves/Teoma|Baiduspider|Bigmir|China|curl/|Dolphin|Download|EltaIndexer|Email|FlashGet|GameSpy|Gigabot|grub|Gulper
Web|ia_archiver|liveinternet|Meta|Mihalism|OmniExplorer|Pagebull|Scooter|Twiceler|Validator|WebAlta|Wget|WordPress).*$"
bad
# Блокировка IP-адресов AfriNIC,
APNIC, LACNIC:
SetEnvIf Remote_Addr
^(?:[346-9]|1[1-35-9]|2[0-25689]|3[02-58]|4[04578]|5[1-7]|21[45])\..*$
bad
# AfriNIC:
SetEnvIf Remote_Addr ^(?:41|102|105|197)\..*$ bad
# APNIC:
SetEnvIf Remote_Addr
^(?:1|14|27|3[69]|4[239]|5[89]|6[01]|1(?:0[136]|1[0-9]|2[0-6]|33|75|8[023])|2(?:0[23]|1[0189]|2[0-3]))\..*$
bad
# LACNIC:
SetEnvIf Remote_Addr ^(?:1(?:7[79]|8[1679]|9[01])|20[01])\..*$ bad
# Запрет для бота Dolphin:
SetEnvIf Remote_Addr ^94\.127\.14[45]\..*$ bad
SetEnvIf Referer ^https?://(?:.+\.)?amazing\.ru/.*$ bad
SetEnvIf Remote_Addr ^213\.189\.197\.7$ bad
# Запрет языковых версий браузера - Arabic|Hindi|Turkish|Chinese:
SetEnvIfNoCase Accept-Language (?:ar|hi|tr|zh) bad
# Символы, разрешенные в URL, например:
SetEnvIf Request_URI [^-/\._0-9a-z] bad
# Ограничение длины URL:
SetEnvIf Request_URI ^.{242,}$ bad
# Маска для разрешенных URL — без учета параметров запроса, ограничить
которые можно с помощью модуля mod_rewrite, например:
SetEnvIf Request_URI
^/(?:[-/_0-9a-z]{0,236}(?:/|\.[a-z]{2,4}|[0-9a-z]))?$ good
<Limit GET HEAD>
Order Deny,Allow
Deny from env=!good
Deny from env=bad
</Limit>
</IfModule>
Order Deny,Allow
# Запрет всех IP-адресов компнии, позиционирующей себя на рынке
поискового продвижения сайтов:
Deny from 94.77.64.0/18
Если необходимо заблокировать какую-либо сеть, разрешив1 доступ к сайту с некоторых IP-адресов этой сети, пишем:
Order
Deny,Allow
Deny from 94.77.64.0/18
Allow from 94.77.64.50 94.77.64.51 94.77.64.52
1 Напоминаю, что в этом случае для IP 94.77.64.50, 94.77.64.51, 94.77.64.52 не будут действовать другие запрещающие правила — например, по маске URL или User-Agent.
Правила блокировки для IP адресов стран Европы я не составлял — слишком много диапазонов, распределенных по разным странам, включая СНГ (если не лень, можно отлавливать засланцев по логам). Если IP принадлежит хостинг-провайдеру, можно смело блокировать всю сеть, поскольку зайти из нее может только бот. Дополнительно можно использовать блокировку доступа к сайту по User Agent известных ботов, список которых смотрите здесь.
P.S. Используя вышеописанный метод, я запретил также возможность доступа к своему компьютеру (англоязычные сайты меня не интересуют), прописав в правилах сетевого экрана указанные диапазоны IP адресов (исключая зоны ARIN и RIPE). Правда, у меня по умолчанию всего-то открыты 2 порта, но это тема уже другой статьи, касающейся настройки Windows XP. А пока можете ознакомиться с простым и эффективным способом защиты почты от спама.
Дополнительные настройки в файле .htaccess
Защита сайта от «левых» параметров в запросах
<IfModule
mod_rewrite.c>
# RewriteCond %{THE_REQUEST} \?[0-9A-Z] [NC,OR] (если не используете
ссылки с параметрами, раскомментируйте строку)
RewriteCond %{THE_REQUEST}
(?:\%[0-9A-Z]*|\&|\(|\)|\+|\[|\]|\<|\>) [NC,OR]
RewriteCond %{THE_REQUEST} (?:\<|%3C).*script.*(?:\>|%3E) [NC,OR]
RewriteCond %{THE_REQUEST} _REQUEST(?:=|\[|\%[0-9A-Z]{0,2}) [NC,OR]
RewriteCond %{THE_REQUEST} base64_encode.*\(.*\) [NC,OR]
RewriteCond %{THE_REQUEST} DOCUMENT_ROOT= [NC,OR]
RewriteCond %{THE_REQUEST} GLOBALS(?:=|\[|\%[0-9A-Z]{0,2}) [NC,OR]
RewriteCond %{THE_REQUEST} javascript [NC,OR]
RewriteCond %{THE_REQUEST} mosConfig_[a-zA-Z_]{1,21}(?:=|\%3D) [NC]
RewriteRule ^.*$ - [F,L]
</IfModule>
Запись выше можно существенно сократить:
RewriteCond
%{QUERY_STRING}
(?:\?.*\?|_REQUEST|base64_encode|GLOBALS|mosConfig_|script) [NC,OR]
RewriteCond %{THE_REQUEST}
(?:\%[0-9A-Z]*|\&|\(|\)|\+|\[|\]|\<|\>)
RewriteRule ^.*$ - [F,L]
Либо глобально разрешаем только, например, три метода (GET, HEAD, POST) с заранее указанными символами в строке http-запроса, причем метод POST разрешается только для указанного REQUEST_URI:
RewriteCond
%{THE_REQUEST} !^(?:GET|HEAD)\
/(?:[разрешенные_символы_REQUEST_URI]+(?:\?[разрешенные_символы_QUERY_STRING]+)?)?\
HTTP/1\.[01]$
RewriteCond %{THE_REQUEST} !^POST\
/разрешенный_для_метода_POST_REQUEST_URI\ HTTP/1\.[01]$
RewriteRule ^.*$ - [F,L]
Защита сайта от хотлинка с использованием модуля mod_setenvif
Запрещаем скачивание графических файлов на сайте по прямым ссылкам:
<IfModule
mod_setenvif.c>
SetEnvIf Referer ^$ my_host
SetEnvIf Referer ^http://(?:.+\.)?my_site\.ru/.*$ my_host
SetEnvIf Referer
^https?://(?:.+\.)?(?:google|yandex)\.(?:com?\.)?[a-z]{2,3}/.*$ my_host
SetEnvIf Referer ^https?://(?:.+\.)?googleusercontent\.com/.*$ my_host
<FilesMatch "^.+\.(?:gif|jpg|png)$">
Order Deny,Allow
Deny from env=!my_host
</FilesMatch>
</IfModule>
Защиту сайта от хотлинка можно установить иначе — здесь используется другой порядок обработки правил, который, на мой взгляд, не совсем логичен:
<FilesMatch
".*\.(gif|jpg|png)">
Order Deny,Allow
Deny from all
Allow from env=my_host
</FilesMatch>
<FilesMatch
«.*\.(gif|jpg|png)»>Order Allow,Deny
Allow from all
Deny from env=!my_host
</FilesMatch>
Учтите, при использовании данного способа защиты от хотлинка на указанные файлы не будут действовать другие запрещающие правила — например, блокировка по IP или User-Agent. Для избежания этого можно использовать модуль mod_rewrite, указывая в директиве RewriteCond значение установленной мной переменной my_host — по умолчанию оно равно 1.
А при таком порядке обработки правил, где убрано Allow from all, графика может не отображаться — даже на разрешенных сайтах:
<FilesMatch
".*\.(gif|jpg|png)">
Order Allow,Deny
Deny from env=!my_host
</FilesMatch>
Защита сайта от хотлинка с использованием модуля mod_rewrite
С использованием переменной my_host, установленной в модуле mod_setenvif для файлов с расширениями .gif, .jpg, .png — ее значение по умолчанию равно 1:
<IfModule
mod_rewrite.c>
RewriteCond %{ENV:my_host} !^1$
RewriteRule ^.+\.(?:gif|jpg|png)$ - [F,L]
</IfModule>
Данный вариант можно использовать в случае отсутствия модуля mod_setenvif, поскольку модуль mod_rewrite предназначен для решения других задач — так микроскопом забивают гвозди:
<IfModule
mod_rewrite.c>
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(?:.+\.)?my_site\.ru/.*$ [NC]
RewriteCond %{HTTP_REFERER}
!^https?://(?:.+\.)?(?:google|yandex)\.(?:com?\.)?[a-z]{2,3}/.*$ [NC]
RewriteCond %{HTTP_REFERER}
!^https?://(?:.+\.)?googleusercontent\.com/.*$ [NC]
RewriteRule ^.+\.(?:gif|jpg|png)$ - [F,L]
</IfModule>
Решение задач по защите сайта не ограничивается описанными выше способами. Для этой цели можно использовать не только возможности файла .htaccess, но и php, что иногда бывает более удобно. Например, для проверки IP-адреса по маске подсети в массиве php. И помните, что с момента написания статьи сведения об IP-адресах стран СНГ могут оказаться устаревшими.
Автор: igel