AWAFAWAF

Для разработчиков

Как устроен исходный репозиторий Antibot/AWAF githubniko/antibot: точки входа, модульные проверки, списки, капча, блокировка, логи и безопасное расширение.

Назначение репозитория

Antibot/AWAF из https://github.com/githubniko/antibot — это PHP-защита, которую подключают перед основным приложением сайта. Она проверяет посетителя по конфигурации, спискам и браузерным сигналам, затем принимает одно из трех решений: пропустить, показать проверочную страницу с капчей или заблокировать.

Рабочий код защиты подключается на защищаемом сайте, обычно как /antibot/index.php.

index.php
xhr.php
includes/
includes/Checks/
includes/Utility/
lists/
templates/
skins/
js/
images/README/
VERSION

Точки входа

  • index.php — основной вход защиты. Он не запускает защиту в CLI, пропускает xhr и favicon, подключает includes/autoload.php, создает WAFSystem::getInstance() и вызывает run(), если защита включена.
  • xhr.php — JSON/XHR вход для проверочной страницы. Он стартует session, запрещает кэширование, обслуживает загрузку captcha skin, запускает вторую фазу проверок через isAllowed2() и устанавливает marker после успешной капчи.
  • .htaccess и пример из README позволяют подключать защиту прямым require_once в защищаемом сайте или через auto_prepend_file.

Центральная сборка

Главный объект находится в includes/WAFSystem.class.php. Это singleton, который собирает зависимости и checker-модули:

