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

Как антифрод-системы вычисляют прокси по MTU и MSS: разбор на уровне пакетов

Как антифрод-системы вычисляют прокси по MTU и MSS: разбор на уровне пакетов

TCP-рукопожатие как отпечаток пальца

Антифрод-системы не гадают на кофейной гуще. Они анализируют TCP-пакеты. Самый простой способ определить прокси — посмотреть на MSS (Maximum Segment Size) в SYN-пакете.

MSS — это параметр TCP-рукопожатия. Клиент отправляет SYN, в котором указывает максимальный размер сегмента данных. Обычно это MTU минус 40 байт (20 байт IP-заголовка + 20 байт TCP-заголовка). Для Ethernet MTU=1500, значит MSS=1460.

Прокси-серверы меняют этот параметр. Особенно IPv6-прокси. Почему? Потому что IPv6-заголовок больше — 40 байт вместо 20. Плюс опциональные расширения. Итоговый MTU тоннеля может быть меньше стандартного.

Пример: клиент за прокси с MTU 1280 (минимальный для IPv6). MSS будет 1280 - 40 (IPv6) - 20 (TCP) = 1220. Сервер видит SYN с MSS=1220 и сразу понимает — трафик идёт через туннель.

Как выглядит нормальный MSS

Разные сети дают разные значения. Вот реальные цифры:

| Тип подключения | MTU | MSS | Примечание |

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

| Ethernet | 1500 | 1460 | Стандарт |

| PPPoE | 1492 | 1452 | Домашние сети |

| VPN (OpenVPN) | 1500 | 1450-1460 | Зависит от оверхеда |

| IPv6-прокси | 1280-1500 | 1220-1460 | Диапазон |

| Мобильный 4G | 1500 | 1430-1460 | Иногда меньше |

Проблема в том, что прокси часто используют фиксированное значение MSS. Например, все клиенты одного прокси-провайдера шлют SYN с MSS=1452. Это выдаёт их с головой.

Кейс: nginx и странный MSS

Берём сервер на nginx 1.24. Логи tcpdump показывают SYN с MSS=1452. Провайдер клиента — обычный PPPoE. Но трафик приходит не напрямую, а через CDN. CDN использует IPv6-прокси.

Почему MSS=1452? PPPoE добавляет 8 байт заголовка. MTU снижается до 1492. MSS = 1492 - 40 (IPv6) - 20 (TCP) = 1432. Но tcpdump показывает 1452.

Разгадка: прокси-сервер CDN переписывает MSS. Он берёт значение для Ethernet (1460) и вычитает 8 байт PPPoE. Получает 1452. Но не учитывает, что сам работает через IPv6-туннель.

Антифрод-система видит: SYN приходит с IP, принадлежащим CDN, но MSS не соответствует стандартному для Ethernet. Вывод — трафик идёт через прокси.

PMTUD и его грабли

