- Mullvad tiene varias IP de salida por servidor, pero las asigna de forma determinista según la clave de WireGuard, así que no cambian aleatoriamente en cada conexión
- 3,650 puntos de datos recopilados en 9 servidores, cambiando repetidamente la pubkey, solo fueron asignados a 284 combinaciones de entre 8.2 billones posibles
- Las IP de salida de cada servidor se ubican en una posición percentil similar dentro del pool, y una combinación suele alinearse cerca del percentil 81 en varios servidores
- La causa parece ser una estructura que elige el índice de IP de salida con un RNG basado en seed, usando la pubkey o la dirección del túnel como seed y el tamaño del pool como límite superior
- Si los rangos float de los logs de IP se superponen, es posible correlacionar cuentas incluso usando distintos servidores de Mullvad, lo que aumenta el riesgo para el anonimato
Cómo la IP de salida de Mullvad se convierte en un vector de identificación
- Mullvad ofrece varias IP de salida por servidor, y dos usuarios conectados al mismo servidor normalmente reciben distintas IP públicas
- Tiene 578 servidores, menos que los 20,000 de Proton VPN, por lo que el escalado vertical que evita concentrar usuarios en una sola IP puede ser ventajoso para reducir bloqueos excesivos de IP y limitaciones de velocidad
- Pero la IP de salida no cambia aleatoriamente cada vez que se conecta a un servidor, sino que se elige de forma determinista según la clave de WireGuard
- La clave de WireGuard rota cada 1 a 30 días, pero en clientes de terceros no rota
- Si a cada servidor se le asigna de forma independiente una IP de salida fija, entonces la combinación de IP de unos pocos servidores puede distinguir a un usuario de otros usuarios de Mullvad
Combinaciones de IP de salida observadas en 9 servidores
- Se ejecutó durante toda la noche un script que recopilaba las IP de salida de 9 servidores mientras cambiaba repetidamente la pubkey, obteniendo 3,650 puntos de datos de pubkeys
- El rango de IP de salida observado en cada servidor fue el siguiente
| Hostname | Start IP | End IP | # IPs |
|---|---|---|---|
| au-syd-wg-101 | 103.136.147.5 | 103.136.147.64 | 60 |
| cl-scl-wg-001 | 149.88.104.4 | 149.88.104.14 | 11 |
| de-ber-wg-007 | 193.32.248.245 | 193.32.248.252 | 8 |
| dk-cph-wg-002 | 45.129.56.196 | 45.129.56.226 | 31 |
| fi-hel-wg-201 | 185.65.133.10 | 185.65.133.75 | 66 |
| us-lax-wg-001 | 23.234.72.36 | 23.234.72.126 | 91 |
| us-nyc-wg-602 | 146.70.168.132 | 146.70.168.190 | 59 |
| us-sjc-wg-302 | 142.147.89.212 | 142.147.89.224 | 13 |
| za-jnb-wg-002 | 154.47.30.145 | 154.47.30.155 | 11 |
- Al multiplicar el tamaño de los pools de estos servidores, parecería que hay más de 8.2 billones de combinaciones posibles de IP de salida
- En las pruebas reales, todas las pubkeys evaluadas fueron asignadas solo a una de 284 combinaciones
- La gran diferencia entre la cantidad de combinaciones posibles y las observadas sugiere que la selección de IP en cada servidor no es independiente
El patrón de distintas IP ubicadas en el mismo percentil
- La posición numérica de una IP de salida puede calcularse según qué tan lejos está desde la IP inicial del pool
- Por ejemplo, en
au-syd-wg-101,103.136.147.53, contando desde103.136.147.5, tiene un índice base 1 de 49 - Si se divide la posición de la IP en las combinaciones observadas por el tamaño del pool de cada servidor, aparece casi la misma proporción incluso entre servidores distintos
| Server | IP | Position | Pool size | Ratio |
|---|---|---|---|---|
| au-syd-wg-101 | 103.136.147.53 | 49 | 60 | 0.816 |
| cl-scl-wg-001 | 149.88.104.12 | 9 | 11 | 0.818 |
| de-ber-wg-007 | 193.32.248.251 | 7 | 8 | 0.875 |
| dk-cph-wg-002 | 45.129.56.220 | 25 | 31 | 0.806 |
| fi-hel-wg-201 | 185.65.133.63 | 54 | 66 | 0.818 |
| us-lax-wg-001 | 23.234.72.109 | 74 | 91 | 0.813 |
| us-nyc-wg-602 | 146.70.168.179 | 48 | 59 | 0.813 |
| us-sjc-wg-302 | 142.147.89.222 | 11 | 13 | 0.846 |
| za-jnb-wg-002 | 154.47.30.153 | 9 | 11 | 0.818 |
- Cada IP queda ubicada en un percentil parecido dentro de su pool, y el ejemplo de arriba corresponde en general al percentil 81
- Por este patrón, parece que Mullvad asigna solo IP de salida ubicadas en posiciones vecinas en todos los servidores
La causa parece ser una selección aleatoria basada en seed
cl-scl-wg-001yza-jnb-wg-002siempre comparten el mismo índice de IP en las 284 combinaciones observadas- Lo que tienen en común es un tamaño de pool de 11, lo que encaja con una estructura en la que una llamada aleatoria con la misma seed y los mismos límites devuelve el mismo resultado
- Si un RNG se inicializa con una seed estática y luego se extrae un número aleatorio dentro del mismo rango, el mismo resultado se repite
- Parece que Mullvad elige el índice de IP de salida con un RNG basado en seed, usando la pubkey o la dirección del túnel como seed y el tamaño del pool como valor máximo
- Aunque cambien los límites, el pool de entropía del RNG no se ve afectado, y en Rust esto coincide con un comportamiento donde en la primera llamada se genera el mismo float y luego se multiplica por los límites
- Este comportamiento puede simplificarse como
min + round((max - min) * float), aunque esa puede ser una representación demasiado simplificada - Por esta característica, aunque cambie el tamaño del pool, el float derivado de la misma seed termina mapeándose a puntos de proporción similar en los pools de cada servidor
- Como el cliente de Mullvad está escrito en Rust, es posible que Rust también sea el lenguaje del backend, aunque eso es solo una inferencia basada en la implementación del cliente
- Es difícil predecir con exactitud cómo se comporta
random_rangecuando cambian los límites, y es fácil pensar que al aumentar los límites se mezclaría con la entropía para producir otro número, pero las observaciones muestran lo contrario
Riesgo para el anonimato por correlación de logs de IP
- Se ofrece una herramienta llamada mullvad-seed-estimator para estimar el valor mínimo y máximo posibles del float para una combinación específica de IP
- En la captura, un conjunto específico de IP se interpreta como un valor float entre 0.2909 y 0.2943, con una diferencia de 0.0034
- Eso significa que 0.34% de los usuarios de Mullvad comparten esas IP, lo que en una estimación aproximada de 100,000 usuarios activos equivale a 340 personas
- No es tan único como se pensó al principio, pero una precisión superior al 99% sigue siendo considerable
- Por ejemplo, si un administrador de foro quiere verificar si una cuenta nueva sospechosa es un sockpuppet de un usuario bloqueado el día anterior, incluso si ambas cuentas usan distintos servidores de Mullvad, si los logs de IP muestran rangos float superpuestos como
0.4334 - 0.4428y0.4358 - 0.4423, la probabilidad de que pertenezcan a la misma persona supera el 99% - Si se aplica la misma correlación a logs de IP obtenidos mediante filtraciones de datos o procedimientos legales, el usuario detrás del VPN podría perder el anonimato
Cómo protegerse
- Se recomienda no cambiar de servidor más de una vez por cada pubkey
- En la app de Mullvad se puede cerrar sesión para forzar la rotación de la pubkey
1 comentarios
Comentarios de Hacker News
Soy co-CEO y cofundador, trabajo en Mullvad. Parte del comportamiento descrito en el artículo es intencional y parte no lo es, y la causa no es exactamente la misma que se explica en la publicación del blog
Como mitigación, ya estamos probando en parte de la infraestructura un parche para el comportamiento no intencional, así que si intentan reproducirlo hoy, los resultados podrían ser confusos
También vamos a reevaluar si el comportamiento intencional es aceptable, ya que aquí hay varios factores de privacidad y compensaciones con la experiencia de usuario
Esta es mi evaluación actual, formulada mientras escribo esto tras enterarme hace una hora y discutir de inmediato la respuesta con el equipo de operaciones, así que podría cambiar
A quienes hacen investigación de seguridad: si encuentran problemas de seguridad o privacidad, aunque planeen divulgarlos enseguida, por favor avisen primero a los administradores o al proveedor
Se puede revisar con
mullvad tunnel gety cambiar conmullvad tunnel set rotation-interval, y este también es el método de mitigación que el artículo preferíaEn lo personal, una IP semiestática no me parece un gran problema. El objetivo es impedir la vigilancia a nivel de red por parte de ISP y gobiernos, y algunas empresas incluso venden IPv4 fija como una funcionalidad
En un VPN de privacidad, mientras más pequeño sea el espacio de IP, más usuarios pueden mezclarse detrás de una misma IP visible desde afuera, lo que también tiene ventajas. Combinado con tecnologías como DAITA, que inyectan tráfico señuelo en el túnel, y puntos de entrada multihop, creo que realmente puede dificultarle más las cosas a un vigilante que observa netflow todo el día
El hallazgo principal, la correlación de posición dentro del pool de IP entre servidores, efectivamente parece incluir comportamiento no intencional. Por mi experiencia trabajando con el equipo de Mullvad, creo que lo resolverán pronto
Si quieres “identidades” distintas, debes rotar la clave de WireGuard o usar claves distintas
El artículo decía que “cada vez que te conectas a un servidor, la IP de salida no se elige al azar sino de forma determinista según la clave de WireGuard, y esa clave rota cada 1 a 30 días. Si usas un cliente de terceros, no rota”. Pero WireGuard, por diseñohttps://www.wireguard.com/protocol/, es un protocolo sin conexión, así que no existe el concepto de conexión; solo hay handshakes de rekeying cada 2 o 3 minutos cuando hay tráfico
Si incluso con la misma clave de WireGuard la IP de salida cambiara en cada “conexión”, por ejemplo en cada handshake de rekeying o cada 15 minutos, en la capa de transporte casi todas las conexiones dentro del túnel, excepto QUIC, tendrían que cortarse y restablecerse, y en la capa de aplicación los servicios que sospechan de “la misma cookie, IP nueva” provocarían cierres de sesión, CAPTCHA y puntajes de riesgo
Ambas cosas darían una mala experiencia de usuario y, peor aún, podrían hacer que el usuario quedara más singularmente identificado, como “esta persona sigue reconectándose desde IP distintas, así que es usuaria de Mullvad”
El ejemplo de “un moderador de foro sospechó que era una cuenta secundaria de un usuario bloqueado el día anterior y revisó los logs de IP; aunque usaban distintos servidores de Mullvad, ambas cuentas se mapearon a rangos de punto flotante superpuestos 0.4334~0.4428 y 0.4358~0.4423, así que puede asumirse con más de 99% de probabilidad que es la misma persona” da la impresión de que, si una agencia de inteligencia diseñara un VPN, lo haría así
Además, este método depende de que el usuario elija servidores distintos, así que con más razón no tendría sentido
Para mí sí es un problema grande, porque permite análisis de correlación entre varios nodos de salida de VPN, pero eso es todo
No hace posible identificar usuarios automáticamente
Eso sí, reduce mucho la dificultad de identificarlos, aunque los requisitos siguen siendo altos. Ojalá lo corrijan pronto
No puedo creer que un error del tipo “hagámoslo con un valor sensible como un hash” siga pasando, y encima en Mullvad. Dan ganas de pensar: ¿por qué no simplemente aleatorizarlo?
Claro, hay otras agencias de inteligencia, pero esa sería la más preocupante. Porque podrían operarlo directamente, o conocer esa idea y replicarla, o tener acceso a un servicio operado por una agencia socia. De otro modo, no sería una amenaza para mí
Además, no hay casos públicos de usuarios de Mullvad desanonimizados a través del VPN; en cambio, lo que se conoce son casos descubiertos por otros fallos de seguridad operativa. Si una agencia de inteligencia tuviera esa capacidad, cuesta creer que no la hubiera usado en casi 20 años pese a tener los datos
No entiendo cómo se obtiene una “probabilidad superior al 99%” solo con los números del artículo. Incluso asumiendo con fuerza que tanto la semilla de la primera IP bloqueada como la segunda están dentro del rango 0.4423~0.4358, eso solo significa que ese rango incluye al 0.65% de todos los usuarios de Mullvad
Si hay 100 mil usuarios, son 650 personas; o sea, se eliminó a más del 99% de los “sospechosos”, pero no se identificó a una sola persona con más de 99% de precisión a través de varias IP de salida
Visto de manera bayesiana, la superposición de semillas potenciales sí sería evidencia fuerte de que ambas IP pertenecen a la misma persona, o al menos a la misma cuenta de Mullvad, pero no parece que eso sea lo que el autor quiso decir
En la mayoría de sitios pequeños sí sería una evidencia bastante fuerte
El propósito de un VPN no incluye anonimizar al usuario frente a los sitios que visita, así que no debería sorprender que Mullvad no fuerce una IP de salida única. Los usuarios que quieren anonimato deberían usar una red como Tor
Si usas un VPN público, esperas que nadie sepa quién envía la solicitud, incluida la IP de origen
Con esa lógica, no se debería usar VPN para torrents. Porque significaría que no debe anonimizarte respecto de la IP de origen. Pero en la práctica sí funciona muy bien con torrents
Si te refieres a un VPN privado, Mullvad no es eso
Llevo mucho tiempo usando Mullvad y seguiré comprando y usando el servicio Mullvad VPN con una tarjeta de crédito a mi nombre, siempre que sea legal en mi país
Un VPN no es 100% anónimo ni fue diseñado para serlo. Más bien busca ofrecer cierto grado de privacidad a adultos que cumplen la ley
A la mayoría de las personas les daría vergüenza que colegas y vecinos supieran sobre su vida privada, lo que les gusta, lo que compran o lo que hacen. Por eso la mayoría debería usar VPN para proteger su privacidad
Por definición, “la mayoría de las personas” no quiere ni espera 100% de anonimato en línea; solo quiere algo de privacidad en su vida personal y sus relaciones
Un VPN no protege a criminales que quieren cometer delitos en línea y ser 100% anónimos frente al gobierno, ni pretende hacerlo. Esa distinción es importante. “La mayoría de las personas” no son criminales y no tienen esas expectativas irreales de Mullvad ni de ningún otro proveedor de VPN
No se puede descartar el informe solo con esa lógica. El hallazgo sigue siendo válido
Falta algo. Me pregunto si contactaron a Mullvad. También habría sido interesante ver cómo respondió el equipo de seguridad
Después me arrepentí de haber publicado este comentario. Fue innecesario, pero borrarlo ahora creo que se vería raro
Me sorprende que la gente espere que un VPN sea parecido a Tor
Dicho así, parece no tener sentido, y también hay que considerar que incluso los usuarios de Tor pueden ser desanonimizados si se controla el nodo de salida
La parte de “la IP de salida no se aleatoriza cada vez que te conectas, sino que se elige de forma determinista según la clave de WireGuard, y esta rota cada 1 a 30 días. Si usas un cliente de terceros, no rota nunca” me resulta un poco confusa
Si en el repositorio se detalla bien el método, no entiendo qué impide que un tercero haga la rotación de claves igual que el cliente oficial
El autor encontró algo bueno, y es bastante creíble que haya sido un error de Mullvad. Es bastante impactante que algo tan simple haya pasado desapercibido, aunque yo también podría haberlo pasado por alto
Dejando de lado la correlación de IP entre varios servidores, al principio también me pregunté por qué mantenían estable la IP del usuario dentro de un solo servidor. Pero la explicación del autor, de que eso imita a otros VPN que normalmente tienen una sola IP por servidor, tiene sentido
Si un usuario encuentra un servidor desde el que puede acceder a cierto servicio, tiene la ventaja de que al volver a conectarse a ese servidor probablemente obtendrá la misma IP y volverá a funcionar
Aun así, la correlación de IP entre varios servidores debería corregirse con algo como
rand.seed(user_pub_key + server_id)Trabajo en IPinfo. Nosotros estamos en el negocio de detección de VPN, pero sinceramente quiero darle a Mullvad el beneficio de la duda
Mullvad fue uno de los tres proveedores de VPN que no intentaron enviarnos información de geolocalización IP inexacta a proveedores como nosotros. Estoy seguro de que también corregirán este problema