Перейти к содержанию

testcookie: Модуль защиты от ботов testcookie для NGINX

Установка на Debian/Ubuntu

Эти документы относятся к APT пакету nginx-module-testcookie, предоставляемому репозиторием GetPageSpeed Extras.

  1. Настройте APT репозиторий, как описано в настройке APT репозитория.
  2. Установите модуль:
sudo apt-get update
sudo apt-get install nginx-module-testcookie
Показать дистрибутивы и архитектуры
| Дистрибутив | Версия            | Компонент  | Архитектуры   |
|-------------|-------------------|------------|----------------|
| debian      | bookworm          | main       | amd64, arm64   |
| debian      | bookworm-mainline | main       | amd64, arm64   |
| debian      | trixie            | main       | amd64, arm64   |
| debian      | trixie-mainline   | main       | amd64, arm64   |
| ubuntu      | focal             | main       | amd64, arm64   |
| ubuntu      | focal-mainline    | main       | amd64, arm64   |
| ubuntu      | jammy             | main       | amd64, arm64   |
| ubuntu      | jammy-mainline    | main       | amd64, arm64   |
| ubuntu      | noble             | main       | amd64, arm64   |
| ubuntu      | noble-mainline    | main       | amd64, arm64   |

testcookie-nginx-module — это простой модуль защиты от ботов, использующий куки с вызовом/ответом.

Куки-задания могут быть установлены с использованием различных методов:

  • "Set-Cookie" + HTTP перенаправление по Location 302/307
  • "Set-Cookie" + HTML мета-обновление
  • Пользовательский шаблон, здесь может использоваться JavaScript.

Чтобы предотвратить автоматический анализ, значение куки-задания может быть зашифровано с помощью AES-128 в режиме CBC с использованием пользовательского/случайного ключа и iv, а затем расшифровано на стороне клиента с помощью JavaScript.

Директивы

testcookie

синтаксис: testcookie (on|off|var);

по умолчанию: off

контекст: http, server, location, if

on - Включить модуль

off - Отключить модуль

var - Не перехватывать запросы, только установить переменные модуля.

testcookie_name

синтаксис: testcookie_name <строка>

по умолчанию: TCK

контекст: http, server, location

Устанавливает имя куки.

testcookie_domain

синтаксис: testcookie_domain <строка>

по умолчанию: none, устанавливается браузером

контекст: http, server, location

Устанавливает домен куки.

testcookie_expires

синтаксис: testcookie_expires <строка>

по умолчанию: 31 Dec 2037 23:55:55 GMT

контекст: http, server, location

Устанавливает значение истечения срока действия куки.

testcookie_path

синтаксис: testcookie_path <строка>

по умолчанию: /

контекст: http, server, location

Устанавливает путь куки, полезно, если вы планируете использовать разные ключи для различных локаций.

testcookie_samesite

синтаксис: testcookie_samesite <строка>

по умолчанию: None

контекст: http, server, location

Устанавливает атрибут куки, позволяет вам объявить, должен ли ваш куки быть ограничен контекстом первой стороны или тем же сайтом. По умолчанию None (куки будут отправляться во всех контекстах, т.е. отправка кросс-домена разрешена). Принимает значения: Lax, Strict, None.

testcookie_secret

синтаксис: testcookie_secret <строка>

по умолчанию: обязательная директива конфигурации

контекст: http, server, location

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

testcookie_session

синтаксис: testcookie_session <переменная>

по умолчанию: обязательная директива конфигурации

контекст: http, server, location

Устанавливает входные данные для функции генерации вызовов, * $remote_addr - IP-адрес клиентов будет использоваться как уникальный идентификатор пользователя * $remote_addr$http_user_agent - IP-адрес клиентов + User-Agent

testcookie_arg

синтаксис: testcookie_arg <строка>

по умолчанию: none

контекст: http, server, location

Устанавливает имя GET-параметра, используемое для вычисления попыток установки куки,

Если не установлено - сервер будет пытаться установить куки бесконечно.

testcookie_max_attempts

синтаксис: testcookie_max_attempts <целое число>

по умолчанию: 5

контекст: http, server, location

Устанавливает максимальное количество перенаправлений, прежде чем пользователь будет перенаправлен на запасной URL, согласно RFC1945, не может быть более 5.

