Как написать свое правило фильтрации трафика [WAF] на данных визита

Правила фильтрации: Полный контроль над трафиком

Фильтрация трафика в возможна не только через слепки, но и через гибкие правила фильтрации, которые задаются вручную. Это значит, что вы получаете прямой контроль над логикой фильтрации, настраивая ее под свои реальные задачи. Правила, в зависимости от параметров браузера, параметров Килбота, IP пользователя и др. позволяют выполнять нужное действие (блокировка, капча, зацикливание, скрытие метрики).

Внимание!
Правила этого раздела работают на странице верификации (Экране KillBot). Т.е. пользователь попадает на страницу верификации, а уже там срабатывает правило. Если вам нужно чтобы страница верификации вообще не срабатывала (колбеки платежных систем, например), то для этой цели в настройках скрипта есть параметры: белый список IP, белый список user-agent и список страниц для которых защита вообще отключена

Где именно посмотреть параметры для создания правил?

Все самые интересные параметры можно посмотреть в интерфейсе системы KillBot, для этого нужно зайти в "Визиты" - и там навести мышку на "?" который находится в столбце с данными:

Заходим в визиты в килботе

Сами данные в Килботе представлены в формате JSON. Данные сгруппированы по "блокам" и параметрам со значениями::

Параметры визита в Килботе

 

Ниже приведен пример данных для создания правила:


{
    "killbot": {
        "UserID": "308676189735353810",
        "bot": true,
        "vpn": "1",
        "solved_early": true,
        "snsht": 1128679841,
        "net_id": 3957945795,
        "net_t": "corp",
        "bl": false,
        "wl": false,
        "l": false,
        "ffp": "1571847785",
        "adt": true
    },
    "user": {
        "timezone": "UTC",
        "locale": "en-US"
    },
    "net": {
        "ip": "18.216.102.68",
        "host": "ec2-18-216-102-68.us-east-2.compute.amazonaws.com",
        "asn": "16509",
        "country": "US",
        "LocalPorts": {
            "5985": "Windows Remote Management HTTP (WSMan)",
            "47001": "Windows Remote Management (WinRM)"
        },
        "ports": {
            "22": {
                "port": 22,
                "ttl": 59,
                "rtt": 12
            },
            "443": {
                "port": 443,
                "ttl": 59,
                "rtt": 0
            }
        },
        "ping": false,
        "ttlOS": "Linux",
        "ttl": "52"
    },
    "request": {
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
        "referer": "https://trafficgen.net/",
        "url": "https://trafficgen.net/"
    },
    "browser": {
        "name": "Chrome",
        "language": "en-US",
        "webdriver": true,
        "innerheight": 768,
        "innerwidth": 1366,
        "outerheight": 768,
        "outerwidth": 1366
    },
    "device": {
        "width": 1366,
        "height": 768,
        "os": "Mac OS X"
    }
}

Пример, почему параметры выше принадлежат боту

  1. Параметр "webdriver": true - этот параметр означает, что браузер находится под программным управлением
  2. Временная зона "timezone": "UTC", хотя пользователь находится в США ("country": "US")
  3. IP захода "ip": "18.216.102.68"резолвится на сервер с амазона: "host": "ec2-18-216-102-68.us-east-2.compute.amazonaws.com"
  4. Используется технология антидетекта: "adt": true
  5. Код килбота прогружен не полностью: l.false - поведение, характерное для бота
  6. Слепка браузера сайта нет в списке известных: wl.false

Далее я раскрою подробное значение каждого параметра, расскажу по каким именно параметрам боты себя выдают и покажу примеры конкретных правил.

Подробное описание всех параметров

