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

в 14:26, , рубрики: iptables, nginx, p0f, боты, веб-аналитика, системное администрирование

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 — не единственный критерий, который мог бы работать в этом механизме.

Автор: YourChief

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js