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

Почему IPv6-прокси «фонит» через WebRTC при использовании в антидетект-браузере и как это закрыть

Антидетект-браузер меняет отпечаток. Подменяет Canvas, WebGL, шрифты, user-agent. Пользователь выставляет прокси, заходит на сайт проверки — и видит свой реальный домашний IPv6. Прокси работает, трафик идёт через него, а утечка всё равно есть. Причина — WebRTC. Он живёт своей жизнью и не всегда слушает прокси-настройки.

Разберём, откуда берётся утечка именно по IPv6, почему антидетект-браузеры её не всегда закрывают, и что делать руками.

Что такое WebRTC и почему он обходит прокси

WebRTC — набор протоколов для передачи медиа в реальном времени. Браузер использует его для видеозвонков, голосовых чатов, P2P-соединений. Ключевая деталь: чтобы установить соединение, браузер собирает ICE-кандидатов — набор IP-адресов и портов, по которым его можно достать.

Кандидаты бывают трёх типов: host (локальный интерфейс), srflx (публичный адрес через STUN), relay (адрес TURN-сервера). Проблема в том, что сбор host- и srflx-кандидатов идёт в обход прокси. Браузер перечисляет все сетевые интерфейсы машины, включая IPv6, и отправляет их на STUN-сервер. STUN возвращает публичный адрес — тот, который видит внешний мир.

Если у вас dual-stack подключение (а в 2024-м это норма), браузер соберёт и IPv4, и IPv6 кандидатов. SOCKS5-прокси в антидетект-браузере обычно настроен на IPv4-выход. IPv6-трафик WebRTC при этом уходит напрямую через провайдера. Вот и утечка.

Почему IPv6 фонит сильнее IPv4

С IPv4 проще: большинство антидетект-браузеров и расширений умеют отключать WebRTC или принудительно гнать его через прокси. С IPv6 — зоопарк.

Причина в том, как устроен двойной стек. Когда приложение открывает сокет, оно указывает семейство адресов: AF_INET для IPv4, AF_INET6 для IPv6. SOCKS5-прокси с поддержкой IPv6 должен обработать оба. Большинство дешёвых прокси-серверов настроены только на IPv4. Браузер пытается отправить IPv6-кандидата через прокси, получает отказ, и... идёт напрямую. Или не идёт, но локальный IPv6-адрес всё равно попадает в SDP.

Второй момент — приватные IPv6-адреса. В IPv4 у нас 192.168.x.x, в IPv6 — fc00::/7 (ULA). Эти адреса тоже собираются как host-кандидаты. Они не маршрутизируются в интернете, но выдают структуру вашей локальной сети. По префиксу можно сопоставить пользователя между сессиями.

Третий момент — privacy extensions (RFC 4941). Современные ОС генерируют временные IPv6-адреса, которые меняются. Но WebRTC собирает их все, включая стабильный адрес интерфейса. Утечка получается богаче, чем при IPv4.

Как выглядит утечка на практике

Открываете антидетект-браузер, ставите SOCKS5-прокси на IPv4, заходите на `browserleaks.com/webrtc`. Видите таблицу: публичный IPv4 — адрес прокси, публичный IPv6 — ваш домашний. Локальный IPv6 — префикс вашей сети.

Вот как это проверить через curl, если у вас есть STUN-сервер под рукой:

```bash

curl -6 -s https://ifconfig.co/json

```

Если команда возвращает ваш реальный IPv6 при активном прокси — WebRTC или системный стек его не слушают. Проверять надо именно с флагом `-6`, иначе curl пойдёт по IPv4 и покажет прокси.

Более точная проверка — через Python с библиотекой `aiortc`, которая эмулирует сбор ICE-кандидатов:

```python

import asyncio

from aiortc import RTCPeerConnection, RTCSessionDescription

async def collect_candidates():

pc = RTCPeerConnection()

pc.addTransceiver("audio")

offer = await pc.createOffer()

await pc.setLocalDescription(offer)

candidates = []

while True:

try:

candidate = await asyncio.wait_for(pc.iceGatheringState, timeout=3)

except asyncio.TimeoutError:

break

for c in pc.getTransceivers()[0].receiver.transport.iceTransport.getLocalCandidates():

candidates.append(c)

await pc.close()

return candidates

cands = asyncio.run(collect_candidates())

for c in cands:

print(f"{c.type}: {c.ip}:{c.port} ({c.protocol})")

```

Скрипт покажет, какие адреса реально собираются. Если в выводе есть `srflx` с IPv6, которого нет в вашем прокси — утечка подтверждена.

Что делает антидетект-браузер и где он не справляется

Хорошие антидетект-браузеры (Dolphin Anty, AdsPower, GoLogin) умеют подменять WebRTC-отпечаток. Они перехватывают вызовы `RTCPeerConnection` и подменяют возвращаемые кандидаты. Но реализация отличается.

