Volver al Centro de conocimiento
Red

¿Qué es una fuga de IP por WebRTC? Protección y privacidad

¿Qué es una fuga de IP por WebRTC? Descubra cómo los candidatos ICE exponen la identidad de red y cómo verificar la coherencia del proxy.

BotBrowser Team

Documentación

Prefieres la documentación del producto mantenida?

Este artículo tiene una página equivalente en el centro de documentación. Usa los docs para el flujo canónico, las flags actuales y la referencia duradera.

WebRTC le da a la página una segunda vista de la red. Antes de que se conecte cualquier llamada, el navegador puede informar qué interfaces locales existen, qué dirección pública observó un servidor STUN y qué relé respondió. BotBrowser configura la lista de servidores ICE y los candidatos que la página recibe, y alinea esas observaciones con un perfil y una ruta aprobada para los caminos que el navegador envía por esa ruta, pero no puede garantizar que el relé, el par o la red de origen no revelen una dirección por otra vía.

TL;DR

  • El proxy reescribe las solicitudes HTTP, y la recopilación puede seguir otro camino, así que una carga de página correcta no dice nada sobre WebRTC.
  • Cada tipo declara un dato distinto: host una interfaz local, srflx la dirección que vio un servidor STUN, relay un extremo TURN y prflx una asignación descubierta por el par.
  • BotBrowser elige la lista de servidores ICE y la información expuesta mediante --bot-webrtc-ice, mientras que --bot-webrtc=profile y --bot-webrtc=disabled deciden si WebRTC sigue al perfil o desaparece.
  • La evidencia de versión es iceGatheringState en complete, una rejilla en chrome://webrtc-internals que coincide con la ruta aprobada y getStats() informando el mismo candidato local.

Contenido

Ver el vídeo

Este vídeo en inglés muestra lo que una página aprende de la recopilación de RTCPeerConnection antes de que empiece cualquier llamada. Una página de laboratorio local declara tres conjuntos de candidatos y un script lee cada uno con la devolución de llamada habitual; después compara cada dirección server-reflexive declarada con la dirección declarada que ve HTTP. Luego se ejecutó la misma llamada en Google Chrome oficial con una lista de servidores ICE vacía: dos líneas de candidato host en una máquina con Windows y una en una máquina con Ubuntu, cada una con un nombre mDNS. Muestra lo que devolvieron esas dos máquinas, y una lista coincidente significa coherencia, no anonimato. No interviene ningún perfil de BotBrowser. El audio es en inglés.

Qué expone un candidato recopilado

Un candidato es un camino posible para los medios, y su campo type registra cómo conoció el navegador ese camino: host, srflx, prflx o relay. Chrome suele producir los cuatro mientras se prepara una llamada, y cada uno responde a una pregunta distinta sobre la red que hay detrás de la sesión. La pregunta útil no es si existe un candidato, sino qué permite concluir ese candidato sobre la máquina, la ruta y el relé que respondió.

TipoQué aprende la páginaCampo en chrome://webrtc-internalsEsperado en un contexto controlado
hostUn valor de interfaz local, o un nombre mDNS que lo ocultaLínea candidate de la descripción localUn nombre mDNS o un valor que defina el perfil
srflxLa dirección pública que vio un servidor STUNLínea candidate más relatedAddressLa salida aprobada, no el enlace del host
relayEl extremo TURN que transportará los mediosLínea candidate con typ relayPresente cuando TURN está configurado y accesible
prflxUna asignación descubierta por el par en las comprobacionesFila candidate-pair de la vista de estadísticasAusente, o coherente con la ruta aprobada

La tabla importa porque un despliegue puede superar una fila y fallar en otra. Un perfil que oculta los valores de las interfaces privadas sigue dejando filas srflx que describen la salida real de la solicitud STUN, y un relé TURN añade un segundo valor público que el par verá durante los medios. Revisar los cuatro tipos por separado también hace que un informe de fallo sea concreto: una fila relay ausente apunta a la entrada TURN o al camino UDP, mientras que una fila prflx inesperada apunta al lado del par en la conexión.

Candidatos host y el nombre mDNS