Path MTU Discovery — механизм, который определяет максимальный размер пакета на всём пути. Работает через флаг DF (Don't Fragment) и ICMP-сообщения "Fragmentation Needed".

Прокси-серверы часто ломают PMTUD. Почему? Потому что они меняют IP-адреса. Клиент отправляет пакет с DF=1 через прокси. Прокси получает ICMP-ответ от промежуточного маршрутизатора, но не передаёт его клиенту. Клиент продолжает слать большие пакеты, которые теряются.

Антифрод-системы отслеживают это. Если клиент не получает ICMP-сообщения при нормальном MTU, значит трафик идёт через прокси, который фильтрует ICMP.

Пример: сервер с MTU 1500. Клиент шлёт пакет 1500 байт. Прокси с MTU 1280 не может передать такой пакет. Он либо фрагментирует (если DF=0), либо отбрасывает (если DF=1). В любом случае — аномалия.

Кейс: ICMP-тишина на IPv6

Клиент использует IPv6-прокси от lexic.ml. Сервер пытается отправить пакет 1500 байт. Прокси имеет MTU 1280. Сервер получает ICMPv6 "Packet Too Big" с новым MTU=1280.

Клиент уменьшает размер пакетов. Всё работает. Но антифрод-система замечает: клиент слишком быстро адаптируется. Обычные пользователи не меняют MSS мгновенно. Прокси-клиенты — да, у них это встроено в софт.

Дополнительный признак: ICMPv6-сообщения приходят с IP-адреса, который не принадлежит ни одному маршрутизатору на пути. Это IP прокси. Антифрод видит несоответствие.

TCP timestamps и их аномалии

Опция TCP timestamps в SYN-пакете — ещё один маркер. Прокси-серверы часто модифицируют или добавляют эту опцию.

Нормальный клиент может не отправлять timestamps. Прокси — почти всегда отправляет. Почему? Потому что ему нужно синхронизировать два TCP-соединения: с клиентом и с сервером.

Антифрод-системы проверяют: если SYN содержит timestamps, а последующие пакеты нет — это подозрительно. Или наоборот: SYN без timestamps, а ACK с ними.

Кейс: разрыв в последовательности

Клиент отправляет SYN без опции timestamps. Прокси добавляет её на лету. Сервер отвечает SYN-ACK с timestamps. Клиент не поддерживает timestamps. Прокси вынужден удалить их из ответа перед отправкой клиенту.

Антифрод-система видит: SYN-ACK содержит опцию timestamps, но клиентский ACK — нет. Несоответствие. Плюс клиент не учитывает timestamp в расчёте RTT. Это тоже видно.

Пример: curl с опцией `--tcp-nodelay` на клиенте. Прокси добавляет timestamps. Сервер отвечает. Клиент игнорирует timestamps. Антифрод вычисляет разницу.

TTL и его искажение

Time To Live — простой, но эффективный маркер. Каждый маршрутизатор уменьшает TTL на 1. Прокси-сервер может менять TTL в пакетах.

Начальное значение TTL зависит от ОС:

- Windows: 128

- Linux: 64

- macOS: 64

- Cisco: 255

Прокси обычно устанавливает TTL=64 или 128. Если клиент с Windows (TTL=128) идёт через прокси, который уменьшает TTL до 64, сервер видит несоответствие.

Антифрод-система анализирует: TTL пакета не соответствует количеству хопов до клиента. Если до клиента 10 хопов, а TTL=54 (64-10), это нормально для Linux. Но если TTL=118 (128-10), а клиент использует Linux — аномалия.

Кейс: TTL=64 на Windows

Клиент с Windows 10 (TTL=128) использует прокси. Прокси на Linux (TTL=64). Сервер видит TTL=54 (64 - 10 хопов). Антифрод проверяет fingerprint ОС по другим параметрам (Window Scale, MSS, SACK) и определяет Windows.

Несоответствие: Windows с TTL=54. Вывод — трафик идёт через прокси.

Решение для прокси: не менять TTL, а передавать оригинальное значение. Но это сложно, если прокси сам является точкой маршрутизации.

Window Scale и его странности

Опция Window Scale в SYN-пакете определяет множитель для окна TCP. Прокси-серверы часто меняют это значение.

Нормальные значения: 7 (множитель 128), 8 (256), 9 (512). Прокси могут ставить 0 или 1 — это редкость для современных ОС.

Антифрод-системы проверяют: Window Scale соответствует fingerprint ОС. Если клиент с Linux (обычно 7-9) имеет Window Scale=0 — это прокси.

Кейс: Window Scale=0 на macOS

Клиент на macOS 12 (Window Scale=3 по умолчанию) использует прокси. Прокси устанавливает Window Scale=0. Сервер видит: SYN с Window Scale=0, но fingerprint macOS.

macOS никогда не использует Window Scale=0. Это невозможно. Вывод — трафик изменён.

Прокси делает это, чтобы уменьшить оверхед. Но антифрод-системы давно знают такие трюки.

Как защититься от детекта

Полностью скрыть прокси невозможно. Но можно усложнить детект:

1. **Не менять MSS**. Передавать оригинальное значение от клиента.

2. **Не добавлять опции**. Если клиент не отправляет timestamps — не добавлять их.

3. **Сохранять TTL**. Передавать оригинальное значение, уменьшая на 1 только за себя.

4. **Не фильтровать ICMP**. Передавать все ICMP-сообщения клиенту.

5. **Использовать правильный Window Scale**. Соответствовать fingerprint клиента.

Пример настройки nginx для сохранения MSS:

```nginx

stream {

upstream backend {

server 192.168.1.10:443;

}

server {

listen 443;

proxy_pass backend;

proxy_protocol on;

set_real_ip_from 10.0.0.0/8;

real_ip_header proxy_protocol;

}

}

```

Но даже это не гарантирует защиту. Антифрод-системы анализируют сотни параметров. Один прокси-сервер может быть вычислен по комбинации MSS+Window Scale+TTL+timestamps.

Итог

Антифрод-системы вычисляют прокси на уровне TCP-пакетов. MSS, PMTUD, timestamps, TTL, Window Scale — каждый параметр может выдать прокси.

Прокси-серверы изменяют сетевые параметры. Это неизбежно. Вопрос только в том, насколько хорошо они это делают.

lexic.ml с 2015 года решает эти проблемы. Но идеального решения нет. Каждый новый трюк антифрода требует нового ответа от провайдеров прокси.

Главный совет: если используете прокси — проверяйте его fingerprint. curl с опцией `--verbose` покажет все параметры SYN-пакета. Анализируйте, сравнивайте с нормальными значениями. И помните: антифрод-системы тоже читают эту статью.

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