Привет! Я — Григорий, и последние 10 лет занимался созданием ботов. Однако теперь я разработал KillBot, который блокирует ботов и защищает сайты от их влияния.

В статье я расскажу как настроить промежуточный прокси-сервер, для проверки пользователя на бота еще до попадания на сайт, так же я расскажу как однозначно выявить простых http ботов и высокоуровневых JS.

Антибот должен выявлять два типа ботов:

  • простые HTTP-боты

  • продвинутые боты с поддержкой JavaScript.

Для их обнаружения существует как минимум три технических подхода:

  1. Установка JS скрипта на сайт, который анализирует JS для выявления бота;

  2. Использование PHP-предобработчика для анализа HTTP-трафика перед загрузкой сайта;

  3. Скрытие сайта за прокси-сервером по аналогии с Cloudflare;

Первый метод не защищает от парсинга простыми HTTP-ботами. Второй способ помогает защититься от HTTP-ботов, однако не выявляет ботов, поддерживающих JavaScript. Третий вариант способен защитить от ботов любого типа, поскольку трафик сначала проходит через промежуточный сервер, а затем попадает на сайт. Последний метод также предотвращает сканирование на уязвимости, так как первое взаимодействие происходит с сервером-прокладкой, а не с самим сайтом.

Как выявить простых ботов, которые представляются Яндексом, но таковыми не являются?

Сделать это просто - достаточно, отрезолвить домен на какой ссылается IP бота.

IP ботов поисковых систем и других популярных сервисов всегда прилинкованы к их головным доменам. Пример хоста, с которого ходит бот YaDirectFetcher Яндекса: 213-180-203-16.spider.yandex.com.

Ниже пример php кода, который проверяет, что домен прилинкован к Яндексу:

function checkIfTrueYandexBot($user_agent, $client_ip) {    
    if ((stripos($user_agent, 'bot') !== false) && (stripos($user_agent, 'yandex') !== false) ) {
        $hostname = gethostbyaddr($client_ip);    
        if ($hostname !== $client_ip && $hostname) {
            $yandex_domains = ['yandex.ru', 'yandex.net', 'yandex.com'];
            foreach ($yandex_domains as $domain) {
                if (substr($hostname, -strlen($domain)) === $domain) {
                    return true;
                }
            }
        }
        return false;
    }
    return true;
}

Таким образом, для защиты от простого HTTP парсинга можно создать свой список сервисов чьим ботам можно заходить на сайт, а всем остальным - запрещать. Так же нужно создать белый список серверов-колбеков с которыми взаимодействует сайт (оповещения о успешной оплате, например). Такой подход полностью защитит от http парсинга и не навредит.

Как заблокировать поведенческих JS ботов?

Сначала передам идею выявления ботов.

Допустим, есть заход на сайт с юзер агентом мобильного сафари. Но, по анализу параметров я вижу, что на самом деле это десктоп с разрешением экрана 1920:1080.

Могу я сказать что это бот?
нет, не могу - возможно некий пользователь просто использует расширение для изменения юзер агента.

А если из 4000 сессий 3000 имеют такой паттерн?
да, в этом случае я могу сказать что все (почти все) 3000 визитов - это боты. В этом случае можно или заблокировать такие заходы или показать капчу (а вдруг один из них будет реальным).

Поэтому, если браузерный движок не принадлежит настоящему браузеру (как в примере выше), и количество визитов от него статистически значимое, то это - бот.

Современные боты таких очевидных несоответствий, как в примере выше, не допускают. Я передал лишь идею. Но, тем не менее, KillBot умеет строить устойчивый слепок браузера для всех современных ботов.

Пример. Здесь: https://www.youtube.com/@Berzserkk/videos можно купить бот программу, написанную на БАС, которая крутит поведенческие. У этой бот программы есть свой основной слепок: 3083615002, и если я в статистике своего сайта увижу визиты с таким слепком, то это значит, что это визиты от бот программы товарища Дронова.

Ниже скриншот, который говорит, что от бот программы со слепком 3083615002 было 31879 сессий (каждая из этих сессий уникальна: со своим юзер агент и др. параметрами), но слепка 3083615002 нет среди реальных браузеров и число визитов очень велико (2-й по счету сверху). Значит - это бот программа:

Интерфейс управления ботами системы KillBot, пример блокирования бота, от которого много визитов
Интерфейс управления ботами системы KillBot, пример блокирования бота, от которого много визитов

Как настроить проксирование DNS трафика самостоятельно по типу как сделано у CloudFlare?

ДНС проксирование трафика - это когда пользователь сначала попадает на промежуточный прокси сервер, там заход анализируется и после анализа принимается решение пустить посетителя дальше на сайт или нет.

Настраиваем JS страницу проверки пользователя на бота самостоятельно

Здесь мы создадим страницу верификации - это файл botcheck.html. До захода на сайт пользователь будет перебрасываться на botcheck.html, находящийся на сервере-посреднике и, если проверка успешна, то трафик будет проксироваться на защищаемый сайт, если проверка не успешна, то пользователю можно запретить заход, показать капчу, редиректнуть на другой сайт: т.е. сделать любой действие.

Показываю пример настройки прокси сервера в связке Ubuntu + apache.

  1. Устанавливаем apache и включаем модули проксирования:

