BotBan Защита сайта от ботов
Попробовать
Меню
BotBan Защита сайта от ботов
Тема оформления

Подключение

Подключение PHP-модуля

Подключение PHP-модуля одной строкой: решение принимается до того, как сайт начнёт собирать страницу. Требования, установка, проверка.

Шаг 1. Скачайте модуль

Файл botban.php лежит на странице вашего сайта в личном кабинете. Положите его в папку botban/ в корне сайта.

Модуль ни от чего не зависит и работает на PHP 7.0 и выше.

Шаг 2. Подключите

Вызов должен стоять в самом начале входного файла — до любого вывода и до подключения CMS:

<?php
if (is_file(__DIR__ . '/botban/botban.php')) {
    try {
        require_once __DIR__ . '/botban/botban.php';
        BotBan::protect('bb_pk_...', 'bb_sk_...');
    } catch (\Throwable $e) {
        // Сбой модуля — сайт работает без защиты.
    }
}

Проверка файла и try — страховка: код можно вставить раньше, чем загружен сам модуль. Пока файла botban/botban.php нет на сервере или он загружен не полностью, сайт работает как обычно, просто без защиты. Кабинет выдаёт код именно в таком виде, уже с ключами вашего сайта.

Для WordPress это начало index.php в корне сайта, для Bitrix — начало bitrix/php_interface/init.php или того же корневого index.php.

Почему именно первой строкой

Модуль отдаёт ответ раньше, чем сайт начнёт формировать страницу. Бот не увидит ни контента, ни запросов к базе. Если поставить вызов позже, страница уже успеет сгенерироваться, и смысл потеряется.

Если вывод уже начался, модуль молча ничего не делает — сломать вёрстку он не может.

Шаг 3. Проверьте

Откройте сайт в браузере и загляните в журнал визитов в кабинете. Ваш визит должен там появиться в течение минуты.

Первый же корректный запрос от модуля подтверждает владение доменом: поставить модуль с верным ключом может только тот, у кого есть доступ к серверу.

Ловушка для краулеров

Невидимая ссылка, по которой человек не перейдёт никогда, а робот, собирающий все ссылки подряд, — обязательно. JS-скрипт и плагин WordPress ставят её сами. Если у вас только PHP-модуль, добавьте в подвал страниц:

<a href="/.bb-trap/x7k2p9" rel="nofollow" tabindex="-1" aria-hidden="true"
   style="position:absolute;left:-9999px;top:0;width:1px;height:1px;overflow:hidden">.</a>

и строку Disallow: /.bb-trap/ в robots.txt, чтобы честные поисковики её не трогали (они и так подтверждаются отдельно и в ловушку не попадают). Первый переход по ловушке — тяжёлая улика, второй с того же адреса — блокировка, адрес попадает в общую память нарушителей.

Статика и служебные пути

Запросы к картинкам, стилям, скриптам и шрифтам модуль не проверяет: если сайт отдаёт миниатюры через PHP, страница с тридцатью картинками иначе выглядела бы как шторм запросов от одного человека. Такие запросы не считаются ни в частоте, ни в квоте, ни в журнале. Если статику всё же нужно проверять, передайте 'check_assets' => true в параметрах protect(). Пути, которые не нужно трогать вообще (обмен с 1С, вебхуки оплаты, служебные скрипты), перечислите в 'skip_paths' => ['/bitrix/admin/1c_exchange.php'] — они не дойдут до нас совсем.

Работу внутри админки сайта — /wp-admin/…, /bitrix/admin/…, /admin/… — BotBan не проверяет и не учитывает: сотрудник, который за час сохраняет сотни товаров, не получит проверку, а его запросы не попадут ни в журнал, ни в лимит визитов. Доступ туда закрывает сама CMS. Страницы входа в админку (wp-login.php, /bitrix/admin/, адреса со словом login) проверяются как обычно: на них подбирают пароли.

На своём сервере модуль может записывать адреса заблокированных программ в файл для fail2ban — настройка 'ban_log' => '/var/log/botban/ban.log' (с версии 1.4.9, по умолчанию выключено). Как это устроено и что туда попадает — в статье «Список для файрвола и fail2ban».

Laravel Octane, RoadRunner, Swoole, FrankenPHP

Эти серверы держат приложение в памяти и обслуживают запросы одним и тем же процессом. Вызов в index.php там не работает: файл выполняется один раз при запуске воркера, а не на каждый запрос, и exit модуля остановил бы весь воркер. Для таких сайтов в модуле с версии 1.4.11 есть метод BotBan::check(). Он ничего не выводит сам: возвращает ответ, а отдаёт его уже приложение.

