Пасивний фингерпринтинг для виявлення синтетичного трафіку

imageЯ досить довгий час виношував ідею розглянути клієнтів публічного web-сервісу, браузер яких посилає заголовок User-Agent як у браузера на Windows, і які при цьому мають всі ознаки мережевого стека *nix-систем. Імовірно, у цій групі повинна бути велика концентрація ботів, запущених на недорогих хостингах для накрутки трафіку або сканування сайту.

Коротко про предмет

Різні реалізації стека TCP/IP в операційних системах мають різні значення параметрів за замовчуванням. Це дозволяє з непоганою ступенем достовірності зробити висновок про те, яка операційна система сформувала пакет.
У цьому контексті набір характерних для операційної системи параметрів пакета називають OS fingerprint. Оскільки цей метод передбачає тільки спостереження трафіку без відправки будь-яких запитів, метод називають passive OS fingerprinting.

Я використовую nginx як фронт-сервера, і для нього немає mod_p0f як для apache, тому маркувати запити за ознакою фингерпринта в ньому — завдання непросте, але вирішуване. Нижче я пропоную до розгляду рішення, яким я досяг результату.

Рішення

Як згадувалося вище, цікава для мене група — никсовые машини, які видають себе за віндовий. Потрібно мати всередині nginx розуміння, від якої ОС з'єднання. Я вирішив маркувати шукані з'єднання, направивши їх на окремий порт порт nginx за критерієм TTL.
iptables-A PREROUTING-t nat-p tcp-m tcp --dport 80-m --ttl ttl-lt 64-j REDIRECT --to-ports 8123

В nginx тоді все стає досить просто.
Додамо додатковий порт:
listen 80;
listen 8123;

Зазначимо змінної запити, які прийшли на цей виділений порт.
map $server_port $is_specialport {
default 0;
8123 1;
}

Пометим проксі-сервери. Таких запитів багато Opera Turbo і їм подібних.
map $http_x_forwarded_for $is_proxy {
default 0;
~^. 1;
}

Ознака віндового юзер-агента.
map $http_user_agent $is_windows {
default 0;
"~Windows" 1;
}

І, нарешті, визначимо змінну-прапор для випадків, коли запит має віндовий юзер-агент, не проксирован, має низький TTL:
map $is_windows$is_specialport$is_proxy $is_suspected {
default "";
"110" is_suspicious;
}

Залогируем значення прапора для всіх запитів:
log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$upstream_addr" '
'"$gzip_ratio" "[$upstream_response_time]" "$upstream_cache_status" "$request_time" "$is_suspected"';
access_log /var/log/nginx/nginx.access.log custom buffer=128k;


Висновки

Звичайно ж я не вважаю, що метод дає велику точність, але спостереження логів виявило:
  • клієнтів, від яких надходили запити виключно до лічильників статистики
  • ботів, які були націлені на парсинг Вконтакту, але забрели на сайт за посиланням із соцмереж
  • нечисть особливого роду, яка теж не є живим користувачем
Частка влучень дуже хороша, придивитися дійсно коштувало.

P.S.
Зрозуміло, я знаю, що замовчування легко змінити і, звичайно ж, TTL — не єдиний критерій, який міг би працювати в цьому механізмі.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.