← Назад в базу знаний

Как антифрод-системы вычисляют прокси по RTT и TCP window scaling

Как антифрод-системы вычисляют прокси по RTT и TCP window scaling

Антифрод-системы давно перестали полагаться только на IP-репутацию. Они копают глубже — прямо в TCP-стек. RTT и window scaling — два параметра, которые выдают прокси быстрее, чем вы успеете сказать "Hello".

RTT: что это и почему оно важно

RTT (Round-Trip Time) — время, за которое пакет доходит до сервера и обратно. Для обычного пользователя с прямым соединением это значение стабильно. Домашний интернет даёт RTT 10-50 мс до локального сервера, 100-200 мс до европейского.

Прокси добавляет лишний прыжок. Пакет идёт: клиент → прокси → целевой сервер → прокси → клиент. Каждый прыжок — дополнительные миллисекунды. Но фишка не в абсолютных значениях — их легко подделать. Фишка в **вариативности**.

У реального пользователя RTT колеблется в пределах 5-15% от среднего. Загрузка канала, расстояние до вышки, погода — всё влияет. Прокси же даёт подозрительно ровный RTT. Плюс-минус 1-2 мс от запроса к запросу. Слишком идеально для реального мира.

```bash

Измеряем RTT до сервера

ping -c 10 target-server.com

Смотрим мин/ср/макс — разброс должен быть > 5 мс для реального пользователя

```

TCP window scaling: скрытый отпечаток пальца

TCP window scaling — параметр, определяющий размер окна перегрузки. Он передаётся при установке соединения в SYN-пакете. Каждая ОС и даже версия ядра использует своё значение.

Windows 10 — window scale 8 (фактор 256). Linux 5.x — window scale 7 (фактор 128). macOS — window scale 3 (фактор 8). Прокси-серверы чаще всего крутятся на Linux с дефолтными настройками. Если у клиента Windows, а window scale говорит о Linux — тревога.

Но антифрод смотрит не только на абсолютное значение. Он анализирует **dynamic window scaling** — как меняется окно при перегрузке. Реальный пользователь адаптируется: уменьшает окно при потерях, увеличивает при свободном канале. Прокси часто держит окно константным или меняет слишком резко.

```python

import socket

import struct

def get_window_scale(packet):

Извлекаем window scale из TCP-опций SYN-пакета

Реальный парсер сложнее, но суть понятна

tcp_options = packet[20:40]

for i in range(len(tcp_options)):

if tcp_options[i] == 3: # Window Scale option

return tcp_options[i+1]

return None

Пример: сравниваем window scale клиента и прокси

client_ws = get_window_scale(client_syn)

proxy_ws = get_window_scale(proxy_syn)

if client_ws != proxy_ws:

print("Подозрительно: window scale не совпадает")

```

Как антифрод собирает данные

Системы вроде Cloudflare Bot Management или PerimeterX не ждут, пока вы что-то сделаете. Они встраивают JavaScript-сниффер, который собирает TCP-метрики на этапе рукопожатия. Без вашего ведома.

Сервер отправляет клиенту специальный пакет с timestamp. Замеряет время ответа. Повторяет 3-5 раз. Строит профиль RTT. Если профиль совпадает с известными прокси-провайдерами — бан.

Дополнительно проверяют **RTT до разных IP**. Прокси часто маршрутизирует весь трафик через один выходной узел. RTT до сервера в США и до сервера в Европе у прокси-пользователя будет почти одинаковым. У реального — разница в 50-100 мс.

```bash

Проверяем RTT до разных географических точек

for target in "us-server.com" "eu-server.com" "asia-server.com"; do

ping -c 3 \ | tail -1 | awk '{print \\$4}'

done

Если разброс < 20 мс — вы через прокси

```

Window scaling в комбинации с другими параметрами

Один параметр — плохой детектор. Комбинация — смертельное оружие. Антифрод строит **fingerprint** из 10-15 TCP-параметров:

- MSS (Maximum Segment Size) — обычно 1460 для Ethernet, 1400 для PPPoE