Часть браузеров просто отключает WebRTC через флаг `--disable-webrtc`. Это ломает видеозвонки и иногда палится — сайт видит, что WebRTC недоступен, и помечает профиль как подозрительный. Другие подменяют кандидатов на заглушки, но забывают про IPv6-семейство.

Третьи пытаются проксировать WebRTC через тот же SOCKS5, что и остальной трафик. Тут начинаются грабли: SOCKS5 не поддерживает UDP по умолчанию (только через расширение UDP ASSOCIATE, RFC 1928). WebRTC любит UDP. Прокси без UDP-релея просто дропает пакеты, и браузер откатывается на TCP-кандидатов или на прямой путь.

Проверить, что реально делает ваш антидетект, можно через `chrome://webrtc-internals`. Откройте страницу, запустите тест на browserleaks и посмотрите в лог: какие кандидаты собраны, какие отправлены, какие выбраны.

Настройка прокси, который не течёт

Первый шаг — прокси должен поддерживать IPv6 на входе и выходе. Если SOCKS5-сервер слушает только IPv4, IPv6-трафик браузера либо дропнется, либо пойдёт напрямую. Проверьте конфиг:

```bash

ss -tlnp | grep -E '1080|socks'

```

Если видите `0.0.0.0:1080` без `[::]:1080` — IPv6 не слушается. В `danted` (Dante SOCKS-сервер) это правится строкой в `/etc/danted.conf`:

```

internal: :: port = 1080

external: ::

```

Для 3proxy в `3proxy.cfg`:

```

nserver 2001:4860:4860::8888

nscache 65536

auth none

allow *

socks -6 -p1080 -i0.0.0.0 -e0.0.0.0

```

Флаг `-6` включает IPv6-режим. Без него 3proxy будет работать только с IPv4.

Теперь про UDP. WebRTC хочет UDP. SOCKS5 умеет UDP через UDP ASSOCIATE, но не все серверы это поддерживают. Если ваш прокси UDP не умеет, WebRTC пойдёт по TCP-кандидатам — медленнее, но без утечки. Если умеет — трафик пойдёт через прокси, и это лучше.

Проверить поддержку UDP ASSOCIATE можно через `socat`:

```bash

socat - SOCKS5:proxy.example.com:1080,socksuser=user,socksport=1080

```

В интерактивном режиме попробуйте установить UDP-ассоциацию. Если сервер отвечает ошибкой — UDP не поддерживается.

Вот тут в игру вступает IPv6-прокси с полноценным двойным стеком. Сервисы вроде lexic.ml держат IPv6 на всех уровнях — от слушающего сокета до исходящих соединений. Это не гарантирует, что антидетект-браузер не сольёт адрес, но убирает один из слоёв проблемы: прокси-сервер готов принять и обработать IPv6-трафик, вместо того чтобы молча дропнуть его и отправить браузер в обход.

Закрываем утечку на уровне браузера

Самый надёжный способ — заставить браузер не собирать лишних кандидатов. В Chromium есть флаг `--force-webrtc-ip-handling-policy`, который принимает значения `default`, `default_public_and_private_interfaces`, `default_public_interface_only`, `disable_non_proxied_udp`.

Последнее значение — то, что нужно. Оно запрещает WebRTC использовать UDP, если он не идёт через прокси. Флаг ставится в аргументы запуска браузера:

```bash

google-chrome \

--force-webrtc-ip-handling-policy=disable_non_proxied_udp \

--proxy-server="socks5://user:pass@proxy.example.com:1080"

```

В антидетект-браузерах это обычно настраивается в профиле. Ищите опцию «WebRTC mode» или «WebRTC policy». Выбирайте «disable non-proxied UDP» или «proxy only».

Второй флаг — `--disable-features=WebRtcHideLocalIpsWithMdns`. Он отключает mDNS-обфускацию локальных адресов. По умолчанию Chromium прячет локальные IP за mDNS-именами (`.local`), но не все сайты это уважают, и не все антидетекты это правильно эмулируют. Если хотите полный контроль — отключайте.

Третий уровень — политика на уровне ОС. Если машина не должна светить IPv6 вообще, отключите его в сетевом интерфейсе:

```bash

sysctl -w net.ipv6.conf.all.disable_ipv6=1

sysctl -w net.ipv6.conf.default.disable_ipv6=1

```

Но это крайняя мера. Если сайт требует IPv6 (а таких всё больше), вы просто не зайдёте. Лучше оставить IPv6, но гнать его через прокси.

Проверка после настройки

После всех правок нужно убедиться, что утечки нет. Открывайте `browserleaks.com/webrtc` и `ipleak.net` в антидетект-профиле. Смотрите на три вещи: публичный IPv4, публичный IPv6, локальные адреса.

