🛡️

MurKir Security

Многоуровневая система защиты от ботов и DDoS-атак на базе Redis + PoW JS Challenge

v3.8.13-optimized  ·  PHP 5.6–8.3  ·  Redis

🚀 Что это и как работает?

inline_check_lite.php — PHP-скрипт встроенной защиты от ботов, работающий на базе Redis. Подключается через auto_prepend_file или require в начале каждой страницы и выполняет многоуровневую проверку до загрузки CMS, что критически снижает нагрузку на сервер.

Ключевые возможности

🧩 JS Challenge (PoW)SHA-256
⏱️ Rate LimitingMultiwindow
🔨 Hammer ProtectionAuto
🔄 UA Rotation DetectionBotnet
🌐 rDNS-верификацияDNS
🔥 API → iptables DROPKernel

Два уровня защиты

РежимКомпонентыПринцип действияНагрузка при атакеТребования
Лёгкий Lite PHP + Redis Выдаёт ошибку 503 (Soft Ban) Средняя Обычный хостинг
PRO Hard PHP + Redis + API Полная блокировка iptables DROP (Hard Ban) Нулевая VPS / Root
💡
Преимущества PRO: При атаке в 10,000 req/sec обычный режим заставит PHP отвечать 10,000 раз ошибкой 503. PRO режим заблокирует IP на уровне ядра Linux — PHP даже не запустится.

⚙️ Архитектура обработки запроса

Запрос ──→ Quick Block Check (проверка уже заблокированных в Redis) │ ├── hammer:blocked → 502 │ ├── ua_blocked → 502 │ └── rate_blocked → 502 │ ├──→ JS Challenge Flow │ ├── Whitelist IP? → SKIP │ ├── Admin URL? → SKIP │ ├── Custom UA? → SKIP │ ├── SEO Bot? → SKIP │ ├── Static/AJAX? → SKIP │ ├── Cookie mk_verified валидна? → SKIP │ └── mode = auto → _jsc_check_anomaly() │ mode = always → CHALLENGEmode = never → SKIP │ └──→ SimpleBotProtection::protect() ├── IP Whitelist → SKIP ├── Custom UA → SKIP ├── rDNS Verification (поисковые боты) → SKIP ├── UA Rotation check → превышение → 502 + API block └── Rate Limit check → превышение → 502 + API block ═══ ПРОПУСК → легитимный посетитель видит сайт ═══

Мультисайтовая изоляция

Каждый домен получает уникальный site_id — первые 8 символов MD5 от hostname. Все Redis-ключи имеют префикс bot_protection:{site_id}:, что позволяет одному Redis обслуживать несколько сайтов без пересечения данных.

🎛️ Три режима JS Challenge $_JSC_CONFIG['mode']

🔴 always

Challenge для каждого посетителя

Каждый новый посетитель обязательно проходит JS Challenge (PoW). Пока cookie mk_verified не установлена — страница не откроется.

  • Максимальная защита
  • Ни один бот без JS не пройдёт
  • Простая логика
  • Все видят страницу проверки (1–5 сек)
  • Ухудшает UX
  • HTTP 503 влияет на SEO
  • Без JavaScript — не пройти

Когда: Сайт под DDoS-атакой, временная мера.

🟢 auto

Challenge только для подозрительных

Анализ поведения запроса, начисление баллов подозрительности. При достижении порога — challenge. Легитимные пользователи ничего не видят.

  • Легитимные юзеры не видят challenge
  • Минимальное влияние на UX и SEO
  • Интеллектуальная детекция
  • Grace-период от ложных срабатываний
  • Больше параметров для настройки
  • Продвинутый бот может пройти

Когда: Основной рабочий режим, продакшен.

⚪ never

Challenge выключен

JS Challenge никогда не показывается. Работают только: Rate Limit, UA Rotation Detection, Hammer Protection, API-блокировка.

  • Нулевое влияние на UX
  • Подходит для API-бэкендов
  • Rate Limit всё ещё защищает
  • Нет проактивной защиты
  • Боты проходят до Rate Limit
  • Медленные скраперы не ловятся

Когда: API / отладка / достаточно Rate Limit.

Сравнительная таблица режимов

Характеристикаalwaysautonever
Challenge для всех✓ Да✗ Нет✗ Нет
Challenge для подозрительных✓ Да✓ Да✗ Нет
Влияние на UX🔴 Высокое🟢 Минимальное🟢 Нулевое
Влияние на SEO🟡 Среднее🟢 Нет🟢 Нет
Защита от простых ботов🟢 Макс🟢 Высокая🟡 Средняя
Защита от продвинутых🟢 Макс🟡 Хорошая🔴 Rate Limit
Rate Limit
UA Rotation
Hammer Protection
Подходит для API~