Если установлено на 0 - сервер будет пытаться установить куки бесконечно (на самом деле, браузер покажет страницу с ошибкой).

testcookie_p3p

синтаксис: testcookie_p3p <строка>

по умолчанию: none

контекст: http, server, location

Устанавливает политику P3P.

testcookie_fallback

синтаксис: testcookie_fallback <скрипт>

по умолчанию: none

контекст: http, server, location

Устанавливает запасной URL, на который пользователи будут перенаправлены после достижения максимального количества попыток, указанного директивой testcookie_max_attempts. Здесь можно использовать переменные скрипта Nginx. Если не установлено - клиент получит 403 после достижения максимального количества попыток.

testcookie_whitelist

синтаксис: testcookie_whitelist <список сетей>

по умолчанию: none

контекст: http, server

Устанавливает сети, для которых тестирование не будет использоваться, добавьте сюда сети поисковых систем. В настоящее время только IPv4 CIDR.

testcookie_pass

синтаксис: testcookie_pass $переменная;

по умолчанию: none

контекст: http, server

Устанавливает имя переменной для проверки, должен ли быть пропущен контроль куки. Если значение переменной установлено на 1 во время запроса - проверка куки не будет выполнена. Может использоваться для более сложного белого списка.

testcookie_redirect_via_refresh

синтаксис: testcookie_redirect_via_refresh (on|off);

по умолчанию: off

контекст: http, server, location

Установите куки и перенаправьте с использованием HTTP мета-обновления, требуется, если используется testcookie_refresh_template.

testcookie_refresh_template

синтаксис: testcookie_refresh_template <строка>

по умолчанию: none

контекст: http, server, location

Используйте пользовательский html вместо простого HTTP мета-обновления, вам нужно будет установить куки вручную из шаблона Доступны все переменные nginx и

$testcookie_nexturl - URL, на который клиент должен быть перенаправлен, если превышено *testcookie_max_attempts*, это значение будет здесь
$testcookie_got - значение куки, полученное от клиента, пусто, если куки нет или оно не соответствует формату
$testcookie_set - правильное значение куки, которое мы ожидаем от клиента
$testcookie_ok - пользователь прошел тест (1 - прошел, 0 - не прошел) Примечание: изменено с "yes"/"no" в v1.10

также, если testcookie_refresh_encrypt_cookie включено, есть три дополнительные переменные:

$testcookie_enc_key - ключ шифрования (32 шестнадцатичных знака)
$testcookie_enc_iv - вектор инициализации шифрования (32 шестнадцатичных знака)
$testcookie_enc_sec - зашифрованное значение куки (32 шестнадцатичных знака)

testcookie_refresh_status

синтаксис: testcookie_refresh_status <код>

по умолчанию: 200

контекст: http, server, location

Используйте пользовательский код состояния HTTP при обслуживании html.

testcookie_deny_keepalive

синтаксис: testcookie_deny_keepalive (on|off);

по умолчанию: off

контекст: http, server, location

Закрыть соединение сразу после установки куки, нет причин поддерживать соединения с ботами.

testcookie_get_only

синтаксис: testcookie_get_only (on|off);

по умолчанию: off

контекст: http, server, location

Обрабатывайте только GET-запросы, POST-запросы будут пропущены.

testcookie_https_location

синтаксис: testcookie_https_location (on|off);

по умолчанию: off

контекст: http, server, location

Перенаправить клиента на протокол https после установки куки, также влияет на $testcookie_nexturl, полезно с 3dparty SSL offload.

синтаксис: testcookie_refresh_encrypt_cookie (on|off);

по умолчанию: off

контекст: http, server, location

Шифруйте переменную куки, используемую с testcookie_refresh_template, чтобы принудить расшифровку на стороне клиента с помощью AES-128 CBC.

синтаксис: testcookie_refresh_encrypt_cookie_key <32 шестнадцатичных знаков|random>

по умолчанию: обязательная директива, если шифрование включено

контекст: http, server, location

Устанавливает ключ шифрования.

Возможные значения:

random - новый ключ создается каждый раз при перезапуске nginx
32 шестнадцатичных знака - статический ключ, полезный, если вы планируете скрыть его глубоко в клиентском JavaScript.