Блок killbot

  • UserID — Уникальный идентификатор пользователя, не зависящий от cookie. Используется для отслеживания визитов одного пользователя даже. UserID пользователя не изменится при использовании режима инкогнито и очистке куков. UserID условно-уникальный, т.е. KillBot берёт всевозможное браузерное окружение и генерирует UserID. Т.е. могут существовать и разные реальные пользователи у которых UserID совпадает. Цифру уникальности для каждого UserID я предоставлю позже - как сделаю соответствующие эксперименты.

  • bot — Является ли визит ботом (true/false), выставляется системой до применения правил по логике выставленной в настройках скрипта килбот на основании слепков.

  • capt - это какой тип капчи показан. capt = false - капча не показана, capt = 2 - слайдер, capt = 3 - ALERT CANSEL , capt=31 - ALERT OK , capt=4 - зациклить

  • deny - запретить заход. если deny=true, то заход на сайт запрещён - будет показан просто белый экран.
  • solved_early — если solved_early = true значит, что пользователь уже решил капчу ранее, по умолчанию таким пользователям капча не показывается. solved_early = false это значит, что ранее и пользователь капчу не решал.

  • vpn — Используется ли VPN (1 — да, 0 — нет). Определяется, по доступности сайтов, заблокированных в РФ (например, Instagram).

  • snsht — Слепок (snapshot) браузера, используется для сравнения с слепками известных браузеров и ботов.

  • snsht_hd — Слепок детализированный, можно использовать если бот повторяет слепок реального браузера.

  • net_id — Внутренний идентификатор сети KillBot, определяет какое именно у пользователя сетевое окружение. Описание идентификатора сети в параметре net_t.

  • net_t — Тип сети:

    • corp — корпоративная сеть или VPN  (на IP пользователя открыт один из портов: 80,443,22,3389)

    • mobile — мобильная сеть (все порты закрыты)

    • home — домашняя сеть (IP только пингуется)

  • bl — Слепок визита находится ли визит в чёрном списке (blacklist).

  • wl — Слепок визита есть в списке системных или пользовательских браузерах (whitelist).

  • ffp — Font fingerprint браузера - фингерпринт того, как именно браузер отрисовывает шрифты. Если слепок бота повторяет слепок реального браузера, то можно по этому параметру создать правило.

  • adt — Признак использования технологии антидетекта, выставляется системой KillBot и может говорить о том, что используется антидетект браузер или так бот скрывает себя.

Блок user

  • timezone — Временная зона пользователя (например, Europe/Moscow, UTC).

  • locale — Локаль пользователя (язык системы, например, ru-RU, en-US).

Блок net

  • ip — IP-адрес пользователя.

  • webrct_ip —  WEBrtc IP-адрес пользователя.

  • host — Имя хоста, на который резолвится IP-адрес (к IP адресу может быть привязан домен, если значение пустое, то домен не привязан).

  • asn — Autonomous System Number — номер автономной системы, к которой принадлежит IP (можно использовать для определения интернет провайдера). Есть провайдеры через которых прогоняется только бот трафик, например Biterika.

  • country — Страна, определённая по IP.

  • ports — Список открытых портов на данном IP (обычно пуст для мобильных/домашних сетей).

  • LocalPorts — Список открытых портов localhost.

  • ping — Пингуется ли IP пользователя (true/false).

  • ttlOS — Операционная система, определённая по TTL пакета (например, Linux, Windows).

  • ttl — Значение TTL пакета (например, 52, 64, 128 — косвенно указывает на ОС и тип трафика).

Блок request

  • user-agent — User-Agent браузера (можно использовать для поиска ботов и парсеров).

  • referer — С какого сайта пришел пользователь (реферер).

  • url — Запрошенный URL.

Блок browser

  • name — Название браузера (Chrome, Firefox и т.д.).

  • language — Язык, установленный в браузере (например, en-US, ru-RU).

  • webdriver — Програмно управляется бразузер или нет (true — браузер управляется программой, это 100% боты).

Блок device

  • width/height — Физическая ширина/высота экрана устройства.

  • os — Операционная система устройства (например, Mac OS X, Windows, Linux).

 

Внимание!
Для написания правила нужны навыки по программированию, поэтому, за помощью написания правил обращайтесь в телеграм: https://t.me/grigoriy_melnikov - правила именно для вашего случая будут написаны. Простой интерфейс для создания правил будет реализован чуть позже - тогда каждый сможет создать правило просто кликая мышкой.

 