Autoload в includes/autoload.php рекурсивно подключает PHP-файлы из includes/, сортируя файлы по имени. При добавлении нового класса нельзя полагаться на Composer или namespace autoload: файл должен быть совместим с этим простым загрузчиком.

  • Config читает и дополняет config.ini, создает cache/ и хранит пути BasePath, CachePath, DOCUMENT_ROOT, ANTIBOT_PATH.
  • Profile нормализует IP, HTTP protocol, User-Agent, Referer, Request URI, язык, RayID и RayIDSecret.
  • Logger, Marker, Template, GrayList и session storage используются всеми проверками.
  • includes/Checks/* подключаются как независимые модули: IP, ASN, URL, Referer, User-Agent, Tor, FingerPrint, HTTP, Mobile, FPS, IFrame и поисковые боты.

Поток проверки

Первая фаза выполняется до показа проверочной страницы:

Вторая фаза запускается из xhr.php, когда JS на проверочной странице отправляет func: "checks":

  • Если marker уже валиден, посетитель сразу пропускается.
  • Сначала выполняются быстрые allow-правила: whitelist_ip, whitelist ASN и индексирующие роботы.
  • Затем идут block-правила: IPv6 при BLOCK, HTTP protocol, blacklist_ip, ASN block, Tor, URL block и User-Agent block.
  • URL, User-Agent и Referer могут пропустить запрос без капчи, если соответствующие allow-правила включены.
  • Если ни одно правило не пропустило посетителя, Template->showVerificationPage() отдает templates/template.inc.php.
  • js/api.js собирает fingerprint, FPS, screen metrics, pixel ratio, referrer, location, признаки BAS/старого Mozilla engine, iframe state и другие браузерные данные.
  • Api принимает только POST JSON, ограничивает размер входа, требует CSRF token и добавляет плохие запросы в graylist.
  • isAllowed2() блокирует отсутствующие обязательные сигналы, BAS/старый driver, mobile/FPS/Fingerprint/IFrame/HTTP/ASN/Tor по action BLOCK или возвращает captcha по action CAPTCHA.
  • Если все фильтры пройдены, Marker->set() ставит метку и API возвращает allow.

Модульность проверок

Большинство проверок живет в отдельных классах под includes/Checks/. У многих модулей есть общая схема: enabled, action, путь к списку в lists/ и метод Checking() или isListed().

При расширении системы лучше добавлять новый checker как отдельный класс и явно подключать его в initializeComponents() и нужной фазе isAllowed() или isAllowed2(). Не смешивайте новую проверку с существующим классом, если она имеет отдельные настройки, список или action.

  • WhiteListIP и BlackListIP наследуют ListBase и умеют работать с IPv4, IPv6, CIDR и диапазонами через сетевые utility-классы.
  • RequestChecker, RefererChecker и UserAgentChecker используют списки регулярных/строковых правил для URL, referer и User-Agent.
  • ASNChecker кэширует ASN-сети в SQLite базе под cache/ и обновляет данные по updateTime.
  • TorChecker загружает и кэширует список Tor exit nodes.
  • FingerPrint сверяет браузерный fingerprint со списком blacklist_fingerprint и может добавить IP в blacklist_ip.
  • FPSChecker, MobileChecker, HTTPChecker и IFrameChecker работают без list-файлов и принимают решение по параметрам из config и профиля.
  • IndexBot проверяет поисковых роботов по PTR-правилам из indexbot_rules; это более тяжелая DNS-проверка, поэтому порядок правил важен.

Списки и конфигурация

config.ini создается и дополняется через Config->init() и Config->set(). Если параметра нет, модуль добавляет значение по умолчанию и комментарий. Boolean значения читаются как On/Off, true/false, yes/no, 1/0.

lists/ содержит пользовательские и runtime-списки. Базовый ListBase создает файл при первом использовании, игнорирует комментарии после #, добавляет записи с file lock и форматирует комментарий с датой.

Важные списки:

Не хардкодьте абсолютные пути к этим файлам. Используйте пути из Config->BasePath, Config->CachePath и значения из config, потому что установка может жить не только в /antibot/.

  • whitelist_ip, blacklist_ip, graylist
  • whitelist_uri, blacklist_uri, captcha_uri
  • whitelist_useragent, blacklist_useragent, captcha_useragent
  • whitelist_referer, blacklist_referer, captcha_referer
  • whitelist_asn, blacklist_asn, captcha_asn
  • blacklist_fingerprint, blacklist_tor, indexbot_rules

Капча, шаблоны и клиентские файлы

Капча не ставит marker напрямую. Сначала API возвращает captcha и кладет скрытый флаг в session. После успешного skin-запроса клиент вызывает динамическую функцию marker, а xhr.php проверяет hidden value и только потом вызывает Marker->set().

  • Template->showVerificationPage() отдает templates/template.inc.php, ставит no-cache/noindex headers и может вернуть 404 для заглушки, если включен main.header404.
  • Template->showBlockPage() отдает templates/template_block.inc.php с HTTP 403.
  • skins/checkbox.php, slider.php, slider_rotate.php, slider_zsay.php и example.php — варианты капчи. Skin выбирается через main.captcha_type; имя skin в xhr.php очищается регулярным выражением перед подключением файла.
  • js/api.js, fp.js, frame_rate.js, metrika.js, tags.js и js/lang/* обеспечивают браузерные проверки, fingerprint/FPS, локализацию и интеграцию с Яндекс Метрикой.

Логи, marker и обновления

Logger пишет в logs/antibot.log строки с датой, RayID, IP и сообщением. Уровень DEBUG добавляет JSON context. Ротация запускается в xhr.php во время проверки и использует параметры logs.max_size и logs.rotate.

Marker по умолчанию хранит метку в cookie с префиксом aw_; альтернативный cookie.storage_type = awsession использует файловое session storage в cache/sessid/. Смена cookie.cookie_name сбрасывает метки для посетителей, потому что RayIDSecret строится из salt, IP и User-Agent.

SysUpdate обновляет код из githubniko/antibot через GitHub API и zip-архив выбранной ветки, когда sysupdate.enabled = On. При удалении старой версии он сохраняет .git, .gitignore, lists/, logs/, cache/, *.ini, *.bak, *.backup, *.origin и архив обновления. Локальные правки в PHP, JS, templates или skins могут быть перезаписаны обновлением, поэтому храните изменения в репозитории или отдельном процессе деплоя.

Безопасное расширение и отладка

  • Сначала добавляйте настройку через Config->init(), чтобы существующие установки получили безопасное значение по умолчанию.
  • Сохраняйте порядок правил: дешевые allow/block проверки должны идти раньше DNS, ASN, внешних HTTP-загрузок и браузерных проверок.
  • Для list-based правил наследуйте ListBase и переопределяйте validation/comparison только там, где формат данных отличается.
  • Не доверяйте данным из JS: isAllowed2() должен проверять наличие и тип каждого поля, как это уже сделано для frameRate, fingerPrint, isBas, screenWidth, pixelRatio, isFrame и location.
  • При работе за proxy или Cloudflare используйте HeaderProxy и секцию header_proxy, а не прямое чтение REMOTE_ADDR.
  • Проверяйте поведение по logs/antibot.log: ищите RayID, IP, причину allow/block/captcha и записи о добавлении в списки.
  • Не меняйте публичные имена status в API (allow, captcha, block, fail, no_csrf) без синхронного изменения js/api.js и skins.
  • Перед релизом проверяйте PHP versions, потому что README заявляет поддержку PHP 5.6.4+; не добавляйте синтаксис, который сломает старые установки.