testcookie_refresh_encrypt_iv

синтаксис: testcookie_refresh_encrypt_iv <32 шестнадцатичных знаков|random|random2>

по умолчанию: random

контекст: http, server, location

Устанавливает вектор инициализации шифрования.

Возможные значения: random - новый вектор инициализации создается для каждого клиентского запроса random2 - новый вектор инициализации создается при каждом перезапуске nginx 32 шестнадцатичных знака - статический вектор инициализации, полезный, если вы планируете скрыть его глубоко в клиентском JavaScript

testcookie_internal

синтаксис: testcookie_internal (on|off);

по умолчанию: off

контекст: http, server, location

Включить проверку testcookie для внутренних перенаправлений (по умолчанию отключена для оптимизации!), полезно для такого типа конфигураций:

rewrite ^/(.*)$ /index.php?$1 last;

testcookie_httponly_flag

синтаксис: testcookie_httponly_flag (on|off);

по умолчанию: off

контекст: http, server, location

Включите флаг HttpOnly для куки.

testcookie_secure_flag

синтаксис: testcookie_secure_flag (on|off|$variable);

по умолчанию: on

контекст: http, server, location

Включите флаг Secure для куки. Любое значение переменной, кроме "on", интерпретируется как False.

testcookie_port_in_redirect

синтаксис: testcookie_port_in_redirect (on|off);

по умолчанию: off

контекст: http, server, location

Показать порт в перенаправлении.

Пример конфигурации

http {
    #стандартная конфигурация, модуль отключен
    testcookie off;

    #установка имени куки
    testcookie_name BPC;

    #установка секрета
    testcookie_secret keepmesecret;

    #установка ключа сессии
    testcookie_session $remote_addr;

    #установка имени аргумента
    testcookie_arg ckattempt;

    #установка максимального количества попыток установки куки
    testcookie_max_attempts 3;

    #установка p3p политики
    testcookie_p3p 'CP="CUR ADM OUR NOR STA NID", policyref="/w3c/p3p.xml"';

    #установка запасного URL
    testcookie_fallback http://google.com/cookies.html?backurl=http://$host$request_uri;

    #настройка белого списка
    testcookie_whitelist {
        8.8.8.8/32;
    }


    #установка перенаправления с помощью html-кода
    testcookie_redirect_via_refresh on;

    #включение шифрования
    testcookie_refresh_encrypt_cookie on;

    #установка ключа шифрования
    testcookie_refresh_encrypt_cookie_key deadbeefdeadbeefdeadbeefdeadbeef;

    #установка вектора инициализации шифрования
    testcookie_refresh_encrypt_cookie_iv deadbeefdeadbeefdeadbeefdeadbeef;

    #установка шаблона ответа
    testcookie_refresh_template '<html><body>setting cookie...<script type=\"text/javascript\" src=\"/aes.min.js\" ></script><script>function toNumbers(d){var e=[];d.replace(/(..)/g,function(d){e.push(parseInt(d,16))});return e}function toHex(){for(var d=[],d=1==arguments.length&&arguments[0].constructor==Array?arguments[0]:arguments,e="",f=0;f<d.length;f++)e+=(16>d[f]?"0":"")+d[f].toString(16);return e.toLowerCase()}var a=toNumbers("$testcookie_enc_key"),b=toNumbers("$testcookie_enc_iv"),c=toNumbers("$testcookie_enc_set");document.cookie="BPC="+toHex(slowAES.decrypt(c,2,a,b))+"; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/";location.href="$testcookie_nexturl";</script></body></html>';

    server {
        listen 80;
        server_name test.com;


        location = /aes.min.js {
            gzip  on;
            gzip_min_length 1000;
            gzip_types      text/plain;
            root /var/www/public_html;
        }

        location = /w3c/p3p.xml {
            root /var/www/public_html;
        }

        location / {
            #включите модуль для конкретной локации
            testcookie on;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:80;
        }
    }
}

Смотрите больше примеров в директории "docs" проекта.

Тестовый комплект

Этот модуль поставляется с тестовым комплектом на основе Perl. Благодарим за использование модуля Test::Nginx в мире Perl.

Исходники

Доступны на github по адресу kyprizel/testcookie-nginx-module.