testcookie: Модуль NGINX для смягчения атак роботов
Установка
Вы можете установить этот модуль в любой дистрибутив на базе RHEL, включая, но не ограничиваясь:
- RedHat Enterprise Linux 7, 8, 9 и 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 и Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-testcookie
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-testcookie
Включите модуль, добавив следующее в верхнюю часть файла /etc/nginx/nginx.conf:
load_module modules/ngx_http_testcookie_access_module.so;
Этот документ описывает nginx-module-testcookie v1.28, выпущенный 19 июля 2022 года.
testcookie-nginx-module — это простой модуль для смягчения атак роботов, использующий основанный на cookie метод вызова/ответа.
Cookies для вызова могут быть установлены с использованием различных методов:
- "Set-Cookie" + 302/307 HTTP Location редирект
- "Set-Cookie" + HTML meta refresh редирект
- Пользовательский шаблон, здесь можно использовать JavaScript.
Чтобы предотвратить автоматический парсинг, значение cookie для вызова может быть зашифровано с помощью 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
Устанавливает имя cookie.
testcookie_domain
синтаксис: testcookie_domain <строка>
по умолчанию: none, устанавливается браузером
контекст: http, server, location
Устанавливает домен cookie.
testcookie_expires
синтаксис: testcookie_expires <строка>
по умолчанию: 31 Dec 2037 23:55:55 GMT
контекст: http, server, location
Устанавливает значение истечения срока действия cookie.
testcookie_path
синтаксис: testcookie_path <строка>
по умолчанию: /
контекст: http, server, location
Устанавливает путь cookie, полезно, если вы планируете использовать разные ключи для различных локаций.
testcookie_samesite
синтаксис: testcookie_samesite <строка>
по умолчанию: None
контекст: http, server, location
Устанавливает атрибут cookie, позволяет вам указать, следует ли ограничить ваш cookie контекстом первого лица или того же сайта. По умолчанию None (Cookies будут отправляться во всех контекстах, т.е. отправка кросс-домена разрешена). Принимает значения: Lax, Strict, None.
testcookie_secret
синтаксис: testcookie_secret <строка>
по умолчанию: обязательная директива конфигурации
контекст: http, server, location
Секретная строка, используемая в вычислении cookie для вызова, должна быть 32 байта или более, лучше, чтобы она была длинной, но статической, чтобы предотвратить сброс cookie для законных пользователей при каждом перезапуске сервера. Если установлено "random" - новый секрет будет генерироваться при каждом перезапуске сервера, не рекомендуется (все cookie с предыдущим ключом будут недействительными).
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 параметра, используемого для вычисления попыток установки cookie.
Если не установлено - сервер будет пытаться устанавливать cookie бесконечно.
testcookie_max_attempts
синтаксис: testcookie_max_attempts <целое число>
по умолчанию: 5
контекст: http, server, location
Устанавливает максимальное количество редиректов, прежде чем пользователь будет отправлен на резервный URL, согласно RFC1945 не может быть более 5.
Если установлено в 0 - сервер будет пытаться устанавливать cookie бесконечно (на самом деле браузер покажет страницу с ошибкой).
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 $variable;
по умолчанию: none
контекст: http, server
Устанавливает имя переменной для проверки, следует ли обойти проверку cookie. Если значение переменной установлено в 1 во время запроса - проверка cookie не будет выполнена. Может использоваться для более сложного белого списка.
testcookie_redirect_via_refresh
синтаксис: testcookie_redirect_via_refresh (on|off);
по умолчанию: off
контекст: http, server, location
Установите cookie и перенаправьте с использованием HTTP meta refresh, требуется, если используется testcookie_refresh_template.
testcookie_refresh_template
синтаксис: testcookie_refresh_template <строка>
по умолчанию: none
контекст: http, server, location
Используйте пользовательский html вместо простого HTTP meta refresh, вам нужно вручную установить cookie из шаблона. Доступны все переменные nginx и
$testcookie_nexturl - URL, на который клиент должен быть перенаправлен, если превышено значение *testcookie_fallback*
$testcookie_got - значение cookie, полученное от клиента, пусто, если cookie нет или оно не соответствует формату
$testcookie_set - правильное значение cookie, которое мы ожидаем от клиента
$testcookie_ok - пользователь прошел тест (1 - прошел, 0 - не прошел) Примечание: изменено с "yes"/"no" в v1.10
Также, если testcookie_refresh_encrypt_cookie включен, есть три дополнительные переменные:
$testcookie_enc_key - ключ шифрования (32 шестнадцатеричных цифры)
$testcookie_enc_iv - вектор инициализации шифрования (32 шестнадцатеричных цифры)
$testcookie_enc_sec - зашифрованное значение cookie (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
Закройте соединение сразу после установки cookie, нет смысла поддерживать соединения с ботами.
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 протокол после установки cookie, также влияет на $testcookie_nexturl, полезно с 3dparty SSL offload.
testcookie_refresh_encrypt_cookie
синтаксис: testcookie_refresh_encrypt_cookie (on|off);
по умолчанию: off
контекст: http, server, location
Шифрует переменную cookie, используется с testcookie_refresh_template для принудительного расшифрования на стороне клиента с помощью AES-128 CBC.
testcookie_refresh_encrypt_cookie_key
синтаксис: 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 - новый iv генерируется для каждого клиентского запроса random2 - новый iv генерируется при каждом перезапуске nginx 32 шестнадцатеричных цифры - статический iv, полезный, если вы планируете скрыть его глубоко в клиентском 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 для cookie.
testcookie_secure_flag
синтаксис: testcookie_secure_flag (on|off|$variable);
по умолчанию: on
контекст: http, server, location
Включите флаг Secure для cookie. Любое значение переменной, кроме "on", интерпретируется как False.
testcookie_port_in_redirect
синтаксис: testcookie_port_in_redirect (on|off);
по умолчанию: off
контекст: http, server, location
Укажите порт в редиректе.
Пример конфигурации
http {
#стандартная конфигурация, модуль отключен
testcookie off;
#установка имени cookie
testcookie_name BPC;
#установка секрета
testcookie_secret keepmesecret;
#установка ключа сессии
testcookie_session $remote_addr;
#установка имени аргумента
testcookie_arg ckattempt;
#установка максимального количества попыток установки cookie
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.
GitHub
Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-testcookie.