Инструкция: Как писать PHP-правила фильтрации трафика в KillBot

Создать правило для фильтрации трафика можно на странице: https://killbot.ru/waf/create (левое меню -> создать правило)

Там два основных поля:

  1. PHP-код правила — нужно написать логику правила на PHP.

  2. JSON-параметры визита — тестовые данные для проверки вашего правила. Сюда можно просто скопировать и вставить данные визита для которого нужно создать правило.

Какие элементы языка php можно использовать:

Доступная переменная

  • $data — содержит JSON-структуру визита (например, $data['user']['locale']). Используйте только $data. Все другие переменные — запрещены.

Разрешённые функции

strpos, stripos, strstr, stristr, str_contains, substr, preg_match, in_array, isset, empty, count, strlen, array_key_exists

Разрешённые операторы

&&, ||, !, ==, ===, !=, !==, <, >, <=, >=

Разрешённые конструкции

if, else, elseif, return, true, false, null 

Что запрещено

  • Опасные функции: eval, exec, system, shell_exec, fopen, file_get_contents, include, require, и т.п.

  • Создание классов/функций: нельзя использовать function, class, namespace, new.

  • Глобальные переменные: $_GET, $_POST, $_SERVER и т.п.

  • Вывод: echo, print, die, exit.


Пример как обращаться к параметрам

Что нужно Как написать
Часовой пояс $data['user']['timezone']
Язык пользователя $data['user']['locale']
User-Agent $data['request']['user-agent']
WebDriver (бот?) $data['browser']['webdriver']
IP хост $data['net']['host']
TTL ОС $data['net']['ttlOS']
Операционная система $data['device']['os']

Что должен вернуть php код правила?

PHP код должен вернуть true или false. TRUE - это значит что правило выполнено.

Внимание!
В KillBot можно создать много правил для фильтрации. Для визита правила проверяются по порядку. Первое выполненное правило считается примененным - остальные правила игнорируется. Если ни одно правило не выполнено, то визит считается ботом или пользователем по умолчанию - на основе настроек выставленных в скрипте KillBot.

Пример создания правила

Ниже правило, которое будет считать ботом все визиты, в user agent которых есть слово Bot:


if (stripos($data['request']['user-agent'], 'bot') !== false) {
  return true;
}
return false;

В правиле:

  • $data['request']['user-agent'] - UserAgent визита
  • stripos - функция, которая ищет подстроку "Bot", stripos (через "i") - это значит без чувствительности к регистру, т.е. "bot" и "Bot" - одно и тоже.
  • stripos($data['request']['user-agent'], 'bot') - найдёт позицию первого вхождения подстроки "bot" и вернет false - если подстроки "bot" нет в строке $data['request']['user-agent']
  • if (stripos($data['request']['user-agent'], 'bot') !== false) - это означает, что условие выполнено, если подстрока bot содержится в $data['request']['user-agent']


Так это выглядит в интерфейсе KillBot:

пример правила для фильтрации трафика


Далее нужно нажать на кнопку "Сохранить правило". В этот момент чекер килбота проверит синтаксис правила на валидность и выдаст результат применения правила к тестовым данным:

Правило килбот выполнено


Килбот выдал сообщение "Результат выполнения правила: FALSE - правило НЕ сработало, тестовые данные не удовлетворяют требованиям правила" - это значит что в User Agent (на скриншоте ниже выделено красным) нет подстроки Bot.

Теперь если мы изменим юзер агент тестовых данных на юзер агент гугл бота: "Mozilla/5.0 (compatible; Googlebot/2.1; +https://www.google.com/bot.html)" и посмотрим как именно будет работать наше правило. Далее нажимаем "сохранить правило" и посмотрим какой результат мы получим:

изменили Юзер агент на гугл бота


 

 

Наше правило вернуло TRUE, так как юзер агент содержит подстроку "Bot".

Доработаем правило, чтобы настоящие поисковые боты пропускались, а фейковые - нет. 

