Twitter через IPv6 прокси: мультиаккаунтинг и обход лимитов API
Содержание
- Почему Twitter душит мультиаккаунтинг
- Как Twitter видит ваши аккаунты
- Что даёт IPv6 в мультиаккаунтинге
- Настройка прокси-сервера
- /etc/squid/squid.conf
- Проверка через curl
- Python-клиент для работы с API
- Rate limits и как их обходить
- Распределение аккаунтов по адресам
- Кейс: блокировка после смены подсети
- Кейс: утечка IPv4 через DNS
- Кейс: MTU и фрагментация
- Мониторинг и ротация
- Итоговая архитектура
Почему Twitter душит мультиаккаунтинг
Twitter (X) за последние годы выстроил многоуровневую систему детекции. Раньше хватало разных email — теперь этого мало. Платформа смотрит на fingerprint браузера, поведенческие паттерны, IP-адрес, TLS-отпечаток (JA3/JA4), HTTP/2 fingerprint и timing запросов. Каждый из этих параметров складывается в общий score, и когда он превышает порог — аккаунт улетает в теневой бан или на верификацию.
IPv4-адреса в этом уравнении — самое слабое звено. Датацентровые диапазоны давно помечены, резидентные прокси дорогие и медленные, а мобильные — вообще лотерея. IPv6 тут даёт неожиданное преимущество: пул адресов настолько велик, что каждый аккаунт может получить уникальный /128 из одной /64-подсети провайдера. И выглядеть это будет как обычный домашний пользователь.
Проблема в том, что Twitter это тоже знает. С 2023 года они начали агрессивно фильтровать IPv6-диапазоны хостингов. Поэтому просто «взять прокси и зайти» — не работает. Нужен грамотный подход.
Как Twitter видит ваши аккаунты
Разберём слои детекции по порядку.
Первый слой — сетевой. Twitter логирует IP, ASN, геолокацию по GeoIP2, наличие IPv6, MTU, TCP window size. Если у вас 10 аккаунтов с одного /64 — это уже красный флаг. Даже если адреса разные, подсеть одна.
Второй слой — TLS и HTTP. JA3-хеш зависит от набора шифров, расширений, порядка их следования. У curl и Chrome они разные. Если вы логинитесь через curl с одного IP, а через браузер с другого — палево.
Третий слой — поведенческий. Скорость действий, время между кликами, движения мыши, scroll-паттерны. Тут IPv6 не поможет, но комбинация с правильным прокси снижает общий риск.
Четвёртый слой — API-лимиты. У X API v2 жёсткие квоты: 300 твитов за 3 часа на пользователя, 50 запросов на чтение в 15 минут для базового тарифа. Мультиаккаунтинг частично решает это — каждый аккаунт имеет свой лимит.
Что даёт IPv6 в мультиаккаунтинге
Главное преимущество — стоимость и масштаб. Один /64 от провайдера содержит 18 квинтиллионов адресов. Даже /112 — это 65536 адресов, чего хватит на сотни аккаунтов. Стоимость такой подсети в разы ниже, чем пул резидентных IPv4.
Второе — репутация. IPv6-адреса из residential-диапазонов пока не так зашумлены, как IPv4. Многие антифрод-системы просто не имеют исторических данных по конкретному /128, поэтому стартовый trust score выше.
Третье — отсутствие NAT. Каждый аккаунт может работать со своего адреса без порт-форвардинга, что упрощает проксирование. В IPv4 вам пришлось бы держать пул адресов и маппить их, в IPv6 — просто назначать.
Минус один: часть сайтов до сих пор не поддерживает IPv6. Twitter поддерживает, но, например, некоторые CDN и антибот-провайдеры могут отдавать разный контент. Проверяйте через `curl -6`.
Настройка прокси-сервера
Базовый сценарий: Linux-сервер с выделенной /64, на нём поднимается прокси, каждый аккаунт ходит через свой адрес. Конфиг для Squid с привязкой к source IP:
```
/etc/squid/squid.conf
acl account1 src 10.0.0.1
acl account2 src 10.0.0.2
tcp_outgoing_address 2001:db8:1234:1::100 account1
tcp_outgoing_address 2001:db8:1234:1::101 account2
http_port 3128
```
Клиент подключается к прокси, а Squid подменяет исходящий адрес в зависимости от source. Простой способ, но Squid не умеет в HTTP/2, а Twitter давно на нём. Для серьёзной работы лучше использовать 3proxy или самописный решатель на Go.
Альтернатива — shadowsocks или v2ray с per-user routing. Там можно гибко разруливать по юзернейму:
```json
{
"inbounds": [{"port": 1080, "protocol": "socks", "settings": {"auth": "password", "accounts": [{"user": "acc1", "pass": "..."}]}}],
"outbounds": [{"protocol": "freedom", "settings": {"domainStrategy": "UseIPv6"}}],
"routing": {"rules": [{"user": ["acc1"], "outboundTag": "acc1-out"}]}
}
```
Проверка через curl
Перед массовым запуском убедитесь, что трафик реально уходит с нужного адреса. Простой чек через ipify или аналогичный сервис:
```bash
curl -6 --socks5-hostname user:pass@[2001:db8::1]:1080 https://api64.ipify.org?format=json
```
Ответ покажет внешний IPv6. Если он совпадает с ожидаемым — всё ок. Если видите IPv4 — прокси не поддерживает IPv6 или клиент предпочитает IPv4. Проверяйте на нескольких аккаунтах сразу:
```bash
for i in \$(seq 1 5); do
curl -6 -s --socks5-hostname "user\$i:pass@[2001:db8::1]:1080" \
https://api64.ipify.org
echo
done
```
Если все пять возвращают один адрес — проблема в конфиге. Если разные — маршрутизация работает.
Python-клиент для работы с API
Для автоматизации постов и чтения лучше использовать `httpx` с явной привязкой к прокси. Пример клиента, который ходит через IPv6-прокси и умеет ротировать аккаунты:
```python
import httpx
import asyncio
ACCOUNTS = [
{"user": "acc1", "pass": "p1", "proxy": "[2001:db8::100]"},
{"user": "acc2", "pass": "p2", "proxy": "[2001:db8::101]"},
]
async def post_tweet(account, text, token):
proxy_url = f"socks5://{account['user']}:{account['pass']}@{account['proxy']}:1080"
async with httpx.AsyncClient(proxy=proxy_url, timeout=30.0) as client:
r = await client.post(
"https://api.twitter.com/2/tweets",
headers={"Authorization": f"Bearer {token}"},
json={"text": text},
)
return r.status_code, r.json()
async def main():
tasks = [post_tweet(acc, f"test {i}", "TOKEN") for i, acc in enumerate(ACCOUNTS)]
results = await asyncio.gather(*tasks)
for status, body in results:
print(status, body.get("data", {}).get("id"))
asyncio.run(main())
```
Обратите внимание на `socks5://` — httpx через `httpx-socks` умеет работать с SOCKS5, что даёт меньше утечек, чем HTTP CONNECT. Также важно ставить таймауты: Twitter может держать соединение 60+ секунд при rate limit.
Rate limits и как их обходить
Официальные лимиты X API v2 (Basic tier, \$200/мес):
| Endpoint | Лимит | Окно |
|---|---|---|
| POST /2/tweets | 100 | 24 часа |
| GET /2/tweets | 500 | 15 минут |
| GET /2/users/me | 25 | 24 часа |
| POST /2/users/:id/following | 50 | 24 часа |
Free tier вообще смешной: 500 постов в месяц на приложение, 100 чтений. Для мультиаккаунтинга это означает — либо платить за несколько приложений, либо использовать разные токены на разных аккаунтах.
Ключевой момент: лимиты привязаны к приложению (API key), а не к IP. Поэтому IPv6-ротация тут не помогает напрямую. Зато помогает против блокировок на уровне IP — если Twitter забанил адрес за подозрительную активность, вы просто переключаетесь на следующий /128.
Для чтения без API есть неофициальные пути — через web-эндпоинты `https://x.com/i/api/graphql/...`. Они требуют `auth_token` и `ct0` из cookies, и вот тут IPv6-прокси критичны. Twitter жёстко коррелирует cookies с IP: смена адреса в середине сессии = logout.
Распределение аккаунтов по адресам
Не назначайте адреса случайно. Есть несколько правил, которые снижают риск.
Первое: один аккаунт = один /128 на всю жизнь. Не меняйте адрес между сессиями, если не хотите триггерить проверку. Twitter помнит, с каких адресов заходил аккаунт, и резкая смена геолокации — красный флаг.
Второе: группируйте аккаунты по /64. Если у вас 50 аккаунтов, разбейте их на 5-10 /64-подсетей. Внутри одной подсети адреса выглядят как соседи по дому, между подсетями — как разные провайдеры (если ASN отличается).
Третье: не смешивайте IPv6 и IPv4 в одной сессии. Если аккаунт зашёл через IPv6, все последующие запросы должны идти через IPv6. Иначе Twitter видит «прыжок» между стеками и может потребовать верификацию.
Пример распределения для 100 аккаунтов на /56-подсети:
```
2001:db8:1234:100::/64 - аккаунты 1-20
2001:db8:1234:101::/64 - аккаунты 21-40
2001:db8:1234:102::/64 - аккаунты 41-60
2001:db8:1234:103::/64 - аккаунты 61-80
2001:db8:1234:104::/64 - аккаунты 81-100
```
Внутри каждой /64 — по 20 уникальных /128. Такой расклад выглядит естественно: как будто 20 человек живут в одном доме и заходят с одного провайдера.
Кейс: блокировка после смены подсети
Пример: сервис на 30 аккаунтов работал через /64 от Hetzner. Через две недели 12 аккаунтов получили теневой бан — их твиты перестали показываться в поиске и у подписчиков. Проверка через `https://shadowban.eu` подтвердила search ban.
Причина оказалась в ASN. Hetzner — датацентр, и Twitter давно пометил их диапазоны как «хостинг». Аккаунты, которые заходили только с этих адресов, получали низкий trust score. Те, что иногда логинились с мобильного IPv4, выжили.
Решение: миграция на residential IPv6 от немецкого провайдера (Deutsche Telekom, AS3320). Стоимость выросла в 4 раза, но теневые баны прекратились. Через 3 недели часть забаненных аккаунтов восстановилась после смены адреса и паузы в активности.
Кейс: утечка IPv4 через DNS
Более коварная проблема. Прокси настроен на SOCKS5, клиент ходит через IPv6, но DNS-резолвинг идёт через локальный резолвер. В логах Twitter видно: запросы приходят с IPv6, а DNS-запросы к `api.twitter.com` — с IPv4 провайдера.
Причина: `curl` без флага `--socks5-hostname` резолвит имена локально. С `--socks5` — тоже локально. Только `--socks5-hostname` передаёт DNS через прокси.
Решение для Python: использовать `httpx-socks` с опцией `rdns=True`. Для curl — всегда `--socks5-hostname`. Для браузеров — `network.proxy.socks_remote_dns = true` в Firefox.
После фикса утечка прекратилась, и один аккаунт, который до этого висел на верификации, разблокировался через 48 часов.
Кейс: MTU и фрагментация
IPv6 не поддерживает фрагментацию на маршрутизаторах — только на источнике. Если MTU на пути меньше стандартных 1500, пакеты просто дропаются. У Twitter CDN (Fastly) MTU 1500, но у некоторых провайдеров в цепочке — 1480 или 1400.
Симптом: TLS handshake проходит, но большие POST-запросы (например, загрузка медиа) отваливаются по таймауту. Логи показывают `connection reset` через 30 секунд.
Диагностика:
```bash
ping6 -M do -s 1452 api.twitter.com
ping6 -M do -s 1400 api.twitter.com
```
Первая команда проверяет MTU 1500 (1452 + 48 байт заголовков), вторая — 1448. Если 1500 не проходит, а 1400 — да, значит, где-то узкое место.
Решение: понизить MTU на интерфейсе прокси до 1400:
```bash
ip link set dev eth0 mtu 1400
```
Это снижает пропускную способность на ~7%, но убирает дропы. Для API-запросов, где важнее стабильность, чем скорость, — правильный выбор. После фикса загрузка медиа через прокси заработала без таймаутов.
Мониторинг и ротация
Даже с правильной настройкой аккаунты будут отваливаться. Вопрос — как быстро вы это заметите. Простой мониторинг через Python:
```python
import httpx
def check_account(account, token):
proxy = f"socks5://{account['user']}:{account['pass']}@{account['proxy']}:1080"
try:
r = httpx.get(
"https://api.twitter.com/2/users/me",
headers={"Authorization": f"Bearer {token}"},
proxy=proxy,
timeout=15.0,
)
if r.status_code == 200:
return "ok", r.json()["data"]["username"]
elif r.status_code == 429:
return "ratelimit", None
elif r.status_code == 403:
return "banned", None
return f"http_{r.status_code}", None
except Exception as e:
return "error", str(e)
```
Запускайте раз в час, пишите результаты в базу. Если аккаунт возвращает 403 три раза подряд — снимайте с ротации, меняйте прокси, ждите 72 часа. Если 429 — просто пропускайте до следующего окна.
Ротация адресов внутри /64 — плохая идея. Twitter видит, что аккаунт «переехал» с одного адреса на другой в той же подсети, и это выглядит подозрительно. Лучше держать привязку аккаунт→адрес жёстко и ротировать только при блокировке.
Инфраструктура вроде lexic.ml как раз даёт готовые пулы IPv6-адресов с привязкой к подсетям, что упрощает эту схему — не нужно самому возиться с BGP и аллокацией /64.
Итоговая архитектура
Собираем всё вместе.
Пул IPv6-подсетей от residential-провайдеров. Прокси-сервер на каждом /64 (или виртуалка с маршрутизацией). Клиенты подключаются через SOCKS5 с `rdns=True`. Каждый аккаунт жёстко привязан к своему /128. Мониторинг раз в час, ротация только при блокировках.
MTU 1400 на всех интерфейсах. DNS только через прокси. TLS-отпечаток — как у реального браузера (используйте `curl_cffi` или `httpx` с кастомным SSLContext). Таймауты 15-30 секунд, retry с экспоненциальной задержкой.
Такая схема не панацея. Twitter продолжает развивать детекцию, и через полгода что-то придётся менять. Но на текущий момент она даёт стабильную работу сотен аккаунтов с минимальным процентом блокировок — в пределах 5-10% в месяц против 40-60% на датацентровых IPv4.