Los candidatos host describen una interfaz de red de la máquina que ejecuta el navegador. Chrome moderno oculta los valores IPv4 e IPv6 privados detrás de un nombre mDNS como 4f2a9c1e-7b3d-4a52-9e88-1c6d0b8f2e11.local, así que la página sabe que existe una interfaz sin conocer el valor que hay detrás. Es un límite real y también es incompleto: el nombre mDNS es estable durante la vida del perfil, aparece en la descripción local y vuelve a aparecer en la vista de estadísticas dentro de local-candidate. Una página puede comparar dos visitas y saber si ambas usaron la misma interfaz, por eso Candidatos mDNS de WebRTC y privacidad de la red local trata el nombre como un punto a revisar y no como un caso resuelto.

La recopilación de host sigue ocurriendo cuando la máquina está detrás de un proxy. El proxy cambia la salida de las solicitudes de página; no elimina las interfaces locales, así que el navegador continúa enumerándolas salvo que la política del perfil indique otra cosa. Un contexto controlado debería mostrar un nombre mDNS o un valor definido por el perfil, y el registro del despliegue debe indicar cuál de los dos produce el perfil.

Candidatos server-reflexive y el valor observado

Los candidatos srflx existen porque el navegador envió una solicitud de enlace STUN a un servidor y la respuesta indicó el origen que ese servidor vio. El camino habitual usa stun:stun.l.google.com:19302 sobre udp:3478. La respuesta lleva el valor público asignado y el campo relatedAddress conserva el valor local que lo produjo, así que una fila puede contener los dos lados de la misma asignación.

La fila srflx es la que más citan los informes de fuga, porque describe algo que el host no eligió. Cuando la solicitud viaja por una ruta aprobada, ese valor es la salida de la ruta. Cuando viaja directamente, el valor es el enlace del host. Ambos resultados se ven igual en la lista, y por eso la revisión tiene que registrar la ruta y no solo el valor, y por eso Coherencia del proxy entre DNS y WebRTC compara la salida HTTP, la respuesta del resolutor y el valor del candidato en una sola pasada.

Candidatos relay y peer-reflexive

Los candidatos relay aparecen cuando hay un servidor TURN configurado y accesible. El navegador asigna un valor en el servidor y los medios fluyen por turn:relay.example.com:3478?transport=udp. La fila nombra el extremo TURN en lugar del host, así que es la fila que muestra que un despliegue tiene un camino de medios que no depende del enlace local.

Los candidatos prflx aparecen cuando una comprobación del par llega al navegador desde un valor que el navegador no había previsto. La fila se crea a partir de esa comprobación y no de la enumeración local, así que registra lo que vio otra parte. Un contexto controlado que muestra una fila prflx tiene evidencia de que algún camino evitó la asignación prevista, y la revisión debería tratarlo como una pregunta sobre el par y el camino, no sobre el perfil.

Cuatro filas comparan los candidatos host, srflx, relay y prflx con los campos que se leen en chrome://webrtc-internals y el valor que debería mostrar un contexto controlado

Dónde termina el control del navegador

Los límites se describen mejor una vez conocidos los cuatro tipos. Cada enfoque siguiente cambia lo que informa la página o la interfaz del navegador, y ninguno cambia lo que observa un par o un servidor TURN cuando los medios ya fluyen.

Ajustes y extensiones

Desactivar WebRTC desde los ajustes del navegador, por ejemplo con media.peerconnection.enabled en Firefox, elimina toda la recopilación. La ausencia es observable: una página puede comprobar si existe RTCPeerConnection y si createOffer() se resuelve, y un navegador sin esa interfaz destaca entre la población que la página espera.

Las extensiones pueden interceptar onicecandidate, reescribir listas de RTCIceServer o sustituir el constructor. Se ejecutan después de que el código nativo de recopilación haya producido sus valores, así que un valor que la página obtiene por la ruta del prototipo puede seguir siendo distinto del que usó la capa de red. Modificar además deja rastros en la forma del objeto: otra cadena de prototipos, un getter que devuelve un valor cambiado o una devolución de llamada que se dispara más tarde de lo que la página espera.

Límites de VPN y de relé

Una VPN traslada todas las conexiones del sistema a un túnel, lo que cambia lo que ve el servidor STUN pero no lo que enumera la máquina. Las filas host siguen describiendo interfaces locales y los medios siguen negociando con el par salvo que se exija un relé TURN. El túnel añade además una segunda salida que el despliegue puede no haber aprobado, y una revisión que solo mira el proxy la pasará por alto.

