Parte 2 de una serie de 3 partes sobre VPNs.

Esta parte se enfoca con más profundidad en las VPNs. Usaré mi configuración real de Mullvad VPN en Fedora Linux para ver qué sucede cuando te conectas, cómo el kernel maneja el tráfico, etc.

Este post no es un ad de Mullvad, sino escritos de parte de un usuario.



Qué Sucede Cuando te Conectas

Este es el flujo de una conexión a internet normal vs. una que pasa por una VPN:

vpn-vs-no-vpn-connection.webp

Nota que con una VPN, el tráfico primero llega a la interfaz wg0, se encripta, y luego va a la interfaz de red real como un paquete encriptado. El ISP solo ve el paquete externo. Todo lo que está dentro está encriptado.

Ahora vamos a configurar esto.



Instalando Mullvad en Linux

Yo uso Fedora, pero esto funciona en cualquier distro de Linux. Hay dos formas de ejecutar Mullvad: usando la app oficial (desde https://mullvad.net/) (que maneja todo por ti), o usando las herramientas crudas de WireGuard (que te da control total).

Fedora tiene WireGuard integrado directamente en el kernel, así que no se necesita ninguna dependencia de terceros.


La App Oficial de Mullvad

Para instalar la app oficial de Mullvad en Fedora Linux sigue los pasos de: https://mullvad.net/en/help/install-mullvad-app-linux#fedora.

# Agregar el repositorio oficial de Mullvad
sudo dnf config-manager addrepo --from-repofile=https://repository.mullvad.net/rpm/stable/mullvad.repo

# Instalar la app oficial
sudo dnf install mullvad-vpn

Después de la instalación, inicia sesión y conéctate usando el CLI (también puedes hacerlo con la GUI).

# Iniciar sesión con tu ID de cuenta de Mullvad (lo obtienes al registrarte)
mullvad account login 123456789

# Ver información de la cuenta (número de cuenta, vencimiento, nombre del dispositivo)
mullvad account get

# Establecer tu país preferido (Suecia en este ejemplo)
mullvad relay set location se

# Conectar
mullvad connect

# Ver estado (relay, funcionalidades, ubicación)
mullvad status

La app oficial crea la interfaz WireGuard, configura el enrutamiento, establece el kill switch, maneja el DNS, todo. Muy útil.


Lo que Crea la App

Cuando Mullvad se conecta, crea una interfaz WireGuard. Puedes verla así:

ip link show type wireguard

# Salida
42: wg0-mullvad: <POINTOPOINT,UP,LOWER_UP> mtu 1380 qdisc noqueue state UNKNOWN

Lo mismo que arriba pero viendo la interfaz específica.

ip addr show wg0-mullvad

# Salida
42: wg0-mullvad: <POINTOPOINT,UP,LOWER_UP> mtu 1380 qdisc noqueue state UNKNOWN

También puedes revisar la configuración de WireGuard (puede que necesites instalar el paquete wireguard-tools si no lo tienes).

sudo wg show

# Salida
interface: wg0-mullvad
  public key: <tu llave pública>
  private key: (oculta)
  listening port: 42069
  fwmark: 0xca6c

peer: <llave pública del servidor de Mullvad>
  preshared key: (oculta)
  endpoint: (ip:puerto)
  allowed ips: 0.0.0.0/0, ::/0
  latest handshake: hace 8 segundos
  transfer: 145.67 MiB recibidos, 12.34 MiB enviados

Algunas cosas a notar en la salida:

  • allowed ips: 0.0.0.0/0, ::/0: Esto significa que TODO el tráfico (IPv4 e IPv6) debe pasar por este peer. Es un túnel completo.
  • latest handshake: Debe ser reciente. Si esto está en blanco o es antiguo, el túnel no está funcionando.


Interfaces de Red Virtuales (wg0-mullvad)

Mullvad crea automáticamente la interfaz de red virtual wg0-mullvad para la VPN.

En Linux, hay 2 tipos principales de interfaces virtuales usadas por las VPNs:

TUN (Capa 3): Maneja paquetes IP crudos. Sin encabezados Ethernet. Esto es lo que usa OpenVPN. El kernel envía un paquete IP a la interfaz TUN, y un programa en espacio de usuario (OpenVPN) lo lee desde un descriptor de archivo en /dev/net/tun, lo encripta, y lo envía por un socket regular.

WireGuard (Módulo del Kernel): WireGuard no usa TUN. Registra su propio tipo de interfaz directamente en el kernel. Cuando creas una interfaz WireGuard, el módulo del kernel mismo maneja la encriptación. Sin intervención del espacio de usuario.

vpn-packet-flow.webp

Esta distinción importa para el rendimiento, ya que cada cambio de contexto entre el kernel y el espacio de usuario cuesta ciclos de CPU. Por eso WireGuard es más rápido que OpenVPN.

Puedes verificar que el módulo del kernel de WireGuard está cargado.

lsmod | grep wireguard

# Salida
wireguard             126976  0
libcurve25519          65536  1 wireguard
ip6_udp_tunnel         16384  2 wireguard,vxlan
udp_tunnel             40960  2 wireguard,vxlan


Rastreando un Paquete Desde tu Navegador Hasta el Cable

Esto es lo que sucede cuando visitas un sitio web mientras estás conectado a Mullvad.

Digamos que tu navegador solicita example.com (93.184.216.34).


La Aplicación Envía Datos

Tu navegador llama a send(). La pila TCP/IP del kernel crea un paquete:

  • IP de origen: 10.66.X.X (tu IP del túnel)
  • IP de destino: 93.184.216.34

El Kernel Consulta la Tabla de Enrutamiento

Mullvad usa enrutamiento por políticas, así que la ruta por defecto de la VPN vive en una tabla separada (no en la principal). El kernel revisa primero las reglas de políticas.

# Mostrar Reglas de Política

# Las reglas de política desvían el tráfico sin marca a la tabla de enrutamiento de la VPN
ip rule show

# Salida
0:      from all lookup local
32765:  not from all fwmark 0x6d6f6c65 lookup 1836018789
32766:  from all lookup main
32767:  from all lookup default
# Mostrar Tabla de Enrutamiento de la VPN

# La tabla de enrutamiento de la VPN envía todo a través del túnel
ip route show table 1836018789 # valor de la tabla del output anterior

# Salida
default dev wg0-mullvad scope link
# Mostrar Tabla de Enrutamiento Principal

# La tabla principal aún tiene tu gateway real (para el tráfico del servidor VPN)
$ ip route show

# Salida
default via 192.168.1.1 dev wlan0
10.66.0.0/16 dev wg0-mullvad proto kernel scope link src 10.66.X.X
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.100

Como nuestro paquete hacia 93.184.216.34 (example.com) no tiene la marca 0x6d6f6c65, coincide con la regla 32765 así que se enruta a través de la tabla VPN 1836018789 → interfaz wg0-mullvad, donde WireGuard lo encripta y le pone la marca.

Esa marca es la forma del kernel de decir “este paquete ya fue procesado.” En su segundo paso por las reglas de política, la marca hace que la regla 32765 lo omita, dejándolo caer hasta la tabla principal y salir por el gateway real, esta vez dirigido al servidor de Mullvad, no a example.com.

Tu ISP no ve más que tráfico UDP encriptado con destino a una IP de Mullvad.


Diagrama para Mostrar este Proceso Más Fácilmente

mullvad-how-it-work.webp



Cómo Mullvad Maneja el Enrutamiento (fwmarks)

Un bucle de enrutamiento es lo que ocurre cuando un paquete sigue siendo enviado a través del túnel VPN indefinidamente — el túnel intenta enviar tráfico a través de sí mismo, lo cual crea otro paquete que necesita pasar por el túnel, que crea otro, y así sucesivamente. Mullvad resuelve esto con marcas de firewall (fwmark) y enrutamiento por políticas, lo cual es más limpio que la solución ingenua de agregar una ruta estática para cada IP de servidor VPN.

Mullvad establece fwmark: 0xca6c en la interfaz WireGuard (wg0-mullvad), pero la lógica de enrutamiento se basa en una marca separada (0x6d6f6c65) aplicada a los paquetes que ya están encriptados y destinados al servidor VPN.

# Reglas de enrutamiento por políticas
ip rule show

# Salida
0:      from all lookup local
32765:  not from all fwmark 0x6d6f6c65 lookup 1836018789
32766:  from all lookup main
32767:  from all lookup default
# Lo que vive en la tabla de enrutamiento de la VPN
ip route show table 1836018789

# Salida
default dev wg0-mullvad scope link

La ruta por defecto de la VPN vive en una tabla separada (1836018789), no en la tabla de enrutamiento principal. La tabla principal mantiene tu gateway original intacto. La regla de política es lo que decide qué tabla usa un paquete:

  1. Tu app envía un paquete sin marca
  2. La regla 32765 coincide: "¿sin marca 0x6d6f6c65? → usar tabla VPN 1836018789"
  3. La tabla VPN 1836018789 lo envía por la interfaz wg0-mullvad, donde se encripta y se le estampa 0x6d6f6c65
  4. El paquete encriptado vuelve a pasar por las reglas, esta vez la regla 32765 lo omite, cae hasta la tabla principal, y sale por wlan0 hacia tu ISP con destino al servidor de Mullvad.

Esto previene bucles de enrutamiento sin IPs de servidor hardcodeadas. Si Mullvad cambia de servidores o cambias de ubicación, nada se rompe — la lógica está basada en marcas de paquetes, no en destinos.


Este mismo mecanismo es lo que hace posible el split tunneling. Para evitar la VPN en una app específica, Mullvad marca su tráfico con 0x00000f41 (para el rastreo de conexiones) y 0x6d6f6c65 (para el enrutamiento), lo cual le permite saltarse la tabla VPN y salir por la interfaz normal. Así es exactamente como funciona ejecutar Mullvad y Tailscale simultáneamente On Mullvad VPN and Linux… and Tailscale — las reglas de nftables marcan el tráfico de Tailscale con esas mismas marcas, así que se enruta fuera del túnel mientras todo lo demás permanece encriptado.

Más información sobre split tunneling: https://mullvad.net/en/help/split-tunneling-with-the-mullvad-app



La Funcionalidad Kill Switch

Un kill switch evita que el tráfico se filtre si el túnel VPN se cae. Cuando el kill switch de Mullvad está activo, Mullvad crea reglas de nftables (o iptables) que bloquean todo el tráfico que no pase por la interfaz VPN.

kill-switch.webp

Revisar el estado del kill switch de Mullvad.

mullvad lockdown-mode get

# Salida
Block traffic when the VPN is disconnected: on

Activar el kill switch de Mullvad.

mullvad lockdown-mode set on

Con esta funcionalidad, si el túnel WireGuard se cae, ya no hay interfaz wg0-mullvad. Todo el tráfico de las apps choca con la regla “BLOQUEAR todo lo demás”. Nada se filtra. Ninguna consulta DNS va a tu ISP. Ningún tráfico de aplicaciones sale sin encriptar. Nada.



La Siguiente Parte

Para la parte 3, el plan es ir más en profundidad, filtraciones de DNS en VPNs, técnicas para evitar la inspección profunda de paquetes, especialmente para entornos donde las conexiones VPN son activamente detectadas y bloqueadas. Redes corporativas, firewalls, etc.