Главное
- Страница может открыть попытку WebRTC-соединения, даже не запрашивая доступ к камере или микрофону, а список кандидатов, который она соберёт, может содержать реальный публичный IP даже за прокси.
- Agilelogin предоставляет одну настройку на Profile,
webrtc.mode. Редактор предлагает три режима:privacy,replaceиdisable. Ядро сохраняет два устаревших значения,forward_stunиallow, для существующих Profile и отладки; новый Profile не может их выбрать. privacyостаётся значением по умолчанию с 2026-07-27: ни host-, ни server-reflexive-кандидаты не утекают, что соответствует тому, что корпоративная политика самого Chrome называетdisable_non_proxied_udp.- Редактор отклоняет
replaceна ротируемом прокси, а устаревшийforward_stunнедоступен на Profile с прокси, потому что оба варианта выдали бы список кандидатов, который не подтверждается фактическим сетевым назначением. - Режим считывается один раз при запуске и сохраняется на всю сессию; он не охватывает каждый путь WebRTC, доступный странице, и ни один режим не скрывает реальный адрес от сайта, который держит собственный STUN-сервер.
Что сайт узнаёт ещё до того, как вы дали разрешение
WebRTC изначально создавался, чтобы два браузера могли напрямую обмениваться аудио, видео или данными, не пропуская каждый пакет через сервер. Чтобы это прямое соединение стало возможным, каждая сторона должна сообщить другой, как до неё добраться, и это согласование — Interactive Connectivity Establishment, или ICE — запускается в тот момент, когда страница открывает RTCPeerConnection, ещё до появления любого запроса на доступ к камере или микрофону. Для запуска достаточно RTCPeerConnection с одним data-каналом, и сайту не нужно, чтобы пользователь что-либо подтверждал.
ICE собирает то, что называется кандидатами, а страница, слушающая события icecandidate, может собрать их все. Host-кандидат описывает адрес на собственном сетевом интерфейсе машины; современный Chromium скрывает настоящий за случайно сгенерированным mDNS-именем .local вместо прямого раскрытия локального IP. Server-reflexive (srflx) кандидат — это то, каким STUN-сервер сообщает браузеру его адрес снаружи — обычно реальный публичный IP, обнаруживаемый независимо от того, проксируется ли остальной трафик, потому что STUN-трафик не обязан идти через HTTP-прокси так же, как обычные запросы страницы. Relay-кандидат, когда задействован TURN, — это адрес на ретрансляционном сервере, через который трафик реально проходит. Всё вместе это и есть известный путь «утечки WebRTC»: браузер может проксировать свой HTTP-трафик, а его ICE-кандидаты всё равно отдают сайту реальный публичный IP, лежащий в основе.
Три режима и два устаревших значения бок о бок
Agilelogin предоставляет ровно одну настройку, управляющую всем этим, webrtc.mode, на уровне Profile. Редактор предлагает три её значения: Privacy (privacy), Replace IP (replace) и Block connections (disable). Два других, allow и forward_stun, — устаревшие значения, которые ядро сохраняет для существующих Profile и отладки. Редактор показывает такое значение только на Profile, где оно уже выбрано, поэтому новый Profile не может выбрать ни одно из них. В таблице перечислены все пять значений ядра:
| Режим | Host / mDNS | Server-reflexive | Relay (TURN) | Что видит сайт |
|---|---|---|---|---|
privacy (по умолчанию) | нет | нет | возможен, только если сайт предлагает TCP/TLS TURN | IP выхода прокси или ничего |
replace | — | переписан на IP выхода прокси | — | IP выхода прокси |
disable | нет | нет | нет, TURN-соединения вообще не устанавливаются | никаких кандидатов — сам API при этом остаётся |
allow (устаревшее) | mDNS-кандидат | реальный публичный IP, если STUN-сервер сайта доступен | — | реальный IP через srflx |
forward_stun (устаревшее) | — | реальный публичный IP | — | реальный IP, принудительно |
allow — это неизменённое поведение Chromium: ничего в сборе кандидатов не тронуто. disable идёт дальше всех в обратную сторону — до страницы не доходит ни один кандидат любого типа, и ни одно TURN-соединение никогда не открывается, хотя сам объект RTCPeerConnection по-прежнему существует и скрипт может его создать; страница не может по способу вызова понять, что этот API намеренно придерживается. forward_stun и replace оба нацелены именно на srflx-кандидат: первый пропускает реальный адрес, второй переписывает его на IP выхода прокси данного Profile ещё до того, как страница его увидит.
Почему privacy — режим по умолчанию
privacy не случайно находится между двумя крайностями — он явно прописан в каждом шаблоне Profile с 2026-07-27. Он полностью подавляет и host-, и server-reflexive-кандидаты — ни mDNS-имени, ни реального IP через STUN, — при этом по-прежнему допуская появление relay-кандидата, если TURN-сервер сайта работает поверх TCP или TLS; в этом случае адрес, который видит страница, — это IP выхода прокси, а не адрес машины. Это не придуманное поведение: оно даёт тот же эффект, что и корпоративная политика Chrome WebRTCIPHandlingPolicy, установленная в disable_non_proxied_udp, — значение по умолчанию у Agilelogin соответствует режиму, который сам Chrome уже предоставляет для управляемых развёртываний, только применённому на уровне Profile, а не машины.
Логика, стоящая за выбором его значением по умолчанию, — это согласованность, а не сокрытие. Profile, для которого уже настроен прокси для HTTP-трафика и отпечатка браузера, должен показывать сайту одну и ту же сетевую идентичность везде, где эта идентичность проверяется, включая WebRTC — оператор, работающий одновременно с несколькими Profile, хочет, чтобы каждый из них выглядел как единая, самосогласованная среда, а не так, будто адресная строка называет одну страну, а WebRTC-кандидат — другую. Эта согласованность так же важна, когда Profile управляется автоматизированным рабочим процессом, а не человеком, кликающим вручную, поскольку скрипт не способен сам заметить, что один из сигналов тихо расходится с остальными.
Два сочетания, которые отклоняет редактор
У каждого из двух значений, затрагивающих server-reflexive-кандидата, есть своё защитное ограничение. forward_stun намеренно раскрывает реальный публичный IP; новый Profile не может его выбрать, а редактор Profile не допускает его на Profile с назначенным прокси: если каждый другой сигнал исходит от прокси, а через WebRTC при этом принудительно выдаётся реальный IP, это просто воссоздаёт ту самую утечку, ради устранения которой существует вся остальная настройка.
У replace защитное ограничение уже: он отклоняется на Profile, использующем ротируемый прокси. Переписывание srflx-кандидата на «IP выхода прокси» имеет смысл только тогда, когда этот IP выхода — фиксированное, известное значение, на которое можно опереться всю сессию; у ротируемого прокси такого значения нет. И даже на статическом прокси, если ядро ещё не знает IP выхода этого прокси в момент, когда ICE собирает кандидатов, replace откатывается к поведению privacy, а не выдаёт устаревший или неверный адрес — непереписанное предположение хуже, чем полное отсутствие кандидата.
Чего эти режимы не покрывают
webrtc.mode считывается один раз, по приватному stdin-каналу, в момент, когда ядро запускает Profile — его нельзя изменить, пока этот экземпляр браузера продолжает работать, так что Profile, которому нужен другой режим, требует перезапуска, а не переключения на лету. Для replace и forward_stun переписанные или пропущенные значения остаются согласованными везде, где страница могла бы попытаться их проверить — RTCPeerConnection.getConfiguration(), icecandidateerror.url, а также URL кандидатов, раскрываемые в getStats() и событиях iceTransport, — все они совпадают с тем, что реально ушло наружу. Это закрывает очевидную перепроверку, которую иначе могла бы выполнить страница, но у этого есть жёсткий предел: сайт, который сам держит STUN-сервер, видит адрес, с которого на самом деле пришёл каждый запрос, и может сравнить его с кандидатом, переданным странице. replace не может изменить то, что наблюдает этот сервер. Это средство контроля приватности и согласованности для того, что видит страница, — не более того.
Стоит прямо назвать ещё два ограничения, а не обходить их стороной. Поведение IPv6-кандидатов отдельно не проверялось ни для одного значения webrtc.mode, поэтому в этом материале об этом ничего не утверждается ни в одну, ни в другую сторону. И эти режимы не управляют каждым связанным с WebRTC интерфейсом, который раскрывает Chromium — в ядре существует более новый API RtcTransport, полностью находящийся вне зоны действия webrtc.mode, хотя сегодня он не раскрыт в релизных сборках, так что страница пока не может до него добраться. Всё это — задокументированное поведение ядра Polychrome, измеренное на сборке M150; публичной версии десктопного приложения для скачивания пока не существует, так что относитесь к этому материалу как к описанию того, что делает ядро сегодня, а не как к функции, которую можно опробовать в выпущенном релизе.