Los servicios de relé tienen sus propios límites. Un extremo TURN responde con un valor de su propio grupo, normalmente en una región elegida al contratar el servicio, y ese valor diferirá de la salida del proxy. La diferencia es esperable y debe registrarse, porque una revisión que trata cada valor nuevo como una fuga repetirá la misma pregunta sin fin.

Cómo gestiona BotBrowser los servidores ICE y los candidatos

BotBrowser cambia la lista de servidores ICE y la información de candidatos que expone el navegador, usando el perfil cargado junto con las opciones de arranque. Los controles están por debajo de la capa de JavaScript, así que una página que lee pc.localDescription o pc.getStats() recibe los valores que produjeron el perfil y las opciones.

Tres opciones para la configuración ICE

OpciónQué seleccionaQué queda fuera de su alcance
--bot-webrtc-ice="google"Lista de servidores stun:stun.l.google.com:19302Si udp:3478 llega a ese servidor
--bot-webrtc-ice="custom:..."Una lista STUN o TURN concretaLas credenciales de ese relé
--bot-webrtc=profileLos ajustes de WebRTC guardados en el perfilLa ruta del proxy
--bot-webrtc=disabledLa retirada de la capacidad WebRTCNada: la ausencia es visible para la página

Conviene mantener la distinción entre las dos familias. --bot-webrtc-ice elige servidores y --bot-webrtc elige postura. Un arranque que solo fija la postura conserva la lista de servidores del perfil, y un arranque que solo fija la lista conserva la postura ya registrada en el perfil. Leer una de las dos y suponer la otra es cómo un despliegue acaba con un perfil que parece correcto y una sesión que recopila por otra ruta.

Opciones y rutas de proxy

Un arranque habitual combina el preajuste con un proxy y una política DNS local:

chrome --bot-profile="path/to/profile.enc" \
       --proxy-server="socks5://user:[email protected]:1080" \
       --bot-webrtc-ice="google" \
       --bot-local-dns \
       --bot-timezone="America/New_York" \
       --bot-locale="en-US"

Una lista propia nombra directamente los servidores STUN y TURN:

chrome --bot-profile="path/to/profile.enc" \
       --proxy-server="socks5://user:[email protected]:1080" \
       --bot-webrtc-ice="custom:stun:stun.example.com:3478,turn:turn.example.com:3478?transport=udp"

La automatización pasa los mismos valores por los argumentos de arranque:

const { chromium } = require('playwright-core');

(async () => {
  const browser = await chromium.launch({
    executablePath: 'path/to/botbrowser/chrome',
    args: [
      '--bot-profile=path/to/profile.enc',
      '--proxy-server=socks5://user:[email protected]:1080',
      '--bot-webrtc-ice=google',
      '--bot-local-dns',
    ],
    headless: true,
  });

  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto('https://example.com');
  await browser.close();
})();

Caminos a través de un relé

Un camino de medios aprobado tiene que llegar desde el navegador al extremo TURN, y el transporte decide si puede. Cuando el servicio proxy transporta UDP, socks5://user:[email protected]:1080 también transporta el tráfico STUN y TURN, así que las solicitudes de página y los medios comparten una ruta. Cuando solo transporta TCP, turn:turn.example.com:3478?transport=udp no responderá a través de él y un relé ?transport=tcp debe aprobarse como camino separado. UDP sobre SOCKS5: enrutamiento privado de QUIC y WebRTC cubre las decisiones de transporte por contexto y las comprobaciones que las respaldan.

Verificar el conjunto de candidatos antes de la versión

Una pasada de verificación tiene tres partes: el estado de recopilación, la rejilla que enumera todos los candidatos y el registro de estadísticas del par que transportó los medios. Las tres juntas llevan unos minutos y dejan evidencia que una revisión posterior puede comparar con el registro del despliegue.

Leer el estado de recopilación en chrome://webrtc-internals

Abra chrome://webrtc-internals, inicie la página de prueba y observe iceGatheringState. Pasa de new a gathering y termina en complete. La página muestra una rejilla con una fila por candidato, la columna type, la address, el port, el protocol y el valor relatedAddress. Una rejilla que nunca llega a complete significa que la recopilación sigue en curso o se ha detenido. Una rejilla que llega a complete solo con filas host significa que no llegó ninguna respuesta STUN.

