TCP fingerprint и MTU: как антифрод видит прокси
Содержание
- TCP fingerprint: цифровой отпечаток железа
- MTU-аномалии: дыры в туннелях
- TTL и hop limit: считаем прыжки
- TCP timestamps: синхронизация времени
- Window scaling: размер окна
- MSS clamping: как его обмануть
- TCP option order: канонический порядок
- IP ID: счётчик пакетов
- Initial Sequence Number: ISN генерация
- TCP timestamp echo: задержка ответа
- SACK permitted: selective acknowledgment
- ECN: explicit congestion notification
- Как защититься: практические советы
- Real-world кейс: бан на Cloudflare
- Что дальше: ML на fingerprint
- Итог
Антифрод-системы перестали полагаться только на IP-репутацию. Слишком много легитимных пользователей сидят за CGNAT. Вместо этого они копают глубже — на уровень TCP-стека и сетевых пакетов.
TCP fingerprint: цифровой отпечаток железа
Каждая ОС собирает TCP-пакеты по-своему. Разный порядок опций, разные значения window scale, разные тайминги. Это и есть TCP fingerprint — уникальная сигнатура стека.
Пример: Linux 6.x отправляет SYN-пакет с опциями в порядке: MSS, SACK permitted, Timestamp, Nop, Window Scale. Windows 11 — иначе: MSS, SACK permitted, Timestamp, Window Scale, Nop. Мелочь? Для антифрода — нет.
p0f, uMatrix, JA3 — инструменты, которые собирают эти сигнатуры. База p0f содержит 200+ профилей ОС. Когда с одного IP приходит трафик с fingerprint Linux 6.2, а через минуту — Windows 10 — это подозрительно.
MTU-аномалии: дыры в туннелях
MTU прокси-сервера почти всегда отличается от MTU клиента. Прямое подключение через Ethernet — 1500 байт. PPPoE — 1492. VPN-туннели — 1400-1450. GRE — 1476.
Разница в 50-100 байт — триггер для антифрода. Система меряет размер первого пакета в соединении. Если клиент шлёт MSS 1460 (стандарт Ethernet), а сервер отвечает MSS 1400 — прокси-туннель.
Было: сервер на nginx 1.24 с MTU 1500. Клиенты из РФ шли через прокси с MTU 1400. Система видела: 80% запросов с MSS 1460, 20% — с MSS 1360. Прокси срезал 100 байт на заголовки. Решение: форсировать MSS на прокси-сервере через iptables.
TTL и hop limit: считаем прыжки
TTL в IP-пакетах — ещё один маркер. Windows стартует с 128, Linux — 64, маршрутизаторы Cisco — 255. Прокси уменьшает TTL на количество прыжков до себя.
Если клиент за прокси с TTL=64, а после прокси TTL=58 — антифрод видит 6 прыжков. Нормально. Но когда TTL клиента = 128, а после прокси = 120 — прыжков 8, но fingerprint показывает Linux. Несостыковка.
Пример: пользователь в РФ, прокси в Нидерландах. TTL клиента 64, после прокси 52. 12 прыжков — многовато для Европы. Антифрод считает: либо клиент далеко, либо прокси. Блокировка.
TCP timestamps: синхронизация времени
TCP-опция Timestamp содержит два значения: tsval (отправитель) и tsecr (получатель). Разница между ними — RTT. Антифрод смотрит на стабильность этой разницы.
Прямое соединение: RTT 10-50 мс, разброс 5-10 мс. Прокси: RTT 100-300 мс, разброс 30-100 мс. Плюс timestamps идут с частотой 1 мс или 10 мс в зависимости от ОС. Смена частоты внутри сессии — прокси.
Было: клиент на Windows 10 (timestamp frequency 1 мс) через OpenVPN на Linux (frequency 10 мс). Антифрод видел: tsval растёт на 1 каждую мс, потом на 10. Через 5 секунд — бан.
Window scaling: размер окна
Window scale — множитель размера TCP-окна. Linux использует 7 (максимум 1 МБ), Windows — 8 (2 МБ), FreeBSD — 6 (512 КБ). Прокси часто наследует window scale от клиента, но не всегда.
Если клиент шлёт window scale 7, а прокси отвечает 8 — несовместимость. Антифрод проверяет: window scale клиента и сервера должны совпадать для двустороннего трафика.
Пример: nginx за haproxy. Haproxy сбрасывает window scale до 6. Клиент с Windows (scale 8) получает ответ с scale 6. Антифрод видит: клиент просил 8, сервер дал 6. Прокси.
MSS clamping: как его обмануть
MSS clamping — принудительная установка MSS на маршрутизаторе. Прокси часто режут MSS до 1400-1450, чтобы избежать фрагментации. Но это палит прокси.
Решение: не резать MSS, а разрешить PMTU discovery. Прокси должен пропускать ICMP Fragmentation Needed. Тогда клиент сам подстроит MSS под реальный MTU пути.
Пример: прокси на Linux с iptables:
```
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
```
Это не режет MSS принудительно, а подстраивает под PMTU. Fingerprint остаётся чистым.
TCP option order: канонический порядок
Каждая ОС имеет канонический порядок TCP-опций. Linux: MSS, SACK, Timestamp, Nop, Window Scale. Windows: MSS, Nop, Window Scale, Nop, Nop, Timestamp. MacOS: MSS, Nop, Window Scale, Nop, Timestamp, SACK.
Прокси на OpenBSD может переставлять опции. Антифрод сравнивает порядок с базой. Несовпадение — прокси.
Пример: клиент Linux отправляет SYN с порядком [MSS, SACK, TS, Nop, WS]. Прокси на FreeBSD отвечает [MSS, Nop, WS, TS, SACK]. Антифрод видит два разных fingerprint. Бан.
IP ID: счётчик пакетов
IP ID — 16-битный идентификатор пакета. Linux использует случайный ID. Windows — инкрементный. Прокси может менять IP ID на своих пакетах.
Если клиент шлёт пакеты с IP ID=0x1234, 0x1235, 0x1236 (инкремент), а прокси — 0xABCD, 0xABCE, 0xABCF — два разных счётчика. Антифрод видит: трафик идёт через промежуточный узел.
Было: клиент на Windows 10 (инкрементный IP ID) через Squid на Linux (случайный IP ID). Антифрод замечал: IP ID клиента растёт на 1, IP ID сервера случайный. Через 10 запросов — бан.
Initial Sequence Number: ISN генерация
ISN — начальный номер последовательности. Linux генерирует ISN на основе хэша (IP, порт, секретный ключ). Windows — на основе таймера. Разные ОС — разные ISN.
Прокси на Linux генерирует ISN по своему алгоритму. Если клиент Windows, а прокси Linux — ISN клиента предсказуем (таймер), ISN прокси — хэш. Антифрод коррелирует.
Пример: клиент Windows 11 (ISN = time-based) через OpenVPN на Linux (ISN = hash-based). Антифрод видит: ISN клиента растёт линейно, ISN сервера — случайно. Прокси.
TCP timestamp echo: задержка ответа
Timestamp echo (tsecr) — время получения последнего пакета. Антифрод меряет разницу между отправкой tsval и получением tsecr. Это RTT.
Прокси добавляет свою задержку. Если RTT клиент-прокси 50 мс, прокси-сервер 100 мс — общий RTT 150 мс. Но tsecr от прокси показывает 100 мс. Несоответствие.
Было: клиент в Москве, прокси в Амстердаме, сервер в Нью-Йорке. RTT клиент-прокси 80 мс, прокси-сервер 100 мс. Антифрод видел: tsval клиента = 1000, tsecr от сервера = 1080. Разница 80 мс, но реальный RTT 180 мс. Прокси.
SACK permitted: selective acknowledgment
SACK — опция выборочного подтверждения. Linux и Windows поддерживают SACK. Но некоторые прокси (старые Squid) отключают SACK.
Если клиент шлёт SYN с SACK permitted, а прокси отвечает SYN-ACK без SACK — антифрод видит несовместимость. Либо прокси старый, либо специально отключил.
Пример: клиент MacOS (SACK включён) через HAProxy 2.4 (SACK отключён). Антифрод видит: клиент просил SACK, сервер не дал. Прокси.
ECN: explicit congestion notification
ECN — опция уведомления о перегрузке. Linux поддерживает ECN с версии 2.6. Windows — с 10. MacOS — с 10.12. Прокси может не поддерживать ECN.
Если клиент шлёт SYN с ECN, а прокси отвечает без ECN — несовместимость. Антифрод видит: клиент современный, прокси старый.
Было: клиент на Ubuntu 22.04 (ECN включён) через nginx 1.18 (ECN отключён). Антифрод замечал: SYN с ECN, SYN-ACK без ECN. Бан.
Как защититься: практические советы
Первое: используй прокси с той же ОС, что и клиент. Linux-клиент — Linux-прокси. Windows-клиент — Windows-прокси. Тогда fingerprint совпадает.
Второе: форсируй одинаковые TCP-опции. На прокси-сервере настрой:
```
sysctl -w net.ipv4.tcp_sack=1
sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.ipv4.tcp_window_scaling=1
sysctl -w net.ipv4.tcp_ecn=0
```
Третье: используй MSS clamping с PMTU discovery. Не режь вручную.
Четвёртое: проверяй TTL. Если клиент за прокси, TTL после прокси должен быть на 1-2 меньше, чем у клиента. Не больше.
Пятое: настраивай IP ID. На Linux можно установить случайный IP ID:
```
sysctl -w net.ipv4.ip_id_random=1
```
Real-world кейс: бан на Cloudflare
Cloudflare использует TCP fingerprint для обнаружения прокси. Пример: клиент в РФ через прокси в Германии. Cloudflare видел: fingerprint Linux 6.2, TTL 52, MSS 1460. Но геолокация IP — Германия. Несоответствие.
Решение: на прокси форсировали fingerprint Windows 10 (через iptables и изменение TTL). TTL выставили 128. MSS оставили 1460. Cloudflare перестал банить.
Что дальше: ML на fingerprint
Антифрод-системы переходят на ML. Они собирают тысячи fingerprint и обучают модель. Модель находит аномалии, которые не видны в правилах.
Пример: fingerprint клиента — Linux 6.2, но RTT 200 мс. Обычно Linux 6.2 с RTT 200 мс — это прокси. Модель учится на таких паттернах.
Прокси-сервисы тоже адаптируются. Например, lexic.ml использует динамическую подстройку fingerprint под клиента. Это снижает вероятность обнаружения.
Итог
TCP fingerprint и MTU-аномалии — мощные инструменты антифрода. Они видят прокси там, где IP-репутация молчит. Защита требует глубокого понимания TCP-стека и настройки каждого параметра.
Прокси без настройки fingerprint — дыра. Любой антифрод с p0f или JA3 найдёт его за 5 секунд. Настройка занимает час, но даёт недели работы без банов.