Система scoring для режима auto

Функция _jsc_check_anomaly() анализирует каждый запрос и начисляет баллы подозрительности. Когда сумма ≥ suspicion_threshold — показывается JS Challenge.

Пустой User-Agent+2
Подозрительный UA (curl, wget…)+1
Нет Accept-Language+1
Нет Referer (если вкл.)+1
Burst-детекция (2 req / 2 сек)+3
Rate-детекция (30 req / 60 сек)+2
Запросы без cookie+2
Pending challenge99

Примеры срабатывания (порог = 3)

СценарийБаллыРезультат
Обычный браузер, первый визит0✓ Пропуск
curl без заголовков2 + 1 = 3✗ Challenge
Python requests + дефолтный UA1 + 1 = 2✓ Пропуск
Python requests + burst 5 req/sec1 + 1 + 3 = 5✗ Challenge
Scrapy с пустым UA2 + 1 + 1 = 4✗ Challenge
Бот без cookie + burst + rate3 + 2 = 5✗ Challenge

🧩 Два типа Challenge: PoW vs JS Sum

Параметр pow_enabled переключает между двумя принципиально разными типами проверки. Это не то же самое, что визуальный стиль — это разная логика верификации.

⛏️ PoW — Proof-of-Work

pow_enabled = true

Браузер вычисляет тысячи SHA-256 хешей, перебирая nonce, пока хеш не начнётся с N нулей. Аналог майнинга — вычислительно дорого.

Как работает:

Сервер → генерирует challenge_id + difficulty (N нулей) Браузер → перебирает nonce: 0, 1, 2, 3... → для каждого: hash = SHA-256(challenge_id + nonce) → если hash начинается с "000..." (N нулей) → НАЙДЕНО! Браузер → отправляет: { nonce, hash } Сервер → проверяет: SHA-256(challenge_id + nonce) == hash? → hash начинается с N нулей? → Верифицирован!
  • Максимальная защита — вычислительно дорого для ботов
  • Даже headless-браузер тратит CPU
  • Показывает прогресс: хеши/сек, время
  • Автоматический fallback на Sum если нет crypto.subtle
  • Нагружает CPU пользователя (1–5 сек)
  • Требует Web Crypto API (crypto.subtle)
  • Таймаут 120 сек на сервере
  • На слабых устройствах может быть медленно

🧮 Sum — JS Challenge (лёгкий)

pow_enabled = false

Сервер отправляет 5 случайных чисел (10–99). Браузер просто складывает их и отправляет сумму. Лёгкий, мгновенный.

Как работает:

Сервер → генерирует 5 чисел: [42, 78, 15, 93, 31] → target = SHA-256(id + timestamp + 259 + secret_key) Браузер → sum = 42 + 78 + 15 + 93 + 31 = 259 → отправляет: { answer: 259 } Сервер → проверяет ответ → Верифицирован!
  • Мгновенно — ноль нагрузки на CPU
  • Не требует Web Crypto API
  • Работает на любых устройствах
  • Таймаут 300 сек на сервере (больше запас)
  • Слабая защита — просто проверяет наличие JS
  • Headless-браузер (Puppeteer) пройдёт мгновенно
  • Бот с JS-движком обходит легко
  • Нет вычислительной «стоимости» для атакующего

Детальное сравнение

Характеристика⛏️ PoW (pow_enabled=true)🧮 Sum (pow_enabled=false)
АлгоритмBrute-force SHA-256 с поиском nonceСложение 5 чисел
Нагрузка на CPUСредняя (1–5 сек)Нулевая (мгновенно)
Требует crypto.subtleДа (с fallback на Sum)Нет
Время решения (difficulty=3)~1–3 сек~мгновенно
Время решения (difficulty=5)~10–60 сек
Макс. время на сервере120 сек300 сек
Защита от curl/wget✓ Полная✓ Полная
Защита от Python requests✓ Полная✓ Полная
Защита от headless-браузеров✓ Замедляет (CPU cost)✗ Проходят мгновенно
Защита от DDoS ботнета✓ Каждый бот тратит CPU~ Только факт JS
Влияние на мобильныеСлабые устройства — медленнееБез проблем
Показывает статистикуХеши/сек, время, прогрессНет