Comparar la rejilla con pc.getStats()

pc.getStats() devuelve registros local-candidate con candidateType, address, port, protocol y relatedAddress, además de registros candidate-pair con state, nominated, localCandidateId y remoteCandidateId. El par nominado con state: succeeded es el camino que transportó los medios. Busque su localCandidateId y confirme que la fila local-candidate correspondiente informa el tipo y el valor que mostró la rejilla. Dos vistas que no coinciden, por ejemplo una fila de rejilla con nombre mDNS y una fila de estadísticas con un valor IPv4 privado, significan que la página y los medios usaron interfaces distintas.

Cuando faltan candidatos relay

Un estado complete sin fila relay es el fallo más común, y este orden lo resuelve más rápido:

  1. La lista de servidores no tiene entrada TURN. La rejilla muestra solo filas host y srflx, que es lo que produce por diseño un arranque con --bot-webrtc-ice="google".
  2. La URL TURN no incluye ?transport=udp. Una URL de relé sin parámetro de transporte vuelve a TCP y se queda en silencio en un camino que solo transporta UDP.
  3. udp:3478 está filtrado en la salida. La asignación TURN nunca se completa, no aparece ninguna fila relay y chrome://webrtc-internals muestra el intento terminando sin candidato.
  4. El valor de --bot-webrtc-ice no coincide con el perfil. Una lista propia que nombra un host no permitido por el perfil, o un preajuste sin licencia en el despliegue, deja el arranque con una lista que nadie eligió, y la rejilla muestra exactamente esa lista.

Cada paso es una comprobación única, y la rejilla suele responderla sin leer registros: la fila del extremo TURN existe o no existe.

Guía práctica de decisión

Decida la postura y la lista de servidores juntas y luego verifique el resultado contra la ruta aprobada por el despliegue.

  1. Combine --bot-webrtc-ice con --proxy-server. Sin proxy la salida ya es el enlace del host y la opción solo cambia qué servidor lo informa.
  2. Use el preajuste google salvo que el despliegue nombre su propia infraestructura. stun:stun.l.google.com:19302 es la configuración que usa la mayoría del tráfico, así que una sesión que la omite resulta inusual por otro motivo.
  3. Añada --bot-local-dns. La resolución de nombres y los medios son los dos caminos que más a menudo dejan el proxy sin cubrir, y cerrar ambos acorta la revisión.
  4. Recurra a --bot-webrtc=disabled solo donde la aplicación realmente no tenga funciones de medios. La interfaz ausente es visible y una página puede registrar esa diferencia.
  5. Repita la comprobación en tres partes tras cada cambio de extremo de proxy, proveedor TURN o perfil. La lista de candidatos es producto de esas tres entradas.

¿BotBrowser rompe las llamadas? No, RTCPeerConnection sigue disponible y los medios siguen fluyendo. Las opciones cambian qué servidores recopilan y qué valores recibe la página.

¿Cuál es la diferencia entre las dos opciones? --bot-webrtc-ice elige servidores y --bot-webrtc elige si WebRTC sigue al perfil o se retira.

¿Basta con una VPN? Una VPN cambia la salida de todas las conexiones pero mantiene las filas host y añade una salida que el despliegue puede no haber aprobado.

¿Y IPv6? Se aplican los mismos cuatro tipos, y un valor de perfil que cubre IPv4 sin cubrir IPv6 deja una diferencia visible entre ambas familias.

Conclusión práctica

Una revisión de fugas que solo lee el tráfico de página se pierde el camino que toman los medios. Registre la postura, la lista de servidores y la ruta aprobada; recopile hasta que iceGatheringState informe complete; compare la rejilla con getStats(); y guarde el resultado junto al registro del despliegue. Cuando una sesión posterior muestre otra fila, la comparación nombra el cambio en lugar de dejar que quien revisa lo adivine.

Para los controles de red del entorno, consulte Configuración del proxy, Prevención de fugas DNS y Aislamiento de navegador multicuenta. La página de funciones enumera las capacidades relacionadas y el artículo sobre candidatos mDNS de WebRTC explica qué añade el nombre mDNS a una fila host.

Fuentes públicas

#WebRTC#Ip-Leak#proxy#privacidad#red

Lleva BotBrowser de la investigación a producción

Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.