sudo apt install apache2
sudo a2enmod proxy
sudo a2enmod proxy_http

Создаем конфигурационный файл для апач: он будет проверять нужно ли редиректить пользователя на страницу верификации botcheck.html или можно разрешить доступ к сайту:

sudo nano /etc/apache2/sites-available/kill-bot.net.conf
<VirtualHost *:80>
    ServerName kill-bot.net
    ServerAlias www.kill-bot.net


    RewriteEngine On
    # Если кука не равна 1, то проверяем на бота на botcheck.php
    RewriteCond %{HTTP_COOKIE} !botcheck=1
    RewriteRule ^(.*)$ /botcheck.html [L]

    ProxyPreserveHost On
    ProxyPass / http://234.234.234.234/
    ProxyPassReverse / http://234.234.234.234/

</VirtualHost>

В примере выше: если кука botcheck!=1 , то делаем редирект на страницу botcheck.html (она располагается на самом прокси сервере) - эта страница должна реализовать всю логику проверки и выставить куку для доступа на сайт. IP = "234.234.234.234" нужно заменить на реальный IP вашего сайта - на него будет осуществляться проксирование если кука botcheck=1.

Подключение такого прокси-сервера посредника к сайту осуществляется путем замены DNS записи A основного сайта на IP самого прокси-сервера

Пример файла botcheck.html:

<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Проверка пользователя...</title>
    <script>
        function setBotCheckCookie() {            
            var date = new Date();
            date.setTime(date.getTime() + (365 * 24 * 60 * 60 * 1000));
            var expires = "; expires=" + date.toUTCString();
            document.cookie = "botcheck=1" + expires + "; path=/";                        
            window.location.href = window.location.href;
        }
    </script>
</head>
<body>
    <h1>Подтвердите что вы не бот</h1>
    <button onclick="setBotCheckCookie()">Я не бот</button>
</body>
</html>

Страница botcheck.html при нажатии на кнопку "Я не бот" выставляет куку средствами JS - такая простая проверка не пустит на сайт ботов без поддержки JS и тех кто не нажал на кнопку "Я не бот".


Выше я продемонстрировал простую настройку прокси сервера для демонстрации принципа работы. В эту логику нужно добавить проверку на http ботов, как я описал выше, анализ JS движка, возможность показа капчи и т.п. Так же значение куки нужно сделать динамическим, чтобы его нельзя было украсть.

Если нет желания разбираться в настройке всего этого

В килботе есть готовый шел скрипт, который развернет готовый сервер для проксирования трафика с блокированием http ботов по схеме что я описал выше, с интегрированной защитой KillBot от высокоуровневых JS ботов - т.е. все это можно интегрировать в своё решение, дописать свой код, кастомизировать и т.п. - т.е. все прелести АПИ доступа.

Построение уникального UserID без использования куки

Это последний пост в моём телеграмм канале: https://t.me/KillBotRus. UserID будет одинаковым вне зависимости от режима инкогнито. А один из следующих постов будет посвящен цифровой идентификации личности. Поэтому переходите в мой телеграмм канал, чтобы не пропустить этот интересный материал.

Комментарии (8)


  1. Nunter
    22.10.2024 07:02

    А смысл в этой защите? Мне надо бы отсекать ботов еще на этапе показа рекламы на ЯД, а когда он уже кликнул и денег списали то его заход на сайт мне не делает ни холодно ни горячо
    а парсить с моего сайта нечего, а монстрам типа Озона и прочих маркетплейсов это уже их забота


    1. grigoriy-melnikov Автор
      22.10.2024 07:02

      Для борьбы с ботами в Яндекс Директ, Яндекс предоставляет только один инструмент - это корректировка ставок на аудиторию. Т.е. визиты ботов нужно собрать в аудиторию, построить look-alike аудиторию и на неё сделать корректировку ставок "-100%" (минус 100 процентов). Можно это делать как с использованием сегментов метрики, так и в Яндекс Аудиториях.


  1. PaulZi
    22.10.2024 07:02

    Установка куки botcheck=1 - слишком банально. Обычно даже для обычного http-парсера все куки копируются из браузера ПОСЛЕ прохождения проверок, что уже обходит первый этап блокировки ботов. По хорошему нужно присылать на странице botcheck.html некий ключ и timestamp, который должен выполнить браузер в js и уже на основании вычисления устанавливать куку или ещё что.
    А сервер должен соответственно отсекать то что неверно.


    1. grigoriy-melnikov Автор
      22.10.2024 07:02

      Да, верно замечено, куку нужно генерировать динамически на стороне сервера и делать её зависимой от параметров времени, IP адреса и т.п. В противном случае куку можно украсть.


  1. qeeveex
    22.10.2024 07:02

    Apache2, PHP... и ссылка на телегу. Почему я не удивлён?!


  1. savostin
    22.10.2024 07:02

    Сделать это просто - достаточно, отрезолвить домен на какой ссылается IP бота.

    Так reverse dns запись "в руках злоумышленника". Сделать из своего ip google.com "достаточно просто".


    1. grigoriy-melnikov Автор
      22.10.2024 07:02

      Ревес делается на стороне сервера, т.е. днс сервера в руках админа, а не злоумышленника.


      1. savostin
        22.10.2024 07:02

        Неужели не существует админов злоумышленников и днс записей, доступных для редактирования?