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

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

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

Почему маркетплейсы смотрят на сетевой уровень

Антифрод Wildberries, Ozon, Avito и подобных площадок давно перестал быть набором эвристик на уровне cookie и User-Agent. Современный стек — это комбинация device fingerprinting (Canvas, WebGL, AudioContext), поведенческого анализа и сетевой телеметрии. Последний слой режет большинство «прокси-ферм», потому что на нём палятся даже те, кто аккуратно подменяет отпечаток браузера.

Идея простая: если с одного IP-адреса приходят запросы от десяти «разных» браузеров, но у всех десяти совпадает MTU, TCP timestamp clock rate и набор TCP-опций — вероятность того, что это один физический хост под NAT или один прокси, стремится к единице. Прокси меняет IP, но не меняет то, как ядро Linux или Windows формирует пакеты.

Разберём, что именно утекает и как это ловится.

MTU как отпечаток хоста

Maximum Transmission Unit — максимальный размер полезной нагрузки Ethernet-фрейма, который хост готов принять без фрагментации. Значения по умолчанию сильно различаются между платформами и сетевыми стеками:

| ОС / интерфейс | Типичный MTU |

|---|---|

| Linux Ethernet | 1500 |

| Windows Ethernet | 1500 |

| PPPoE (любая ОС) | 1492 |

| WireGuard | 1420 |

| OpenVPN (tun) | 1500, но PMTU часто 1400–1450 |

| Docker bridge | 1500 |

| macOS Ethernet | 1500 |

Само по себе значение 1500 ничего не говорит. Проблема в том, что прокси-сервер и клиент за ним часто имеют разный MTU, и это видно в TCP-сессиях. Если клиент сидит за VPN с MTU 1420, а прокси отдаёт пакеты с MSS 1460 (1500 − 40 байт заголовков), антифрод видит несоответствие: реальный пользователь из Москвы на домашнем Wi-Fi не может иметь такой паттерн.

Ещё интереснее — MSS clamping. Многие прокси-провайдеры настраивают iptables с `--clamp-mss-to-pmtu`, и тогда все клиенты через этот прокси имеют одинаковый MSS. Десять аккаунтов — один MSS. Это уже сигнал.

Проверить свой MTU и MSS можно так:

```bash

ping -M do -s 1472 -c 1 8.8.8.8

1472 + 28 (ICMP+IP) = 1500. Если "Frag needed" — MTU меньше.

ss -i dst 8.8.8.8

В выводе смотрите rtt, rcv_mss, snd_mss

```

TCP timestamps: часы, которые тикают одинаково

Опция TCP timestamp (RFC 7323) добавляет в каждый сегмент два 32-битных поля: TSval и TSecr. TSval — это текущее значение монотонных часов хоста, обычно с шагом 1 мс, 10 мс или 1 тик в зависимости от `tcp_timestamps` и частоты ядра.

Что важно для антифрода: **TSval растёт линейно и предсказуемо**. По разнице TSval между пакетами можно вычислить uptime хоста с точностью до минут. А по абсолютному значению — сопоставить два соединения, пришедшие с разных IP, но с одного физического хоста.

Пример: клиент подключился через прокси A в 10:00:00 с TSval = 123456789. Через час подключился через прокси B с TSval = 123460389. Разница 3600 секунд при частоте 1000 Гц — идеальное совпадение. Антифрод складывает это в граф связей.

На Linux частота timestamp задаётся `tcp_timestamps` и зависит от `HZ`. На большинстве современных ядер (5.x, 6.x) это 1000 Гц. На Windows — 1000 Гц, но с другими смещениями. На macOS — 1000 Гц, но стартовое значение рандомизируется при загрузке.

Снять timestamps у себя:

```bash

sysctl net.ipv4.tcp_timestamps

1 — включено, 0 — выключено

```

Отключение помогает, но ломает PAWS (Protection Against Wrapped Sequences) и может снизить производительность на длинных fat-pipe соединениях. Не панацея.

Как это выглядит в логах антифрода

Площадки не показывают свои дашборды, но по косвенным признакам (частота блокировок, капчи, требования верификации) можно восстановить логику. Типичный пайплайн:

1. Сбор TCP-заголовков на edge-балансировщике (LVS, nginx stream, HAProxy).

2. Извлечение полей: IP, MSS, window size, TCP options (order и набор), TSval, TSecr.

3. Нормализация и хеширование в «сетевой fingerprint».

4. Кластеризация по fingerprint + поведенческим признакам.

Ключевой момент — **порядок TCP-опций**. Linux, Windows и macOS перечисляют опции в разном порядке и с разным набором. Это уже классический пассивный fingerprint (p0f). Добавьте к этому timestamp clock rate — и вы получите устойчивый идентификатор хоста, который переживает смену IP.

Пример на Python, как выглядит парсинг через scapy:

```python

from scapy.all import sniff, TCP, IP

def fingerprint(pkt):

if TCP in pkt and pkt[TCP].options:

opts = [opt[0] for opt in pkt[TCP].options]

tsval = next((opt[1][0] for opt in pkt[TCP].options if opt[0] == 'Timestamp'), None)

print(f"src={pkt[IP].src} opts={opts} tsval={tsval} win={pkt[TCP].window}")

sniff(filter="tcp and port 443", prn=fingerprint, count=20)

```

