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

Как антифрод TikTok палит IPv6-прокси: TLS и поведение

Разберём механику. TikTok (ByteDance) не смотрит на IP в вакууме. Прокси на IPv6 сам по себе — не красная тряпка. Красная тряпка — рассинхрон между тем, что говорит сеть, и тем, что говорит клиент. Ниже — как это устроено и где сыпется.

Что именно собирает клиент TikTok

Приложение на старте сессии собирает телеметрию. Не только IP. Гораздо больше.

В HTTP-заголовках уходит `X-Forwarded-For` (если прокси не вырезал — а многие не вырезают), `Via`, `Forwarded`. Плюс собственные заголовки ByteDance вроде `x-tt-trace-id`, `x-tt-store-region`, `x-ss-req-ticket`. Последний — HMAC-подпись запроса, привязанная к устройству и времени.

Дальше — TLS. Клиент устанавливает соединение, и сервер видит ClientHello: набор шифров, порядок расширений, ALPN, поддерживаемые группы, эллиптические кривые, GREASE-значения. Это и есть JA3/JA4. У нативного Android-клиента TikTok отпечаток один, у iOS — другой, у веб-версии в Chrome — третий. Если вы гоняете мобильный аккаунт через Python-скрипт с `requests`, JA3 будет от OpenSSL 3.x — и это мгновенный флаг.

```bash

curl -v --tlsv1.3 --ciphers TLS_AES_128_GCM_SHA256 https://www.tiktok.com/ 2>&1 | grep -E "TLS|ALPN"

```

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

JA3 и JA4: цифры, которые важнее IP

JA3 — MD5 от строки с версией TLS, шифрами, расширениями, эллиптическими кривыми и форматами точек. JA4 — развитие идеи: более устойчив к рандомизации, разделяет транспорт. TikTok использует обе сигнатуры плюс собственные модификации.

Вот реальная картина по популярным клиентам (данные из публичных JA3-баз, 2024):

| Клиент | JA3 (сокращённо) | TLS версия | ALPN |

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

| TikTok Android 32.x | `771,4865-4866-4867-49195...` | 1.3 | h2 |

| TikTok iOS 31.x | `771,4866-4867-49196...` | 1.3 | h2 |

| Chrome 122 desktop | `771,4865-4866-4867-49195...` | 1.3 | h2,http/1.1 |

| Python requests 2.31 | `771,4865-4866-4867-49195...` | 1.3 | http/1.1 |

| curl 8.5 OpenSSL | `771,4866-4867-49195...` | 1.3 | h2 |

Видите? Python и Chrome по JA3 почти неотличимы, но ALPN выдаёт: у `requests` только `http/1.1`, у Chrome — `h2`. Плюс порядок расширений разный. Это ловится на уровне edge-сервера за микросекунды.

IPv6-прокси тут ни при чём. Хоть /64 из датацентра, хоть residential — если JA3 от Python, а аккаунт заявлен как мобильный Android, вес фрода растёт.

Поведенческий слой: что видит антифрод

Сеть — только половина. Вторая — как аккаунт себя ведёт. TikTok строит граф действий: лайки, просмотры, скроллы, паузы, переходы между вкладками, время между тапами.

У реального пользователя интервалы между свайпами — 1.5–4 секунды, с дисперсией. У бота — 200–400 мс ровно, без разброса. Джиттер отсутствует. Это видно на гистограмме межсобытийных интервалов: у живого человека экспоненциальное распределение, у скрипта — дельта-функция.

Ещё смотрят на паттерн просмотра. Человек смотрит видео до конца выборочно: 30% досматривает, 50% бросает на середине, 20% проматывает. Бот либо досматривает всё (что физически невозможно за сессию в 40 минут), либо проматывает всё подряд. Обе крайности — маркер.

Как IPv6-прокси связан с поведением

Тут тонкий момент. IPv6-адрес — не просто точка выхода. Это префикс /64, и TikTok группирует аккаунты по префиксам. Если 200 аккаунтов выходят из одного /64, даже с разных адресов внутри — это один кластер. Датацентровые префиксы (например, Hetzner `2a01:4f8::/32`, OVH `2001:41d0::/32`) помечены как hosting в базах вроде MaxMind и IPinfo.