Уровни сложности PoW (pow_difficulty)

Количество ведущих нулей в SHA-256 хеше. Каждый +1 увеличивает сложность примерно в ×16:

difficulty = 2
Ультра-лёгкий
~0.1 сек
difficulty = 3
Рекомендуемый
~1–3 сек
difficulty = 4
Средний
~5–15 сек
difficulty = 5
Тяжёлый
~30–60 сек
💡
Fallback: Если браузер не поддерживает crypto.subtle (HTTP без HTTPS, очень старый браузер), PoW-challenge автоматически переключается на Sum-задачу. В PoW-ответе сервера всегда есть поле fallback с числами для суммирования.

Два визуальных стиля (pow_style)

Независимо от типа challenge (PoW или Sum), можно выбрать внешний вид страницы проверки:

☁️ cloudflare

pow_style = 'cloudflare'

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

Визуал:
• Белый фон с центрированным контентом
• Оранжево-красный градиентный спиннер
• Прогресс-бар с оранжевым градиентом
• SVG-анимация галочки при успехе
• Текст: «Проверяем ваш браузер перед входом на сайт»

Когда: Для сайтов где Cloudflare — привычный вид. Пользователи не пугаются.

📋 smf

pow_style = 'smf'

Страница в стиле форума SMF 2.0. Тёмно-синяя шапка, серые панели, классический форумный дизайн.

Визуал:
• Серый фон #e5e5e8 в стиле SMF
• Шапка с градиентом #315d7d → #1e5380
• Заголовок: «🛡️ Система безопасности»
• Прогресс-бар с голубым градиентом
• Футер: «Powered by MurKir Security»

Когда: Для форумов SMF, DLE, или когда нужен «нейтральный» вид системы защиты.

Матрица всех комбинаций

Тип + СтильКонфигурацияРезультатРекомендация
PoW + Cloudflare pow_enabled: true
pow_style: 'cloudflare'
Страница в стиле CF, SHA-256 brute-force, прогресс хешей Для обычных сайтов
PoW + SMF pow_enabled: true
pow_style: 'smf'
Страница в стиле форума, SHA-256 brute-force, прогресс хешей Для форумов SMF/DLE
Sum + Cloudflare pow_enabled: false
pow_style: 'cloudflare'
Страница в стиле CF, мгновенное сложение чисел Лёгкая проверка
Sum + SMF pow_enabled: false
pow_style: 'smf'
Страница в стиле форума, мгновенное сложение чисел Лёгкая проверка

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

🔒 Максимальная защита (рекомендуемый)

$_JSC_CONFIG = array(
    'enabled'        => true,
    'secret_key'     => 'ваш_секретный_ключ',
    'cookie_name'    => 'mk_verified',
    'token_lifetime' => 129600,
    'pow_enabled'    => true,          // PoW — тяжёлый challenge
    'pow_difficulty'  => 3,             // 3 нуля — ~1-3 сек
    'pow_timeout'    => 60,            // таймаут 60 сек
    'pow_style'      => 'cloudflare',  // стиль Cloudflare
    'mode'           => 'auto',
);

⚡ Быстрая проверка (минимальное влияние на UX)

$_JSC_CONFIG = array(
    'enabled'        => true,
    'secret_key'     => 'ваш_секретный_ключ',
    'cookie_name'    => 'mk_verified',
    'token_lifetime' => 129600,
    'pow_enabled'    => false,         // Sum — мгновенный challenge
    'pow_style'      => 'smf',         // стиль форума
    'mode'           => 'auto',
);

🚨 Под DDoS-атакой (тяжёлый PoW для всех)

$_JSC_CONFIG = array(
    'enabled'        => true,
    'secret_key'     => 'ваш_секретный_ключ',
    'cookie_name'    => 'mk_verified',
    'token_lifetime' => 129600,
    'pow_enabled'    => true,
    'pow_difficulty'  => 5,             // 5 нулей — ~30-60 сек!
    'pow_timeout'    => 120,           // увеличен таймаут
    'pow_style'      => 'cloudflare',
    'mode'           => 'always',       // для ВСЕХ посетителей
);

📋 Все настраиваемые параметры

$CUSTOM_USER_AGENTS Whitelist

Подстроки User-Agent, пропускаемые без JS Challenge и Rate Limit. Для собственных сервисов, мониторинга, cron.

$CUSTOM_USER_AGENTS = array('sitecheckerbotcrawler', 'botprotection', 'murkir-cleanup');

Сравнение регистронезависимое. Достаточно частичного совпадения. Визиты логируются в Redis как CustomUA.