Доработка правила просто для примера - в киллбот при ДНС интеграции идея этого правила уже вшита в килбот и работает по умолчанию. Отдельно такое правило как здесь создавать не нужно.

Один из ключевых способов определить, действительно ли визит принадлежит настоящему поисковому боту Google, — это проверить, на какой хост резолвится IP-адрес визита. KillBot автоматически определяет, к какому хосту привязан IP-адрес визита. Этот параметр хранится в: $data["net"]["host"]. Если визит совершается настоящим GoogleBot'ом, то IP-адрес должен резолвиться на домен в зоне google.com, например: crawl-66-249-66-1.googlebot.com

Если же:

  • хост вообще не резолвится,

  • или указывает на стороннюю инфраструктуру (например, ec2-3-145-12-52.us-west-2.compute.amazonaws.com),

  • или содержит другие зоны (amazonaws.com, contabo.net, и т.п.),

— это признак поддельного поискового бота, маскирующегося под Google.


После выполнения этой проверки наше правило будет выглядеть вот так:



if (substr($data['net']['host'], -strlen(".google.com")) === ".google.com") {
// если хост заканчивается на ".google.com" - т.е. это настоящий поисковый бот,
// считаем визит доверительным - настоящим пользователем
  return false;
}
if (strpos($data['request']['user-agent'], 'bot') !== false) {
//если существует подстрока bot, то считаем визит ботом
  return true;
}
//если оба верхних условия не выполнены, то считаем визит пользователем
return false;

Кем именно считать визит если правило выполнено?

Это задается в настройках правила:

Если правило выполнено считаем визит пользователем

Для нашего правила, если правило вернуло true - то такой визит мы считаем ботом (так как если user agent содержит слово Bot и IP бота не резолвится на сервер гугла - то это очевидный бот).

Выставим действие: как именно обрабатывать визиты которые попадут под действие правила, в нашем случае выберем "заблокировать":

блокируем фейковых ботов

 

Как применить правило к сайту?

Когда мы создали правило - оно просто создано и не применено ни к одному из скриптов килбот созданных в системе. Чтобы применить правило, нужно в настройках скрипта KillBot выбрать это правило:
 

выбираем правило для фильтрации


Все, после этого все визиты скрипта KillBot будут прогоняться через это правило. Если для визита правило выполнено (вернуло true), то в параметрах посетителя в метрике параметр rule будет со значением номера этого правила. Так же в килботе - в списках визитов буде отображаться значение параметра rule для каждого визита.
 

Если нужна помощь в написании правила, то обращайтесь: https://t.me/grigoriy_melnikov - это бесплатно

 

Примеры правил как именно бот палится

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

1. Host (резолв IP-адреса)

Один из самых показательных признаков — это host, к которому имени домена резолвится IP-адрес посетителя.

  • Если IP уходит, например, на *.amazonaws.com, digitalocean.com или другие облачные платформы, это почти всегда сервер, а не домашний пользователь.

  • Такие хосты часто используются либо для работы ботов, либо как выходные узлы VPN.

  • Если таких заходов много с одного диапазона, это почти точно бот-сеть. Если единичный визит — возможно, VPN.


if (strpos($data['net']['host'], 'amazon') !== false) {
//Хост содержит подстроку 'amazon'
  return true; // Если IP указывает на Amazon
}
return false; // Разрешаем остальных

2. Часовой пояс vs география

Следующее, что стоит проверить — это соответствие часового пояса (timezone) географическому положению IP-адреса:

  • Пользователь из России, у которого выставлен часовой пояс, например, UTC+0, вызывает подозрения.

  • Это может указывать на заход с сервера, где часовой пояс установлен по умолчанию, или бот это просто бот, который не подменяет системные настройки.

  if ($data['user']['timezone'] == 'UTC' && $data['net']['country'] === 'RU')
  { 
      return true; // Часовой пояс не соответствует России — подозрительно 
  } 
  return false;  

3. Язык браузера и локаль