На реальном трафике через один прокси вы увидите одинаковые `opts` и почти линейный рост `tsval` для всех «разных» клиентов.

Почему IPv6 меняет картину

В IPv6 заголовок фиксированный (40 байт), опции ушли в extension headers. MSS считается от 1280 (минимальный MTU для IPv6) до 1500 и выше. Провайдеры часто ставят MTU 1500, но туннели (6in4, 6rd, Teredo) дают 1280–1480.

Прокси с поддержкой IPv6 (как lexic.ml) позволяет каждому клиенту получить отдельный /64 или /128, и это снимает проблему «один IP — много аккаунтов». Но MTU и timestamps всё равно утекают, если не изолировать сетевой стек на стороне клиента.

Ключ в том, что IPv6-адрес сам по себе не спасает. Антифрод маркетплейсов уже год как работает с IPv6 не хуже, чем с IPv4. Более того, наличие IPv6 у «домашнего» пользователя из региона, где IPv6 почти не развёрнут (например, часть регионов РФ), — само по себе подозрительно.

Что реально связывает аккаунты

Соберём признаки по убыванию значимости для антифрода:

- **TCP timestamp clock rate и drift** — почти уникален для хоста, переживает смену IP.

- **Порядок и набор TCP options** — фактически отпечаток ОС + версии ядра.

- **MSS** — выдаёт туннели, VPN, нестандартные MTU.

- **Window size и его scaling** — зависит от `tcp_rmem`, часто дефолтный.

- **Начальный ISN (Initial Sequence Number)** — на Linux рандомизирован, но есть корреляции при быстром переподключении.

- **Jitter и RTT** — выдаёт физическое расположение и загрузку канала.

Комбинация первых трёх признаков даёт устойчивый хеш, который антифрод хранит месяцами. Смена прокси, браузера и даже устройства не помогает, если сетевой стек не меняется.

Изоляция на стороне клиента

Единственный способ реально разорвать связь — изолировать сетевой стек для каждого аккаунта. Варианты:

**Network namespaces в Linux.** Каждый namespace имеет свои sysctl, включая `tcp_timestamps`, `tcp_rmem`, `tcp_wmem`. Это даёт разные MSS, window и даже разное поведение timestamps.

```bash

ip netns add acc1

ip netns exec acc1 sysctl -w net.ipv4.tcp_timestamps=0

ip netns exec acc1 sysctl -w net.ipv4.tcp_rmem="4096 65536 4194304"

ip netns exec acc1 curl -x socks5://proxy:1080 https://example.com

```

**Разные ядра / ВМ.** Тяжелее, но эффективнее. Каждая ВМ имеет свой uptime, свои timestamps, свой ISN seed.

**Пользовательские TCP-стеки.** gVisor, lwIP, пользовательские реализации в Go/Rust. Полный контроль над всеми полями, включая рандомизацию TSval.

Первый вариант — минимальный костыль, третий — самый чистый, но требует переписывания клиента.

Разбор одного подключения

Допустим, вы видите в логах два аккаунта с разными IP: 203.0.113.42 и 198.51.100.17. Оба заходят с Chrome 120 на Windows 10, оба из Москвы. Антифрод смотрит на TCP:

```

Conn A: MSS=1460, win=64240, opts=[M,S,TS,N,N,W], TSval=884213

Conn B: MSS=1460, win=64240, opts=[M,S,TS,N,N,W], TSval=884219

```

Разница TSval — 6 мс, при том что соединения разделены минутами реального времени. Это значит, что timestamp clock rate не 1000 Гц, а, скажем, 1 Гц, либо TSval синхронизирован искусственно. В любом случае — оба соединения идут с одного ядра с одинаковыми настройками. Вердикт: связаны.

Если бы у Conn B был MSS=1420 и opts=[M,S,TS,N,W] — это уже другой стек, другая связь, менее очевидная. Но window 64240 совпадает — Linux с дефолтным `tcp_rmem`. Тоже сигнал.

Практика: что проверять у своего прокси

Минимальный чек-лист, если вы гоняете несколько аккаунтов через один прокси:

```bash

MSS и MTU на пути

tracepath -n example.com

TCP options в исходящих

sudo tcpdump -i eth0 -c 5 -vv 'tcp[tcpflags] & tcp-syn != 0' | grep -A2 options

Timestamps

sudo tcpdump -i eth0 -c 5 -vv 'tcp and port 443' | grep timestamp

```

Если видите одинаковые MSS, window и монотонный TSval на всех сессиях — вас свяжут. Не сразу, но при накоплении данных.

Итог

Антифрод маркетплейсов давно ушёл ниже прикладного уровня. IP-адрес — это первое, что меняют, и первое, что перестало быть достаточным. MTU, MSS, порядок TCP-опций и timestamp clock rate формируют отпечаток, который переживает смену IP, cookie и даже браузера. Разрывать эти связи нужно на уровне сетевого стека — через namespaces, отдельные ВМ или пользовательские TCP-реализации. Всё остальное — косметика, которая откладывает блокировку, но не отменяет её.

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