$ADMIN_IP_WHITELIST IP Whitelist

IP администраторов — полностью исключены из всех проверок: без Challenge, без Rate Limit, без Hammer.

$ADMIN_IP_WHITELIST = array(
    '::1', '127.0.0.1',
    '185.109.48.79',
    '2a03:3f40:2:e:0:4:0:2',
);

Поддерживает CIDR (192.168.0.0/24). Без маски — /32 (IPv4) или /128 (IPv6).

$ADMIN_URL_WHITELIST URL Whitelist

Параметр
Тип
Описание
$ADMIN_URL_WHITELIST_ENABLED
bool
Включить/выключить проверку URL
$ADMIN_URL_WHITELIST
array
URL-пути, пропускаемые без Rate Limit и JS Challenge. Частичное совпадение, регистронезависимо.

Настройки AJAX Rate Limit

Параметр
Умолч.
Описание
$AJAX_SKIP_RATE_LIMIT
false
Полностью пропускать Rate Limit для AJAX
$AJAX_RATE_LIMIT_MULTIPLIER
3.0
Множитель лимитов для AJAX (>1.0 = больше разрешённых запросов)

AJAX определяется по: X-Requested-With: XMLHttpRequest, Content-Type: application/json, Accept: application/json, X-JSC-Response.

$_JSC_CONFIG Challenge

Параметр
Умолч.
Описание
enabled
true
Главный выключатель JS Challenge
secret_key
ОБЯЗАТЕЛЬНО СМЕНИТЬ! Секретный ключ для токенов и cookie
cookie_name
mk_verified
Имя cookie верификации
token_lifetime
129600
Время жизни cookie (секунды, 36 часов)
pow_enabled
true
Использовать PoW вместо математической задачи
pow_difficulty
3
Сложность PoW (ведущие нули SHA-256). 3 = быстро, 4 = среднее, 5+ = тяжело
pow_timeout
60
Таймаут решения PoW (секунды)
pow_style
smf
Визуальный стиль: smf (стиль форума) или cloudflare (Cloudflare-like)
mode
auto
Режим: auto / always / never

$_JSC_AUTO_CONFIG Auto Mode

Параметр
Умолч.
Описание
no_cookie_threshold
9999
Запросы без cookie за окно для срабатывания (9999 = отключено)
no_cookie_window
30
Окно подсчёта без cookie (сек)
burst_threshold
2
Запросов за burst_window для burst-детекции
burst_window
2
Окно burst-детекции (сек)
rate_threshold
30
Запросов за 60 сек для rate-детекции
check_empty_ua
true
Пустой User-Agent → +2 балла
check_suspicious_ua
true
curl/wget/python/scrapy → +1 балл
check_no_referer
false
Нет Referer → +1 балл (по умолчанию выкл.)
check_no_accept_language
true
Нет Accept-Language → +1 балл
suspicion_threshold
3
Порог суммы баллов для показа challenge
grace_requests
2
Запросов без проверки (с cookie)
grace_requests_no_cookie
2
Запросов без проверки (без cookie)
log_triggers
true
Логировать срабатывания в error_log

$_HAMMER_PROTECTION Anti-Hammer

Блокировка IP, которые «долбят» challenge-страницы или 502-страницы, не решая их.

Параметр
Умолч.
Описание
enabled
true
Включить защиту
challenge_threshold
3
Показов challenge за окно для блокировки
challenge_window
60
Окно подсчёта challenge (сек)
blocked_threshold
5
Показов 502 за окно для блокировки через API
blocked_window
30
Окно подсчёта 502 (сек)
api_block_enabled
true
Отправлять IP на API для iptables-блокировки

$_API_CONFIG API

Параметр
Умолч.
Описание
enabled
true
Включить интеграцию с API
url
URL endpoint API блокировки
api_key
Ключ авторизации API
method
POST
HTTP-метод (POST или GET)
timeout
5
Таймаут cURL (сек)
retry_on_failure
2
Повторных попыток при ошибке
verify_ssl
true
Проверять SSL-сертификат
block_on_api
true
Отправлять блокировку на внешний API (iptables)
block_on_redis
true
Сохранять блокировку в Redis

Rate Limit SimpleBotProtection

Параметр
Умолч.
Описание
max_requests_per_minute
30
Лимит запросов в минуту
max_requests_per_5min
100
Лимит за 5 минут
max_requests_per_hour
500
Лимит в час
burst_threshold
10
Лимит за 10 секунд
block_duration
900
Длительность блокировки (сек = 15 мин)
cookie_multiplier
2.0
Множитель для пользователей с cookie (×2)
js_verified_multiplier
3.0
Множитель для прошедших Challenge (×3)