Еще один важный индикатор — это язык браузера (navigator.language) и локаль:

  • Например, если часовой пояс России, а язык браузера — русский (ru-RU), а локаль английская, это не является стопроцентным индикатором, но для российского трафика это редкость - т.е. если много визитов с таким паттерном - то все их под капчу, например.

  • В совокупности с другими параметрами это усиливает подозрение, что трафик не живой.

  if ( $data['user']['timezone'] === 'Europe/Moscow' && $data['browser']['language'] === 'ru-RU' && $data['user']['locale'] === 'en-US' ) { 
      return true; // Подозрительное несоответствие языка и локали 
  } 
      return false;  

4. Наличие открытых портов у IP-адреса

У обычного пользователя — будь то сотовый интернет или домашний Wi-Fi — внешний IP-адрес не имеет открытых портов: это значит что удаленно на компьютер пользователя не зайти и никакой внешний сайт на компьютере пользователя (роутере) не висит. 

Если на IP-адресе открыты:

  • 80 или 443 порты — с высокой вероятностью на этом IP работает веб-сервер.

  • 22 (SSH) или 3389 (RDP) — это удалённое администрирование, типичное для серверов.

Такой IP может принадлежать VPN или серверу, с которого работает бот.

  if (isset($data['net']['prots'][443]))) { 
      //если в массиве портов $data['net']['prots'] есть порт 443
      return true; // На IP открыты подозрительные порты — возможно, сервер или VPN 
  } 
  return false;  

5. Анализ TTL (Time To Live)

TTL (Time To Live) — это параметр, содержащийся в каждом сетевом пакете, который определяет максимальное число маршрутизаторов (промежуточных серверов или IP), через которые этот пакет может пройти в интернете. Каждая операционная система устанавливает свой дефолтный TTL при отправке пакетов.

OS TTL
Windows 128
Linux / Android / macOS 64
Unix BSD 255

Когда пакет проходит через маршрутизатор, TTL уменьшается на 1. Таким образом, по значению TTL, которое пришло на сервер, можно приблизительно понять, какой была исходная операционная система.

Если мы знаем, что в заголовках запроса указано, что пользователь сидит, например, на Windows, но TTL у него 64, как у Linux, — это уже повод для подозрения. Такое несоответствие между User-Agent и TTL может указывать на:

  • использование прокси-сервера, который подменяет системный TTL;

  • работу через контейнер или облачный сервер, где ОС другая;

  • подделку User-Agent, когда бот маскируется под другую ОС.

TTL — не абсолютный признак, он может меняться в зависимости от сетевых условий, VPN и маршрутов. Но в связке с другими признаками (WebDriver, host, locale, WebRTC, и т.д.) TTL становится мощным индикатором нечестного трафика или бот-сетей.


if ($data['device']['os'] === 'Windows' && $data['net']['ttl'] < 100) {
//OS=Windows и TTL<100
//Здесь мы предполагаем, что TTL < 100 — подозрительно для Windows.
  return true;
}
return false;

6. Наличие технологии антидетекта в браузере

Параметр adt в системе KillBot указывает на то, что в браузере пользователя обнаружены признаки использования антидетекторных технологий — специального программного обеспечения, маскирующего характеристики браузера.

Большинство продвинутых ботов и накрутчиков трафика используют антидетект-технологии, чтобы замаскироваться под «живых» пользователей и обойти поведенческую и техническую защиту.

➡️ Поэтому, если у визита установлен флаг adt=true, это может свидетельствовать о:

  • использовании специализированного антидетект-браузера (например, Indigo, Dolphin, AdsPower и др.),

  • запущенном расширении, маскирующем fingerprint,

  • использование бот программы написанной на BAS или подобных фреймворках.

Важно понимать, что только наличие технологии антидетект не гарантирует, что это бот.

  • Некоторые реальные пользователи могут использовать антидетект браузеры

  • Например, Firefox с приватными настройками, Tor-браузер или пользователь с расширением типа uBlock Origin тоже может быть помечен как использующий антидетектор.


if ($data['killbot']['adt'] == true ) {
  //Обнаружен антидетект
  return true;
}
return false;

7. 100% признак бота: WebDriver = true

