Утечки WebRTC: когда VPN врет, а браузер говорит правду
Содержание
- Механика утечки
- Почему VPN не спасает
- Тестирование утечек
- Уровни защиты
- Браузерные методы
- Системный уровень
- Настройка VPN
- Продвинутые методы защиты
- Многоуровневая схема
- Настройка прокси для WebRTC
- Запуск браузера в изолированном окружении
- Кейсы из практики
- Кейс: корпоративная сеть
- Кейс: домашний пользователь
- Кейс: разработчик WebRTC-приложения
- Итоги
Механика утечки
WebRTC — это не просто протокол. Это целая экосистема для реального времени. Браузеры используют ICE (Interactive Connectivity Establishment), чтобы найти лучший путь между пирами. И вот тут начинается веселье.
STUN-серверы — это такие "зеркала" в интернете. Браузер спрашивает: "С какого IP меня видят?" И получает ответ. Проблема в том, что браузер отправляет этот запрос напрямую, игнорируя системные настройки прокси. VPN-клиенты часто работают на уровне TUN-интерфейса, но WebRTC может использовать альтернативные маршруты.
Технически это выглядит так: браузер создает сокет, который привязывается к любому доступному интерфейсу. Если ваш VPN создал tun0 с адресом 10.8.0.2, но физический интерфейс eth0 все еще жив и имеет реальный IP — WebRTC может выбрать eth0 для STUN-запроса. Почему? Потому что ICE собирает все кандидаты, включая host-кандидаты с физических интерфейсов.
```javascript
async function checkWebRTCLeak() {
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
pc.createDataChannel('test');
await pc.setLocalDescription(await pc.createOffer());
const candidates = [];
pc.onicecandidate = (e) => {
if (e.candidate) {
candidates.push(e.candidate.candidate);
} else {
console.log('All candidates:', candidates);
}
};
}
```
Почему VPN не спасает
Большинство VPN-клиентов маршрутизируют только IPv4-трафик. IPv6 остается вне туннеля. Если ваш провайдер выдал IPv6-адрес, а VPN не поддерживает IPv6 — браузер отправит STUN-запрос через IPv6, и ваш реальный адрес утечет.
Вторая проблема — split tunneling. Некоторые VPN-клиенты пропускают часть трафика мимо туннеля для экономии带宽. WebRTC-трафик часто попадает в эту категорию, потому что он UDP-based и требует низкой задержки.
Третья причина — DNS. WebRTC может использовать mDNS для скрытия IP, но если mDNS отключен или не поддерживается, браузер использует обычные DNS-запросы. А DNS-сервер вашего провайдера видит все.
Тестирование утечек
Прежде чем защищаться, нужно проверить. Откройте browserleaks.com/webrtc или напишите свой скрипт:
```bash
curl -s https://raw.githubusercontent.com/diafygi/webrtc-ips/master/webrtc-ips.js | node
```
Этот скрипт создает RTCPeerConnection и собирает все кандидаты. Если вы видите IP, который не принадлежит VPN-подсети — утечка есть.
Пример: VPN-клиент WireGuard на Linux. Интерфейс wg0 имеет адрес 10.66.66.2. Но тест показывает 85.23.45.67 — это реальный IP вашего провайдера. Значит, браузер нашел путь через физический интерфейс.
Уровни защиты
Браузерные методы
Firefox — самый простой вариант. Зайдите в about:config и установите `media.peerconnection.enabled` = false. Полностью отключит WebRTC. Но если вам нужен WebRTC для работы, есть другой параметр: `media.peerconnection.ice.default_address_selection` — можно указать конкретный IP.
Chrome хуже. Нет встроенной настройки для отключения WebRTC. Есть флаги, но они не работают с 2021 года. Единственный вариант — расширения. WebRTC Leak Prevent или uBlock Origin с включенной фильтрацией. Расширения работают через `chrome.privacy` API, но это не панацея.
Системный уровень
На Linux можно заблокировать WebRTC на уровне iptables:
```bash
sudo iptables -A OUTPUT -p udp --dport 19302 -j DROP
sudo iptables -A OUTPUT -p udp --dport 3478 -j DROP
```
Но это блокирует только стандартные STUN-порты. Браузер может использовать любой UDP-порт для ICE.
Настройка VPN
Лучший способ — настроить VPN так, чтобы он захватывал весь трафик. Для WireGuard:
```ini
[Interface]
PrivateKey = ...
Address = 10.66.66.2/32
DNS = 1.1.1.1
[Peer]
PublicKey = ...
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = vpn.example.com:51820
```
AllowedIPs = 0.0.0.0/0, ::/0 заставляет маршрутизировать весь трафик через туннель. Но это не решает проблему с IPv6, если ваш VPN-сервер не поддерживает IPv6.
Продвинутые методы защиты
Многоуровневая схема
На lexic.ml используют следующую схему: VPN-туннель + прокси на уровне приложений. VPN-клиент создает туннель, а браузер настраивается на SOCKS5-прокси внутри туннеля. Это гарантирует, что даже если WebRTC обойдет VPN, он упрется в прокси.
Настройка прокси для WebRTC
В Firefox можно указать прокси для WebRTC:
```bash
network.proxy.socks = "127.0.0.1"
network.proxy.socks_port = 1080
network.proxy.socks_remote_dns = true
network.proxy.type = 1
```
Но Chrome игнорирует системные прокси для WebRTC. Нужен прокси на уровне сети.
Запуск браузера в изолированном окружении
Firejail или Bubblewrap могут ограничить сетевой доступ браузера:
```bash
sudo firejail --net=eth0 --ip=192.168.1.100 firefox
```
Но это изолирует браузер от VPN. Лучше использовать сетевой namespace с маршрутизацией через VPN.
Кейсы из практики
Кейс: корпоративная сеть
Компания использует VPN для доступа к внутренним ресурсам. Сотрудник подключается к VPN, открывает веб-конференцию в браузере. Через 10 минут администратор видит в логах firewall реальный IP сотрудника. Проблема — VPN-клиент настроен на split tunneling для экономии трафика. WebRTC-трафик пошел напрямую.
Решение: перенастроить VPN на full tunneling, отключить split tunneling. Заодно включить IPv6 в VPN-туннеле.
Кейс: домашний пользователь
Пользователь купил VPN для обхода блокировок. Проверяет IP на 2ip.ru — все ок. Но при звонке через веб-версию WhatsApp собеседник видит реальный IP. Причина — браузер использует STUN-сервер Google, который не маршрутизируется через VPN.
Решение: включить в браузере `media.peerconnection.ice.proxy_only` в Firefox. Или использовать прокси-расширение.
Кейс: разработчик WebRTC-приложения
Разработчик тестирует WebRTC-приложение с VPN. Приложение показывает неправильные IP-адреса пиров. Оказалось, что ICE собирает кандидаты с физического интерфейса, игнорируя VPN. Это ломает логику приложения.
Решение: использовать `iceTransportPolicy: 'relay'` в конфигурации RTCPeerConnection. Это заставит использовать только TURN-серверы, которые работают через VPN.
```javascript
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'turn:turn.example.com:3478', username: 'user', credential: 'pass' }],
iceTransportPolicy: 'relay'
});
```
Итоги
WebRTC-утечки — это не баг, а архитектурная особенность. Браузеры стремятся найти самый быстрый путь, даже если это нарушает настройки VPN. Полная защита требует комбинации методов: правильная настройка VPN, блокировка на уровне браузера и проксирование.
Помните: если вы работаете с чувствительными данными, WebRTC-утечка может свести на нет все усилия по анонимизации. Проверяйте свои конфигурации регулярно, а не только после сбоев.