IPv6-прокси и WebRTC: почему браузер сливает ваш реальный IP даже при работающем прокси
Содержание
- IPv6-прокси и WebRTC: почему браузер сливает ваш реальный IP даже при работающем прокси
- Как работает утечка
- Пример утечки
- Как проверить утечку
- Почему прокси не спасает
- Настройка Firefox для блокировки утечки
- Как блокировать утечку на уровне сети
- Использование TURN-сервера
- Расширения для блокировки WebRTC
- Настройка прокси для WebRTC
- Проверка после настройки
- IPv6 и WebRTC
- Итоги
IPv6-прокси и WebRTC: почему браузер сливает ваш реальный IP даже при работающем прокси
WebRTC — это зоопарк. Браузер, который должен слушаться системных настроек прокси, в случае с WebRTC плюёт на них и лезет в сеть напрямую. Механизм простой: WebRTC использует ICE (Interactive Connectivity Establishment), который собирает все доступные кандидаты — локальные адреса, адреса после NAT, адреса, полученные через STUN. И вот тут начинается веселье.
STUN-серверы видят ваш реальный IP до того, как трафик дойдёт до прокси. Браузер отправляет STUN-запросы напрямую, игнорируя настройки прокси в системе. Результат — ваш публичный IPv4 или IPv6 адрес утекает на сервер, с которым вы общаетесь через WebRTC. Даже если весь остальной трафик идёт через lexic.ml, WebRTC-соединение сливает реальные адреса.
Как работает утечка
Когда вы открываете сайт с WebRTC, браузер создаёт RTCPeerConnection. Этот объект запускает ICE-процесс: собирает кандидатов, отправляет запросы на STUN-серверы, указанные в конфигурации. Каждый кандидат — это пара IP:порт, через которую можно достучаться до вашего устройства.
Проблема в том, что ICE-кандидаты включают:
- host-кандидаты — реальные IP-адреса ваших сетевых интерфейсов
- srflx-кандидаты — адреса, полученные от STUN-сервера
- relay-кандидаты — адреса TURN-серверов
Даже если вы настроили прокси на уровне системы, WebRTC-код в браузере не использует системные настройки для ICE. Он работает напрямую с сокетами. Поэтому host-кандидаты с вашим реальным IPv6 адресом уходят на сервер.
Пример утечки
Вот типичный сценарий. У вас есть IPv6-адрес 2001:db8::1234 на интерфейсе eth0. Браузер Firefox 115, системный прокси настроен на lexic.ml. Вы заходите на сайт с WebRTC-приложением. Смотрим сетевой трафик:
```
\$ tcpdump -i eth0 -n udp port 3478
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:23:45.123456 IP6 2001:db8::1234.54321 > 203.0.113.5.3478: UDP, length 88
14:23:45.123789 IP6 2001:db8::1234.54321 > 203.0.113.5.3478: UDP, length 88
```
Видите? Пакеты уходят с вашего реального IPv6 адреса, минуя прокси. STUN-запросы идут напрямую к серверу. Если этот сервер — STUN-сервер, контролируемый сайтом, он узнает ваш реальный IP.
Как проверить утечку
Проверка простая. Открываем консоль браузера и выполняем:
```javascript
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
pc.createDataChannel('test');
pc.onicecandidate = e => {
if (e.candidate) {
console.log(e.candidate.candidate);
}
};
pc.createOffer().then(o => pc.setLocalDescription(o));
```
В консоли появятся ICE-кандидаты. Если среди них есть адреса, не совпадающие с IP вашего прокси — утечка. Например, если вы используете прокси с IP 198.51.100.10, а в кандидатах видите 2001:db8::1234 — ваш реальный адрес ушёл.
Почему прокси не спасает
Прокси работает на уровне TCP. WebRTC использует UDP для медиатрафикака. HTTP-прокси и SOCKS5-прокси обрабатывают TCP-соединения, но UDP-трафик WebRTC идёт в обход.
SOCKS5 поддерживает UDP-ассоциации, но браузеры не используют их для WebRTC. Chrome, Firefox, Safari — все они игнорируют прокси при установке ICE-соединений. Это поведение зашито в код.
Есть нюанс: Firefox имеет настройку `media.peerconnection.ice.proxy_only`. Если её включить, Firefox будет использовать прокси для WebRTC. Но эта настройка работает только с SOCKS5-прокси и ломает многие функции WebRTC.
Настройка Firefox для блокировки утечки
В Firefox можно включить прокси для WebRTC:
```
about:config
media.peerconnection.ice.proxy_only = true
```
Но это работает только если у вас SOCKS5-прокси. HTTP-прокси не подойдёт. И даже с SOCKS5, некоторые функции WebRTC могут работать некорректно — например, screen sharing или передача файлов.
В Chrome такой настройки нет. Единственный способ — блокировать WebRTC на уровне расширений или использовать флаги запуска:
```
chrome --webrtc-ip-handling-policy=disable_non_proxied_udp
```
Этот флаг заставляет Chrome использовать только relay-кандидаты. Но он отключает прямое P2P-соединение, что увеличивает задержку.
Как блокировать утечку на уровне сети
Самый надёжный способ — блокировать UDP-трафик, идущий не через прокси. На Linux это делается через iptables:
```bash
iptables -A OUTPUT -p udp --dport 3478 -j DROP
iptables -A OUTPUT -p udp --dport 5349 -j DROP
```
Но это блокирует только стандартные порты STUN. WebRTC может использовать любые порты. Лучше блокировать весь исходящий UDP, кроме разрешённых:
```bash
iptables -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp -j DROP
```
Это жёстко, но эффективно. DNS через UDP останется, весь остальной UDP-трафик — заблокирован. WebRTC без UDP работать не сможет, поэтому соединение просто не установится.
Использование TURN-сервера
TURN-сервер — единственный способ заставить WebRTC работать через прокси. TURN работает как relay: весь медиатрафик идёт через него. Но TURN-сервер видит ваш реальный IP, потому что вы подключаетесь к нему напрямую.
Если TURN-сервер находится за прокси, то трафик до TURN идёт через прокси. Но браузер всё равно не использует прокси для WebRTC. Поэтому нужно настраивать TURN-сервер так, чтобы он принимал соединения через прокси.
Это сложная схема. На практике проще использовать расширения для браузера, которые блокируют WebRTC.
Расширения для блокировки WebRTC
WebRTC Control для Chrome и Firefox — популярное расширение. Оно перехватывает вызовы RTCPeerConnection и подменяет ICE-кандидаты. Но у него есть недостаток — оно ломает легитимные WebRTC-приложения.
uBlock Origin тоже умеет блокировать WebRTC. В настройках есть опция "Prevent WebRTC from leaking local IP addresses". Она работает надёжно, но также ломает WebRTC-функциональность.
Настройка прокси для WebRTC
Если вам нужно работать с WebRTC через прокси, используйте связку TURN + прокси. Настройте TURN-сервер на вашем прокси-сервере:
```
turnserver -a -u user:password -r realm -p 3478
```
Затем в WebRTC-приложении укажите:
```javascript
const pc = new RTCPeerConnection({
iceServers: [
{ urls: 'turn:your-proxy-server:3478', username: 'user', credential: 'password' }
]
});
```
Но помните: браузер всё равно будет отправлять STUN-запросы напрямую, если в iceServers указаны STUN-серверы. Убирайте STUN из конфигурации:
```javascript
const pc = new RTCPeerConnection({
iceServers: [
{ urls: 'turn:your-proxy-server:3478', username: 'user', credential: 'password' }
]
});
```
Тогда браузер будет использовать только relay-кандидаты. Ваш реальный IP не утечёт. Но задержка увеличится — весь трафик пойдёт через TURN-сервер.
Проверка после настройки
После настройки проверьте утечку снова:
```javascript
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'turn:your-proxy-server:3478', username: 'user', credential: 'password' }]
});
pc.createDataChannel('test');
pc.onicecandidate = e => {
if (e.candidate) {
console.log(e.candidate.candidate);
}
};
pc.createOffer().then(o => pc.setLocalDescription(o));
```
В консоли должны быть только relay-кандидаты. Если видите host-кандидаты с реальными IP — настройка не сработала.
IPv6 и WebRTC
IPv6 усугубляет проблему. Если у вас есть IPv6-адрес, браузер будет использовать его для WebRTC, даже если вы настроили прокси для IPv4. IPv6-адреса часто не проходят через NAT, поэтому они напрямую видны в интернете.
Проверьте, какие IPv6-адреса есть на вашей машине:
```bash
ip -6 addr show
```
Если там есть глобальные адреса (не link-local и не ULA), они будут использоваться WebRTC. Отключите IPv6 на интерфейсе, если он не нужен:
```bash
sysctl -w net.ipv6.conf.all.disable_ipv6=1
```
Или удалите глобальные адреса:
```bash
ip -6 addr del 2001:db8::1234/64 dev eth0
```
Итоги
WebRTC — это дыра в любой прокси-схеме. Браузеры не используют прокси для ICE-соединений. Единственный способ защититься — блокировать WebRTC на уровне браузера или сети.
Для большинства задач достаточно расширения uBlock Origin с включённой блокировкой WebRTC. Для более продвинутых сценариев — TURN-сервер с relay-кандидатами. Но помните: TURN увеличивает задержку и требует ресурсов.
Если вам нужен прокси для IPv6-трафика, и вы используете WebRTC — комбинируйте прокси с блокировкой WebRTC. Иначе ваш реальный IP утечёт при первом же звонке через браузер.