WebDriver — это программный интерфейс, который позволяет управлять браузером извне, автоматически эмулируя действия пользователя: клики, переходы, ввод текста и т.д. Он используется в инструментах автоматизации, таких как:

  • Selenium

  • Puppeteer

  • Headless Chrome/Firefox

Если KillBot зафиксировал этот параметр, это означает, что:

  • браузер запущен под программным управлением,

  • внутри браузера присутствует объект navigator.webdriver = true,

  • это прямое свидетельство, что браузером управляет бот-скрипт или антидетект-платформа.

Если webdriver==true - это 100% бот, визит может быть реальным только если администратор тестирует свою бот программу.


if ($data['browser']['webdriver'] == true ) {
//точно бот
  return true;
}
return false;

8. WebRTC и утечка реального IP

Даже если бот грамотно подменяет IP-адрес через прокси, есть технологии в браузере, которые могут его выдать. Одна из самых ярких — это WebRTC (Web Real-Time Communication).

  • WebRTC — это встроенная в браузер технология для передачи аудио, видео и данных в реальном времени.

  • Она работает минуя системные прокси, а значит может раскрыть реальный IP-адрес устройства, даже если весь остальной трафик идёт через VPN или proxy.

  • Если IP браузера (через proxy) не равен IP WebRTC — значит, пользователь использует прокси. Само по себе это не плохо, но требует внимания. Если таких несовпадений много, и при этом IP WebRTC постоянно повторяется, несмотря на разные браузерные IP — это характерный паттерн бота который работает с одного сервера под различными прокси.


if ($data['net']['ip'] !=  $data['net']['webrtc_ip']) {
//webrtc ip не равен ip визита
          return true;
}
return false;

9. Признак бота: wl=false (нет в списке системных браузеров)

wl - это параметр Килбота. Он может принимать два значения:

  • true — слепок браузера визита есть в системном списке браузеров (white list);

  • false — слепок не найден среди известных доверенных браузеров.

Если wl = false,  то, по умолчанию, KillBot считает такие визиты ботами. Если таких визитов много в трафике сайта - это 100% боты, если таких визитов в реальном трафике менее 5% - то тут могут быть и живые пользователи.
 


if ($data['killbot']['wl'] = true) {
//слепка браузера визита нет в системном списке браузеров
          return true;
}
return false;

 

10. Запрещаем некоторые ASN

Есть провайдеры через которых прогоняется только бот трафик, например Biterika. ASN таких и подобных имеет смысл сразу заблокировать.


if (in_array($data['net']['asn'],array("35048","35049","54048") ) ){
//Если значение ASN совпадает с одним из значений, то сразу расцениваем как БОТ
          return true;
}
return false;


11. Запрещаем прямой трафик с определенным слепком

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


if ($data['killbot']['snsht'] == 3933974590 && $data['request']['referer'] == "") { 
//Если слепок браузера равен 3933974590 и заход прямой (т.е. реферер пуст), то расцениваем такой заход как бот
          return true;
}
return false;

12. Разрешаем трафик с определенным URL

Зачастую нужно пропускать трафик с определенными метками в URL.

if (stripos($data['request']['url'], 'from=seo') !==false ){ 
//если url содержит строку 'from=seo', то расцениваем визит как настоящего пользователя, т.е. применяем правило
          return true;
}
return false;

 

13. Запрет доступа с определённого ip

if (in_array($data['net']['ip'],array("46.159.126.145") ) ){

//Если значение ip совпадает с одним из значений, то сразу расцениваем как БОТ

          return true;

}

return false;

 

14. Разрешение запросов с конкретного referer (на примере yandex.ru)

return isset($data['request']['referer']) && stripos($data['request']['referer'], 'yandex.ru') !== false;
// Если referer будет yandex.ru то далее выполняется ваше действие (например не показывать капчу)

 

15. Отмечаем прямые заходы без реферер как боты

if ($data['request']['referer'] == "") { 
// Если заход прямой (т.е. реферер пуст), то расцениваем такой заход как бот
          return true;
}
return false;