UA Rotation Detection Botnet

Параметр
Умолч.
Описание
max_unique_ua_per_5min
10
Макс. уникальных UA за 5 мин с одного IP
max_unique_ua_per_hour
20
Макс. уникальных UA за час с одного IP
block_duration
7200
Блокировка (сек = 2 часа)

10+ разных UA с одного IP за 5 минут — типичный признак ботнета.

rDNS-верификация DNS

Параметр
Умолч.
Описание
cache_ttl
3600
Кеш результатов rDNS (1 час)
rate_limit_per_minute
10
Макс. DNS-запросов в минуту

Логирование поисковых ботов

Параметр
Умолч.
Описание
file
/var/log/search_engines.log
Путь к файлу лога
max_size
1048576
Макс. размер файла (1 МБ)
keep_backups
3
Количество ротируемых бэкапов
redis_log_max
500
Макс. записей в Redis-логе

🔋 Настройка Redis Обязательно

Без Redis защита работать не будет. Redis хранит счётчики, баны и кеш.

1. Установка

# Ubuntu / Debian:
sudo apt update && sudo apt install redis-server

# CentOS / AlmaLinux:
sudo yum install redis

2. Конфигурация памяти

Откройте: sudo nano /etc/redis/redis.conf

# Ограничение памяти (10mb для малых, 50-100mb для крупных)
maxmemory 10mb

# Политика удаления: старые ключи при переполнении
maxmemory-policy allkeys-lru

# Точность проверки
maxmemory-samples 10

После изменений: sudo systemctl restart redis

3. Расчёт памяти

Тип сайтаРекомендацияПримерный объём
Обычный сайт10mb~40k записей
Крупный портал50mb~200k записей
High Load / DDoS256mb+1M+ записей

📂 Файлы системы

Загрузите все файлы в папку /js_challenge_lite/.

1. inline_check_lite.php Ядро

Основной скрипт. Работает автономно. Если API выключен — блокирует через PHP (503). Если включен — шлёт команды в API для iptables.

2. redis-bot_admin.php Админка

Панель управления. Логин/Пароль: admin / ваш_пароль (Смените!).

3. iptables.php API Бан (PRO)

Скрипт-мост между PHP и Linux iptables. Принимает команды «Забанить / Разбанить».

4. cleanup.php Очистка (PRO)

Запускается по CRON. Проверяет Redis на истёкшие баны и даёт команду в iptables разблокировать IP.

5. settings.php Конфиг

Настройки API (ключи, лимиты балансировки нагрузки).

🛠️ Подключение к сайту

Способ А: Через index.php (простой)

Вставьте в самый верх index.php:

require_once $_SERVER['DOCUMENT_ROOT'] . '/js_challenge_lite/inline_check_lite.php';

Способ Б: Через PHP-FPM (рекомендуемый)

В конфиг пула (/etc/php/8.3/fpm/pool.d/www.conf):

php_admin_value[auto_prepend_file] = "/path/to/js_challenge_lite/inline_check_lite.php"

Способ В: Через nginx

location ~ \.php$ {
    fastcgi_param PHP_VALUE "auto_prepend_file=/path/to/inline_check_lite.php";
    fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
}

Способ Г: Через php.ini

auto_prepend_file = /path/to/inline_check_lite.php

🔥 PRO режим: Настройка Sudoers

⚠️
Только для PRO (Hard Ban). Для обычного режима пропустите этот шаг и оставьте 'api_enabled' => false.

1. Создайте файл правил

sudo nano /etc/sudoers.d/iptables

2. Вставьте настройки

Полный блок: IPv4, IPv6, Nginx Reload, ACCEPT:

# Правила для IPv4
Cmnd_Alias IPTABLES_IPV4 = /sbin/iptables -C INPUT -s * -p tcp --dport 80 -j DROP, \
                           /sbin/iptables -I INPUT -s * -p tcp --dport 80 -j DROP, \
                           /sbin/iptables -I INPUT -s * -p tcp --dport 443 -j DROP, \
                           /sbin/iptables -D INPUT -s * -p tcp --dport 80 -j DROP, \
                           /sbin/iptables -D INPUT -s * -p tcp --dport 443 -j DROP, \
                           # ... (полные пути /sbin, /usr/sbin, /bin)