```python

import ipaddress, requests

def check_prefix(ip):

r = requests.get(f"https://ipinfo.io/{ip}/json", timeout=5)

data = r.json()

return {

"prefix": str(ipaddress.ip_network(f"{ip}/64", strict=False)),

"org": data.get("org"),

"privacy": data.get("privacy", {}),

}

print(check_prefix("2a01:4f8:c17:1234::1"))

```

Вывод покажет `Hetzner Online GmbH` — и всё, префикс в чёрном списке датацентров. Даже если каждый адрес свежий, /64 один. Антифрод не дурак.

Кейс: мобильный аккаунт через датацентровый /64

Проблема: аккаунт TikTok, заявленный как пользователь из Германии на Android. Прокси — IPv6 из Hetzner, /64 `2a01:4f8:c17::/48`. Через 6 часов — теневой бан, охваты упали с 12k до 200.

Причина: три несовпадения. Первое — ASN. Hetzner AS24940 — hosting. Второе — JA3 от Python-скрипта, а не от нативного клиента. Третье — rDNS: `static.123.456.clients.your-server.de` в обратной зоне. Реальный мобильный оператор так не резолвит.

Детали: TikTok шлёт запросы к `api16-normal-c-useast1a.tiktokv.com`. Сервер отвечает `x-tt-logid`, по которому видно, что сессия попала в `risk_level: high`. Заголовок `x-tt-store-region` при этом `DE`, а `x-tt-net-type` — `wifi`, хотя IP датацентровый. Мобильный на Wi-Fi из датацентра — сам по себе странно.

Решение: residential IPv6 (реальный мобильный оператор, /64 из пула, который ротируется), JA3 от нативного клиента через проксирование реального устройства или через библиотеку вроде `curl_cffi` с `impersonate="chrome120"` (для веба) либо через эмулятор с настоящим APK. Плюс поведенческий джиттер в скрипте.

JA3-спуфинг: что работает, а что нет

`curl_cffi` — популярный костыль. Он подменяет TLS-отпечаток на браузерный.

```python

from curl_cffi import requests

r = requests.get(

"https://www.tiktok.com/api/recommend/item_list/",

impersonate="chrome120",

proxies={"https": "http://[2a01:4f8:c17:1234::1]:3128"},

timeout=10,

)

print(r.status_code, r.headers.get("x-tt-logid"))

```

Работает против JA3-проверки. Не работает против проверки ALPN-согласованности с остальной телеметрией: если запрос идёт с `User-Agent: TikTok 32.5.4`, а JA3 — Chrome, это рассинхрон. Антифрод сравнивает заявленный клиент с фактическим отпечатком. Несовпадение — флаг.

Второй грабли: HTTP/2 fingerprint. Chrome шлёт `SETTINGS` с конкретными параметрами (`HEADER_TABLE_SIZE=65536`, `MAX_CONCURRENT_STREAMS=1000`, `INITIAL_WINDOW_SIZE=6291456`). Python-клиент шлёт другие. Если JA3 подделан под Chrome, а HTTP/2-фреймы — от библиотеки, палево.

Что видит сервер на уровне TCP

До TLS есть ещё TCP. TTL, размер окна, MSS, порядок опций (MSS, SACK, Timestamps, NOP, WS). У мобильного Android и у Linux-сервера прокси эти параметры разные. Плюс IPv6-специфика: extension headers, hop limit.

```bash

Смотрим TCP-параметры соединения через прокси

ss -tin dst [2a01:4f8:c17:1234::1]

```

Вывод покажет `rtt`, `cwnd`, `mss`. Если MSS 1440 (типично для туннеля) вместо 1460 (нативный IPv6), это намёк на туннелирование. Не приговор, но в копилку.

Ещё один маркер — IPv6 privacy extensions. Реальный клиент Android генерирует temporary addresses (RFC 4941), они меняются раз в несколько часов. Датацентровый прокси отдаёт статический адрес. За сессию из 500 запросов адрес не сменился ни разу — для мобильного это аномалия.