- TTL (Time To Live) — 128 для Windows, 64 для Linux

- SACK permitted — есть не у всех ОС

- Timestamps — включаются не везде

Прокси обычно форвардит TCP-параметры клиента как есть. Но некоторые настройки (например, TTL) прокси меняет. Клиент отправляет TTL=128, прокси уменьшает до 64. Антифрод видит: TTL=64, но window scale от Windows. Несостыковка.

| Параметр | Реальный пользователь (Windows) | Прокси (Linux) |

|----------|--------------------------------|----------------|

| TTL | 128 | 64 |

| Window scale | 8 | 7 |

| MSS | 1460 | 1460 (часто) |

| SACK | Да | Да |

| Timestamps | Да | Нет (если отключено) |

Кейс: как Netflix ловил прокси через RTT

Netflix использовал простую схему. Они замеряли RTT до CDN-серверов. Если пользователь в Москве показывал RTT 5 мс до немецкого сервера — это прокси. Нормальный RTT Москва-Франкфурт — 40-50 мс.

Проблема: некоторые прокси начали эмулировать задержку. Добавляли случайные 30-50 мс к каждому пакету. Netflix ответил: они начали анализировать **jitter** — вариацию задержки. Эмулировать человеческий jitter (5-15%) сложно. Прокси давали либо 0%, либо >30%.

Кейс: прокси с фиксированным window scale

Один провайдер прокси (не будем тыкать пальцем) использовал кастомную сборку Linux с window scale 8 — как у Windows. Думали, что обманули систему. Но антифрод заметил: window scale не меняется при перегрузке. У реального пользователя окно плавает. У прокси — статика.

Решение: пришлось патчить ядро, добавлять случайные флуктуации window scale. Но это породило новую проблему — window scale начал меняться слишком хаотично, что тоже выглядит подозрительно.

Кейс: двойной прокси и RTT-коллапс

Схема: клиент → прокси-1 (Россия) → прокси-2 (Нидерланды) → целевой сервер. Ожидалось, что RTT будет суммой задержек. Но антифрод заметил странность: RTT до сервера в США оказался меньше, чем до сервера в Германии. Физически это невозможно.

Оказалось, прокси-2 маршрутизировал трафик через CDN, который кешировал ответы. RTT до США падал до 10 мс из-за кеша. Антифрод засёк аномалию: RTT не соответствует географическому расстоянию.

Как защититься от детекта по RTT и window scale

Полностью не защититься. Антифроды становятся умнее. Но можно снизить риск:

1. **Эмулировать человеческий jitter**. Добавлять случайную задержку 5-15% от базового RTT. Не константную — нормально распределённую.

2. **Использовать несколько выходных узлов**. Один узел на регион. RTT до разных серверов должен различаться.

3. **Патчить window scale**. Не использовать дефолтные значения. Менять их динамически в зависимости от нагрузки.

4. **Не использовать дешёвые прокси**. Они обычно имеют характерные TCP-профили. Дорогие — эмулируют реальных пользователей.

```python

import random

import time

def emulate_human_rtt(base_rtt):

Добавляем случайный jitter 5-15%

jitter = base_rtt * random.uniform(0.05, 0.15)

if random.random() > 0.5:

jitter = -jitter

return base_rtt + jitter

Пример для прокси-сервера

for request in range(100):

current_rtt = emulate_human_rtt(40) # базовый RTT 40 мс

time.sleep(current_rtt / 1000)

```

Почему это всё не работает на 100%

Антифрод тоже не дураки. Они знают про эти трюки. Поэтому добавляют **поведенческий анализ**. Если TCP-профиль идеален, но поведение пользователя ботовое — бан всё равно придёт.

RTT и window scale — лишь часть пазла. Реальная защита — мимикрия под реального пользователя на всех уровнях: TCP, HTTP, JavaScript, мышь, скролл.

Но если ваш прокси даёт RTT = 5 мс до сервера за 10 000 км — вы уже в базе. Даже не пытайтесь.

✔️Купить прокси