В Laravel это middleware. Положите botban.php в папку botban/ в корне проекта, ключи — в .env, а в config/services.php добавьте 'botban' => ['public' => env('BOTBAN_PUBLIC_KEY'), 'secret' => env('BOTBAN_SECRET_KEY')].

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class BotBanGate
{
    public function handle(Request $request, Closure $next): Response
    {
        $result = null;

        try {
            require_once base_path('botban/botban.php');

            // Под RoadRunner заголовки лежат не в массиве сервера, а отдельно.
            $server = $request->server->all();
            foreach ($request->headers->all() as $name => $values) {
                $server['HTTP_'.strtoupper(str_replace('-', '_', $name))] = implode(', ', $values);
            }
            $server['REMOTE_ADDR'] = (string) $request->ip();
            $server['REQUEST_METHOD'] = $request->getRealMethod();
            $server['REQUEST_URI'] = $request->getRequestUri();
            $server['HTTPS'] = $request->isSecure() ? 'on' : 'off';

            $result = \BotBan::check(
                (string) config('services.botban.public'),
                (string) config('services.botban.secret'),
                $server,
                $request->cookies->all(),
                [
                    'cache_dir' => storage_path('framework/botban'),
                    // Поля формы — для ловушки и повтора формы после проверки, файлы — только чтобы знать, что они есть.
                    'post' => $request->request->all(),
                    'files' => $request->files->all(),
                ],
            );
            $request->attributes->set('botban.finish', $result['finish']);
        } catch (\Throwable) {
            // Сбой модуля — сайт работает без защиты.
        }

        $response = $result !== null && $result['status'] !== null
            ? new Response($result['body'], $result['status'])
            : $next($request);

        // Set-Cookie — отдельными заголовками, остальное заменяет заголовки по умолчанию.
        foreach ($result['headers'] ?? [] as [$name, $value]) {
            $response->headers->set($name, $value, strcasecmp($name, 'Set-Cookie') !== 0);
        }

        return $response;
    }

    public function terminate(Request $request, Response $response): void
    {
        // Замер нагрузки, уборка кэша и обновление — после ответа посетителю.
        $finish = $request->attributes->get('botban.finish');

        if (is_callable($finish)) {
            $finish();
        }
    }
}

Подключите его в bootstrap/app.php строкой $middleware->append(BotBanGate::class) раньше своих глобальных middleware. Встроенные к этому месту уже отработали, поэтому $request->ip() знает настоящий адрес посетителя за прокси. А заголовки безопасности, которые ставит приложение, на страницу проверки не попадут: её скрипт встроен в саму страницу, и строгая политика CSP его бы остановила. Если приложение обслуживает несколько доменов, а защищать нужно один, проверьте $request->getHost() в начале handle().

Есть два отличия от обычного режима. Замедление в нём не применяется: воркер один на много посетителей, и усыпить его — значит задержать всех. Порядок заголовков модуль не передаёт, потому что RoadRunner собирает их в случайном порядке. Остальное работает так же: кэш, пропуск после проверки, страница блокировки с кнопкой «Я человек», замер нагрузки.

Отправка формы

Каждую отправку формы модуль с версии 1.4.12 проверяет заново, а не по запомненному решению: спамер часто открывает страницу «чистым» и потом шлёт заявки пачкой. Если отправку нужно проверить, модуль показывает страницу проверки и сам повторяет форму после неё: заявка человека не теряется, ему не нужно заполнять форму снова. Форму с файлами и фоновые запросы страницы (корзина, поиск, формы на скриптах) модуль в таком случае пропускает: пройти проверку там некому. Блокировка действует на любые отправки.

Содержимое формы модуль нам не передаёт. Он смотрит только на служебное поле ловушки, которое добавляет скрипт, и сообщает «заполнено» или «пусто».

Обновление модуля

Модуль обновляет себя сам, начиная с версии 1.2: когда сервер сообщает, что вышла версия новее, модуль после ответа посетителю скачивает новый файл с cdn.botban.ru, проверяет подпись нашим ключом (открытый ключ зашит в сам модуль), версию и синтаксис, и только потом подменяет файл атомарно, оставив копию botban.php.bak. Файл с неверной подписью не будет записан никогда. Для этого папка botban/ должна быть доступна на запись веб-серверу. Если записать файл нельзя, модуль продолжает работать на прежней версии: защита не выключается, просто новые исправления до сайта не доходят. Свежий файл всегда можно скачать со страницы сайта в кабинете и заменить руками. Отключить самообновление можно параметром 'auto_update' => false.

Обновлено 15 октября 2026

Не нашли ответа?

Напишите в поддержку из кабинета — отвечаем и дополняем документацию.

Подключить бесплатно