Почему антифрод-системы маркетплейсов вычисляют IPv6-прокси по паттерну TTL и как это обойти
Содержание
- Как TTL работает на самом деле
- Почему IPv6 ломает привычную картину
- Паттерн стабильности TTL — главный маркер
- stdev < 0.3 and unique == 1 on 50+ samples -> datacenter proxy
- Как IPv6-прокси выдают себя по хоп-каунту
- Что видит антифрод на уровне TCP
- Почему обычный SOCKS5 не спасает
- Как подделать TTL правильно
- на прокси-сервере, iptables TTL mangling
- Кейс: маркетплейс с 40 млн MAU
- Кейс: API-интеграция и rate limiting
- Кейс: мобильный IPv6 и CGNAT
- Что реально работает в 2025
- проверка своего исходящего TTL
- проверка IPv6 hop limit
- Практический чеклист
TTL — это поле в IP-заголовке, которое уменьшается на единицу при прохождении каждого роутера. Изначально оно было придумано для защиты от петель маршрутизации. Но антифрод-команды маркетплейсов давно научились использовать его как дешёвый сигнал для детекта прокси. И IPv6 тут — отдельная история.
Как TTL работает на самом деле
Стандартные начальные значения: 64 (Linux, macOS, Android), 128 (Windows), 255 (сетевое оборудование Cisco/Juniper). Каждый хоп уменьшает TTL на 1. До получателя пакет доходит с TTL = initial − hop_count.
Если сервер маркетплейса видит входящий пакет с TTL=53, он делает простую арифметику: 64 − 53 = 11 хопов. Для пользователя из Москвы, заходящего через московский мобильный оператор, 11 хопов — нормально. Для пользователя, который якобы в Москве, но реально сидит через прокси во Франкфурте, — 11 хопов уже подозрительно мало или наоборот много, в зависимости от маршрута.
Антифрод не смотрит на TTL в отрыве. Он строит профиль: с какой ОС обычно приходит пользователь, какой у него ASN, какой TTL, какая MTU. И когда TTL перестаёт биться с заявленной ОС — включается флаг.
Почему IPv6 ломает привычную картину
В IPv4 большинство домашних сетей — это NAT, и до сервера доезжает TTL роутера провайдера. В IPv6 NAT почти нет, у клиента реальный глобальный адрес, и путь от клиента до сервера короче на один-два хопа. Типичный TTL для IPv6-клиента с Linux — 62-63, а не 54-58 как в IPv4.
Прокси-сервисы, которые просто пробрасывают TCP через SOCKS5, не трогают TTL. Пакет идёт от прокси-сервера, и его TTL определяется маршрутом от прокси до маркетплейса. Если прокси-сервер в датацентре, TTL будет 64 − 3 = 61 или 64 − 5 = 59. Стабильно. Идеально стабильно, чего у реальных жилых клиентов не бывает.
Вот тут и начинается самое интересное.
Паттерн стабильности TTL — главный маркер
У реального пользователя TTL скачет. Он переключается между Wi-Fi и LTE, роутер меняет маршрут, провайдер перекидывает трафик на другой аплинк. TTL может отличаться на 1-3 единицы между запросами в течение часа.
У прокси-сервера в датацентре TTL одинаковый на всех запросах. Буквально идентичный. 10 000 запросов — 10 000 раз TTL=59.
Антифрод считает дисперсию TTL по сессии. Если она нулевая на длинном окне — это не человек. Это сервер.
```python
import statistics
from collections import defaultdict
def ttl_profile(packets):
by_session = defaultdict(list)
for p in packets:
by_session[p.session_id].append(p.ttl)
result = {}
for sid, ttls in by_session.items():
if len(ttls) < 20:
continue
result[sid] = {
"mean": statistics.mean(ttls),
"stdev": statistics.pstdev(ttls),
"unique": len(set(ttls)),
"samples": len(ttls),
}
return result
stdev < 0.3 and unique == 1 on 50+ samples -> datacenter proxy
```
Этот код — упрощённая модель того, что крутится у маркетплейсов в real-time. Порог stdev ниже 0.5 при более чем 30 сэмплах уже даёт вес в скоринге.
Как IPv6-прокси выдают себя по хоп-каунту
Прокси на IPv6 почти всегда живёт в датацентре. Путь от датацентра до маркетплейса часто идёт через крупные IX (DE-CIX, AMS-IX, MSK-IX). Хопов немного: 4-7. TTL на выходе — 57-60.
Жилой IPv6-клиент в Москве через МГТС или Ростелеком идёт через 8-14 хопов. TTL — 50-56.
Разница в 4-8 единиц TTL — это уже устойчивый сигнал. Антифрод строит гистограмму TTL по ASN. Если ASN заявлен как residential, а TTL попадает в диапазон, характерный для хостинга — флаг.
Плюс есть вторая проверка. IPv6-адрес прокси часто в префиксе /64, который принадлежит хостеру. WHOIS по /64 выдаёт Hetzner, OVH, DigitalOcean. Это уже не TTL, но в паре с TTL даёт очень сильный сигнал.
Что видит антифрод на уровне TCP
TTL — не единственное. Есть ещё TCP timestamps (RFC 7323). Опция TCP timestamp содержит монотонно растущее значение от загрузки хоста. У прокси-сервера оно растёт линейно и быстро — uptime сервера в днях. У домашнего роутера — сбрасывается при перезагрузке, растёт медленнее.
Ещё window size. Linux по умолчанию 65535 или с window scaling до 29200. Windows — 64240. Прокси-серверы на Linux в датацентре часто имеют тюнингованные значения — 29200, 14600, 5840. Это тоже фиксируется.
Комбинация TTL + TCP timestamp + window size + MSS даёт fingerprint, по которому p0f или собственный классификатор маркетплейса определяет ОС и тип хоста за 3 пакета.
Почему обычный SOCKS5 не спасает
SOCKS5 работает на уровне TCP. Он не модифицирует IP-заголовок. TTL пакета, вышедшего с прокси-сервера, — это TTL маршрута прокси → маркетплейс. Клиент никак на него не влияет.
То же с HTTP-прокси и с большинством VPN. WireGuard, OpenVPN в режиме tun — тоже. Пакет выходит с IP прокси-сервера, TTL ставит ядро прокси-сервера, и всё.
Чтобы управлять TTL, нужно либо менять его на самом прокси-сервере (что заметно и требует root), либо использовать прокси, который умеет подделывать IP-заголовок перед отправкой. Таких мало.
Как подделать TTL правильно
Есть три подхода. Первый — raw sockets с IP_HDRINCL на прокси-сервере. Вы формируете IP-заголовок вручную и ставите нужный TTL. Работает, но требует CAP_NET_RAW и полностью ручного стека TCP.
```bash
на прокси-сервере, iptables TTL mangling
iptables -t mangle -A POSTROUTING -o eth0 -j TTL --ttl-set 56
ip6tables -t mangle -A POSTROUTING -o eth0 -j HL --hl-set 56
```
Это грубо. Все клиенты получат одинаковый TTL=56. Если антифрод видит, что у клиента с заявленной Windows 11 TTL=56, а должен быть 128 − hops — палево.
Второй подход — per-session TTL. Каждой сессии присваивается свой TTL из диапазона, характерного для заявленного ASN и ОС. Это уже требует кастомного прокси.
Третий — использовать residential IPv6-прокси, где TTL естественный. Дороже, но не палится по этому конкретному сигналу.
Кейс: маркетплейс с 40 млн MAU
Клиент — продавец на крупном маркетплейсе, работал через IPv6-прокси в датацентре Hetzner (Falkenstein). Заявленный регион — Москва. Аккаунт с историей 2 года.
Проблема: массовые блокировки при попытке выставить товары через API. Блокировка приходила через 5-15 минут после начала сессии.
Причина: TTL входящих пакетов стабильно 58. ASN — AS24940 (Hetzner). По их данным, для московских residential IPv6 TTL распределён в диапазоне 50-56, stdev 1.1. У нашего клиента stdev 0.0 на 200+ пакетах. Плюс TCP timestamp с uptime 47 дней без сброса.
Решение: переезд на residential IPv6-прокси через местного провайдера в Москве, с реальным роутером Keenetic и TTL 63-64 с естественными колебаниями. Блокировки прекратились. Через lexic.ml маршрутизация строилась так, чтобы исходящий TTL соответствовал профилю жилого клиента МГТС — 62-63 с рандомизацией ±1 на каждые 50 пакетов.
Кейс: API-интеграция и rate limiting
Другой сценарий. Компания делала интеграцию с маркетплейсом для автоматизации заказов. 12 аккаунтов, все через один IPv6-префикс /64 от DigitalOcean.
Проблема: через 3 дня все аккаунты получили shadowban — заказы создавались, но не отображались в поиске.
Причина: антифрод сгруппировал аккаунты по /64 префиксу и TTL=59 с нулевой дисперсией. 12 аккаунтов с одинаковым fingerprint — классический признак фермы.
Решение: разнести по 12 разным /64, каждый через своего провайдера. TTL рандомизировать в диапазоне 60-63 с шагом, зависящим от времени суток (эмуляция переключения Wi-Fi/LTE). Через 2 недели shadowban снялся.
Кейс: мобильный IPv6 и CGNAT
Оператор мобильной связи выдавал IPv6 через CGNAT. TTL от клиента до маркетплейса — 52-54, с колебаниями ±2 в зависимости от загрузки сети.
Пользователь работал через VPN на VPS в Амстердаме. TTL — 57, стабильно.
Проблема: маркетплейс помечал сессии как "смена локации" при переключении между приложениями на телефоне. Мобильный трафик шёл напрямую (TTL 52), а приложение через VPN (TTL 57). Разница в 5 единиц — триггер.
Решение: полностью убрать VPN, работать через мобильный IPv6 напрямую. Скорость упала с 40 Мбит/с до 18, но аккаунт перестал ловить челленджи.
Что реально работает в 2025
Чистый TTL-фингерпринт уже не единственный сигнал. Маркетплейсы смотрят на комбинацию: TTL + TCP timestamp + window size + JA4 fingerprint + ASN + поведенческие метрики. Но TTL остаётся самым дешёвым в вычислении, и его проверяют первым — на уровне kernel-bypass обработчиков (DPDK, XDP).
Обход требует не одной правки, а согласованного профиля. Если вы ставите TTL=56, но у вас TCP timestamp с uptime 47 дней и window size 29200 — это не residential, что бы вы ни делали с TTL.
```bash
проверка своего исходящего TTL
tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-syn != 0' -c 5 -v | grep 'ttl'
проверка IPv6 hop limit
tcpdump -i eth0 -nn -v 'ip6 and tcp[tcpflags] & tcp-syn != 0' -c 5 | grep 'hlim'
```
Запустите это на своём прокси, посмотрите реальные цифры. Не гадайте.
Практический чеклист
Перед тем как заходить на маркетплейс через IPv6-прокси, проверьте:
- TTL/hlim вашего исходящего трафика — совпадает ли с профилем заявленного региона и ОС
- Дисперсия TTL на длинном окне — не нулевая ли
- TCP timestamp — uptime не выглядит ли как серверный
- Window size и MSS — соответствуют ли заявленной ОС
- ASN вашего /64 — не хостинг ли
- Совпадает ли всё это с поведенческими метриками (время активности, паттерны запросов)
Если хоть один пункт выбивается — антифрод это увидит. Не сразу, но на длинном окне увидит точно. TTL — это не то, что можно "забыть подкрутить". Это то, что проверяется на каждом пакете автоматически.