Я достаточно долгое время вынашивал идею рассмотреть клиентов публичного 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 — не единственный критерий, который мог бы работать в этом механизме.
Автор: YourChief