Все три должны указывать на прокси или быть пустыми. Если публичный IPv6 показывает ваш провайдерский префикс — настройка не сработала. Если локальные адреса видны — mDNS-обфускация отключена или не работает.

Автоматизировать проверку можно через Puppeteer. Запускаете браузер с нужными флагами, открываете тестовую страницу, собираете результат:

```javascript

const puppeteer = require('puppeteer');

(async () => {

const browser = await puppeteer.launch({

args: [

'--force-webrtc-ip-handling-policy=disable_non_proxied_udp',

'--proxy-server=socks5://proxy.example.com:1080'

]

});

const page = await browser.newPage();

await page.goto('https://browserleaks.com/webrtc', { waitUntil: 'networkidle0' });

await page.waitForTimeout(5000);

const result = await page.evaluate(() => {

const cells = document.querySelectorAll('table td');

return Array.from(cells).map(c => c.textContent.trim()).filter(Boolean);

});

console.log(result.join('\n'));

await browser.close();

})();

```

Скрипт выведет содержимое таблицы. Если там есть IPv6, не совпадающий с прокси — утечка.

Кейс: SOCKS5 без IPv6 на входе

Пример: сервер на Ubuntu 22.04, Dante 1.4.2, конфиг по умолчанию. Антидетект-браузер настроен на SOCKS5 `proxy.example.com:1080`. Пользователь заходит на ipleak.net — видит IPv4 прокси и IPv6 провайдера.

Причина: в `/etc/danted.conf` строка `internal: 0.0.0.0 port = 1080`. Dante слушает только IPv4. Браузер пытается отправить IPv6-кандидата, получает `connection refused` от локального сокета, и WebRTC откатывается на прямой путь. Плюс `external: eth0` без указания семейства — Dante не знает, какой адрес использовать для IPv6-исходящих.

Решение: поменять на `internal: :: port = 1080` и добавить `external: ::`. Перезапустить `systemctl restart danted`. Проверить через `ss -tlnp | grep 1080` — должен появиться `[::]:1080`. После этого IPv6-трафик идёт через прокси, утечка закрыта.

Кейс: UDP ASSOCIATE не поддерживается

Пример: 3proxy 0.9.4, настроен SOCKS5 на IPv4, UDP-релей не включён. WebRTC собирает srflx-кандидата через STUN, но UDP-пакет не проходит через прокси. Браузер ждёт ответа 5 секунд (таймаут ICE), не получает, и переключается на TCP-кандидатов. В логе `chrome://webrtc-internals` видно `STUN binding request timed out`.

Проблема в том, что при таймауте Chromium иногда пытается отправить тот же пакет напрямую — в обход прокси. Это поведение зависит от версии и флагов. На Chromium 120+ при `disable_non_proxied_udp` прямой отправки нет, но на старых версиях бывает.

Решение: включить UDP-релей в 3proxy. В конфиг добавить `socks -p1080 -i0.0.0.0 -e0.0.0.0 -u` (флаг `-u` включает UDP). Проверить, что провайдер не блокирует UDP на порту 1080. Если блокирует — использовать TCP-режим WebRTC через флаг `--force-webrtc-ip-handling-policy=disable_non_proxied_udp` и смириться с отсутствием видеозвонков.

Кейс: mDNS не скрывает IPv6

Пример: антидетект-браузер на базе Chromium 118, профиль с прокси, mDNS включён. На `browserleaks.com/webrtc` локальные IPv4 скрыты за `.local`, а локальный IPv6 виден открытым текстом — `fd12:3456:789a::1`.

Причина: mDNS-обфускация в Chromium работает только для IPv4. IPv6-адреса в некоторых версиях не маскируются, особенно ULA-префиксы (fc00::/7). Баг известен с 2021 года, закрыт частично. В Chromium 118 IPv6-адреса всё ещё утекают при определённых конфигурациях.

Решение: обновить браузер до 124+, где mDNS покрывает оба семейства. Если обновление невозможно — отключить IPv6 на интерфейсе или использовать флаг `--disable-features=WebRtcHideLocalIpsWithMdns` вместе с политикой `disable_non_proxied_udp`. Второй вариант надёжнее: без mDNS и без прямого UDP локальные адреса не собираются вообще.

Итог

WebRTC-утечка по IPv6 — не баг антидетект-браузера, а следствие того, как устроен двойной стек и ICE. Браузер собирает кандидатов со всех интерфейсов, прокси не всегда готов принять IPv6, а UDP-релей есть не везде.

Закрывается в три слоя: прокси с полноценным IPv6 и UDP ASSOCIATE, флаг `disable_non_proxied_udp` в браузере, проверка через browserleaks и `chrome://webrtc-internals`. Пропустите любой слой — получите утечку. Проверяйте после каждой смены конфига, не на глаз, а скриптом.

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