Блокировка ботов через htaccess

Блокируем ботов и подозрительный трафик по Referer, User Agent, URL, IP и строке запроса.

Блокировка ботов через htaccess

Ниже даны примеры правил mod_rewrite, которые позволяют выполнять определённые действия (например, блокировать) для пользователей, подпадающих под соответствие сразу большому количеству критериев.

Запрет доступа с пустым реферером (Referer)

Следующее правило запретит доступ всем запросом, в котором не установлен HTTP заголовок Referer (в логах Apache вместо строки Referer записывается "-"):

RewriteEngine   on
RewriteCond %{HTTP_REFERER} ^$
RewriteRule ^.* -   [F,L]

Блокировка доступа по части пользовательского агента (User Agent)

При блокировке ботов по User Agent необязательно указывать полное имя — можно указать только часть строки User Agent для совпадения. Специальные символы и пробелы должны быть экранированы.

Например, следующее правило заблокирует доступ для всех пользователей, в чьей строке User Agent встречается «Android 10»:

RewriteEngine   on
RewriteCond %{HTTP_USER_AGENT}  "Android\ 10"
RewriteRule ^.* -   [F,L]

Примеры заблокированных этим правилом User Agent:

  • Mozilla/5.0 (Linux; Android 10; SM-G970F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Mobile Safari/537.36
  • Mozilla/5.0 (Linux; Android 10; Redmi Note 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Mobile Safari/537.36

Как заблокировать доступ по точному совпадению User Agent

Если вам нужно заблокировать доступ к сайту определённым User Agent с точным совпадением имени, то используйте конструкцию с If (это не относится к mod_rewrite, но не стоит забывать о такой возможности):

<If "%{HTTP_USER_AGENT} == 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'">
    Require all denied
</If>
 
<If "%{HTTP_USER_AGENT} == 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'">
    Require all denied
</If>
 
<If "%{HTTP_USER_AGENT} == 'Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.9.0'">
    Require all denied
</If>

Запрет доступа к определённым страницам

Переменная %{REQUEST_URI} включает в себя всё, что идёт в запросе после имени хоста (но не включает то, что идёт после знака вопроса в URL), используя её можно фильтровать запросы по URL, строке запроса, именам файла или их частям.

Например:

RewriteEngine   on
RewriteCond %{REQUEST_URI}  "строка-запроса"
RewriteRule ^.* -   [F,L]

Не смотря на то, что в логах веб-сервера Apache некоторые символы, в том числе кириллица, отображается в URL кодировке, в данных правилах можно указывать кириллицу. Например, следующее правило заблокирует доступ к статье с URL https://site.ru/как-узнать-какой-файл-от/:

RewriteEngine   on
RewriteCond %{REQUEST_URI}  "как-узнать-какой-файл-от"
RewriteRule ^.* -   [F,L]

При желании, можно указать сразу несколько URL (или их частей). Каждая строка для поиска должна быть помещена в круглые скобки, между собой строки в скобках должны быть разделены символом | (конвейер, труба).

Например:

RewriteEngine   on
RewriteCond %{REQUEST_URI}  "(проигрыватель-windows)|(как-узнать-какой-файл-от)|(сколько-оперативной-памяти)|(как-в-windows-10-открывать)|(7-приложений-для)"
RewriteRule ^.* -   [F,L]

Поскольку %{REQUEST_URI} не включает то, что идёт после знака вопроса в URL, то для фильтрации по строке запроса, идущей после знака вопроса, используйте %{QUERY_STRING}.

Запрет доступа по IP и диапазонам

С помощью mod_rewrite можно блокировать отдельные IP от доступа к сайту:

RewriteEngine   on
RewriteCond "%{REMOTE_ADDR}"    "84.53.229.255"
RewriteRule ^.* -   [F,L]

Можно указать несколько IP адресов для блокировки:

RewriteEngine   on
RewriteCond "%{REMOTE_ADDR}"    "84.53.229.255" [OR]
RewriteCond "%{REMOTE_ADDR}"    "123.45.67.89" [OR]
RewriteCond "%{REMOTE_ADDR}"    "122.33.44.55"
RewriteRule ^.* -   [F,L]

Также можно использовать и диапазоны, но нужно помнить, что в данном случае строки расцениваются как регулярные выражения, но тесть нотация CIDR (например, 94.25.168.0/21) не поддерживается.

Диапазоны должны быть указаны как регулярные выражения — это можно сделать с использованием наборов символов. Например, для блокировки следующих диапазонов:

  • 94.25.168.0/21 (диапазон 94.25.168.0 - 94.25.175.255)
  • 83.220.236.0/22 (диапазон 83.220.236.0 - 83.220.239.255)
  • 31.173.80.0/21 (диапазон 31.173.80.0 - 31.173.87.255)
  • 213.87.160.0/22 (диапазон 213.87.160.0 - 213.87.163.255)
  • 178.176.72.0/21 (диапазон 178.176.72.0 - 178.176.75.255)

будет работать правило:

RewriteEngine   on
RewriteCond "%{REMOTE_ADDR}"    "(94\.25\.1[6-7]])|(83\.220\.23[6-9])|(31\.173\.8[0-7])|(213\.87\.16[0-3])|(178\.176\.7[2-5])"
RewriteRule ^.* -   [F,L]

Обратите внимание, что диапазон 94.25.168.0 — 94.25.175.255 нельзя записать как 94.25.1[68-75], это будет истолковано как строка «94.25.1», и набор символов, включающий в себя символ 6, диапазон 8-7 и символ 5. Из-за диапазона 8-7 данная запись вызовет ошибку на сервере.

Поэтому для записи 94.25.168.0 — 94.25.175.255 используется «94\.25\.1[6-7]». Да, эта запись не совсем точно передаёт исходный диапазон — для увеличения точности, можно усложнить регулярное выражение. Но в моём случае это временный hotfix, поэтому и так сойдёт.

Также обратите внимание, что последний октет 0-255 можно пропускать, поскольку для совпадения с регулярным выражением достаточно того, что совпадёт часть IP адреса.

источник