Кейс: ротация /64 без ротации поведения

Проблема: ферма из 50 аккаунтов, каждый на своём IPv6 из пула 500 адресов. Ротация каждые 10 минут. Через сутки — блокировка 40 из 50.

Причина: ротация адресов была, ротации поведения — нет. Все 50 аккаунтов лайкали одни и те же видео в первые 3 минуты после публикации автора. Граф совпадений: 50 узлов, 200 общих рёбер. Антифрод строит косинусную близость между векторами действий. У этих аккаунтов она 0.94 — почти идентичны.

Детали: время от регистрации до первого лайка — 47 секунд у всех (скрипт без рандомизации). Средний интервал между действиями — 312 мс с дисперсией 8 мс. У живых — 800–2500 мс с дисперсией 400+. Плюс все 50 заходили с одинаковым `x-tt-store-region=RU` и одинаковым `Accept-Language: ru-RU,ru;q=0.9`.

Решение: разнести поведение. Рандомизировать задержки по логнормальному распределению. Разные часовые пояса и языки. Не лайкать одно и то же. И — да, разные /64, а не только разные адреса внутри одного.

Роль /64 в кластеризации

TikTok (как и большинство антифродов) работает с префиксами, не с адресами. /64 — минимальная единица для IPv6-подсети по RFC 4291. Один /64 = один «дом» в модели.

Если у вас 1000 адресов из одного /48, но раскиданных по 16 /64 — это 16 кластеров. Если все 1000 в одном /64 — один кластер, и вес каждого аккаунта умножается на «подозрительность соседей». Провайдеры вроде lexic.ml выдают именно отдельные /64 на сессию или на пул — это технически оправдано: антифрод видит разные подсети, а не одну.

Проверить, в каком /64 сидит адрес, просто:

```python

import ipaddress

addr = ipaddress.ip_address("2a01:4f8:c17:1234:5678:9abc:def0:1")

print(addr.reverse_pointer) # обратная зона

print(ipaddress.ip_network(f"{addr}/64", strict=False)) # префикс

```

Если reverse pointer указывает на датацентр — префикс уже помечен. Хороший residential-прокси резолвится в домен оператора (`dynamic-2a01-...telekom.de` или подобное).

Кейс: рассинхрон часового пояса и IP-геолокации

Проблема: аккаунт заявлен как пользователь из США. IPv6-прокси — residential, из Техаса. Логин проходит. Через 2 дня — запрос верификации по SMS.

Причина: часовой пояс устройства (`Asia/Shanghai`), язык системы (`zh-CN`), но IP — США. Плюс `x-tt-tz-offset` в заголовках — `-28800` (UTC+8). Антифрод сверил: IP говорит US/Central (UTC-6), устройство — UTC+8. Разница 14 часов. Реальный путешественник так не летает за сессию.

Детали: TikTok шлёт `x-tt-tz-offset` и `x-tt-device-locale`. Сервер сверяет с геолокацией IP и с историей аккаунта. Если аккаунт три месяца был в UTC+8, а тут резко UTC-6 — это либо переезд (редко), либо прокси (часто). Флаг.

Решение: согласовать всё. Прокси в UTC+8, локаль zh-CN, часовой пояс Asia/Shanghai. Или наоборот — всё под US. Рассинхрон любого из трёх параметров повышает риск-скор.

Что реально работает

Не существует одной кнопки. Антифрод TikTok — композитный: TLS, HTTP/2, TCP, телеметрия приложения, поведение, граф аккаунтов, IP-репутация. Прокси решает только сетевой слой. Остальное — на клиенте.

Рабочая схема выглядит так: residential IPv6 с отдельными /64, ротация по сессиям, а не по запросам. Клиент — либо реальное устройство, либо эмулятор с нативным APK и правильным JA3. Поведение — с рандомизацией по логнормальному распределению, с паузами, с разными паттернами досмотра. Согласованность локали, часового пояса, языка и IP.

И главное — не гнать 200 аккаунтов из одного /64. Даже идеальный JA3 не спасёт, если соседи по префиксу уже в бане.

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