# Правила для IPv6
Cmnd_Alias IPTABLES_IPV6 = /sbin/ip6tables -C INPUT -s * -p tcp --dport 80 -j DROP, \
                           # ... (аналогично IPv4)

# Информационные команды
Cmnd_Alias IPTABLES_INFO = /sbin/iptables -S INPUT, \
                          /sbin/iptables -L INPUT -n -v, \
                          # ...

# Сохранение правил
Cmnd_Alias IPTABLES_SAVE = /bin/sh -c *iptables-save*rules.v4*, \
                          /bin/sh -c *ip6tables-save*rules.v6*, \
                          # ...

# Правила ACCEPT для IPv4/IPv6
Cmnd_Alias IPTABLES_IPV4_ACCEPT = /sbin/iptables -A INPUT -p tcp -s * --dport * -j ACCEPT, \
                                  # ...

# Перезагрузка Nginx
Cmnd_Alias NGINX_RELOAD = /usr/sbin/nginx -s reload, \
                         /bin/systemctl reload nginx

# Назначаем права (раскомментируйте нужную строку):
nginx ALL=(ALL) NOPASSWD: IPTABLES_IPV4, IPTABLES_IPV6, IPTABLES_INFO, \
    IPTABLES_MISC, IPTABLES_SAVE, NGINX_RELOAD, IPTABLES_IPV4_ACCEPT, \
    IPTABLES_IPV6_ACCEPT, IPTABLES_FULL_INFO
#www-data ALL=(ALL) NOPASSWD: ...
#apache ALL=(ALL) NOPASSWD: ...

3. Права (КРИТИЧЕСКИ ВАЖНО)

sudo chown root:root /etc/sudoers.d/iptables
sudo chmod 0440 /etc/sudoers.d/iptables

4. Проверка синтаксиса

sudo visudo -c
Должно написать: /etc/sudoers.d/iptables: parsed OK

5. Включите API в конфигах

В inline_check_lite.php, redis-bot_admin.php и cleanup.php установите 'enabled' => true и укажите api_key.

🔄 Авто-очистка (CRON)

⚠️
В PRO режиме (с API) это обязательно. Иначе баны в iptables останутся навечно.

1. Откройте cron: crontab -e

2. Добавьте строку:

*/3 * * * * php /path/to/js_challenge_lite/cleanup.php > /dev/null 2>&1

Скрипт запускается каждые 3 минуты, проверяет Redis на истёкшие баны и разблокирует IP в iptables.

🗄️ Redis: используемые ключи

Все ключи имеют префикс bot_protection:{site_id}:, где site_id — первые 8 символов MD5 от hostname.

КлючTTLОписание
rate:{user_hash}3600Данные rate limit пользователя
blocked:{user_hash}900Блокировка по rate limit
blocked:hammer:{ip}3600Блокировка по hammer
blocked:no_cookie:{ip}3600Блокировка за атаку без cookie
ua_blocked:{ip}7200Блокировка за ротацию UA
ua:{ip}3600История UA с IP
jsc_auto:pending:{ip}300Ожидающий challenge
jsc_auto:requests:{id}120Счётчик запросов для auto-mode
jsc_stats:*7 днейСтатистика JS Challenge
search_stats:*7–30 днейСтатистика поисковых ботов
ip_whitelist:{ip}86400Кеш проверки IP whitelist
hammer_stats:*7 днейСтатистика hammer-атак
rdns:cache:{ip_hash}3600Кеш rDNS-верификации
search_logПоследние 500 визитов ботов

🔐 Безопасность

Обязательно сменить!

🚨
1. secret_key — главный секрет для токенов. Уникальный для каждого сайта!
2. api_key — ключ доступа к API блокировки
3. $ADMIN_IP_WHITELIST — ваши реальные IP-адреса

Как работает токен верификации

Cookie mk_verified содержит SHA-256(IP + дата + secret_key). Проверяется за текущий день и 2 предыдущих — cookie валидна ~3 дня даже без учёта token_lifetime.

Идентификация пользователя

User Identifier = cookie_uid + SHA-256(UA + Accept-Language). Смена UA у того же пользователя создаёт новый идентификатор и новый rate limit.

Требования к серверу

КомпонентТребованиеНазначение
PHP5.6 – 8.3Основной скрипт
RedisСервер + phpredisХранение данных (DB #1)
cURLPHP extensionAPI-блокировка
DNSgethostbyaddrrDNS-верификация
random_bytesPHP 7.0+ или polyfillГенерация токенов