WireGuard Roaming: la solución que evita las desconexiones de VPN móviles

¿Te fue útil?

Tu teléfono pasa del Wi‑Fi de la oficina a LTE, el VPN se cae, Slack vuelve a conectarse, tu sesión SSH se congela y tu cerebro de guardia empieza a hacer cálculos que no pidió.
Si has vivido esto, no te lo estás imaginando: la mayoría de los VPN fueron diseñados con la noción romántica de que las direcciones IP permanecen fijas.

WireGuard es uno de los raros VPN que trata el roaming como una realidad de primera clase. No es “amigable para móviles” en el sentido de marketing.
Es amigable para móviles en el sentido de “puedo salir de un edificio en medio de un incidente y mi túnel no implosionará”.

El verdadero problema del roaming: las redes mienten

“Roaming” suena educado. Como si tu portátil paseara por un prado y cambiara puntos de acceso con naturalidad.
En producción, roaming significa que tu IP origen y tu puerto origen cambian, los mapeos NAT se evaporan, las rutas se vuelven extrañas y el estado UDP se trata como un vaso desechable.

La mayor parte del dolor de los VPN móviles no es criptografía. Es estado. Específicamente: quién piensa que el par está “en” qué IP:puerto ahora mismo, y si los dispositivos intermedios coinciden el tiempo suficiente para que lleguen los paquetes.
Las redes celulares añaden más caos: NAT de operador, timeouts agresivos por inactividad y comportamientos de ahorro de energía que pausan tu app y sus sockets.

Las pilas clásicas de VPN a menudo vinculan la identidad a una sesión que asume implícitamente transporte estable. Cuando el transporte cambia, la sesión necesita renegociación.
La negociación toma tiempo. Algunas implementaciones lo hacen mal. Otras lo hacen “correctamente” pero requieren keepalives tan frecuentes que consumen batería y aún así fallan.

El enfoque de WireGuard es directo: tu identidad es tu clave pública. Los detalles de transporte son reemplazables.
Si llega un paquete autenticado válido desde una nueva dirección, WireGuard actualiza su idea de dónde vive ese par.
Eso es roaming. No es magia; es una decisión de diseño que operacionaliza lo obvio: los teléfonos se mueven.

Por qué las VPN móviles “se desconectan” aunque el túnel esté arriba

Muchos incidentes se clasifican erróneamente como “desconexión del VPN”. El túnel puede seguir configurado, la interfaz puede seguir existiendo y el cliente puede mostrar “conectado”.
Lo que realmente ocurre es una de estas:

  • El mapeo NAT expiró: el servidor responde a una dirección/puerto que ya no mapea al cliente.
  • Cambió el Path MTU: la ruta LTE se redujo; paquetes se pierden; TCP se queda atascado; los usuarios lo llaman “desconexión”.
  • DNS cambiado: te moviste a una red con resolutores diferentes; tu DNS del VPN no se aplica; las búsquedas de nombres fallan.
  • Cambió la política de enrutamiento: el SO decide que la ruta por defecto cambió; reglas de split tunnel en conflicto; parte del tráfico se fuga o se hace loop.
  • Desajuste de estado del cortafuegos: las “sesiones” UDP son una sugerencia; a mitad de roaming pierdes el tráfico de retorno.

WireGuard no soluciona todos estos por sí solo. Pero resuelve limpiamente el problema central de identidad/endpoint, lo que elimina una enorme clase de fragilidad.

Cómo funciona realmente el roaming en WireGuard

WireGuard es un túnel de capa 3 con un protocolo pequeño y una idea estricta: los paquetes deben estar autenticados.
Si el servidor recibe un paquete autenticado para un peer desde una nueva IP:puerto, actualiza el endpoint de ese peer a la nueva dirección y responde allí.
No se necesita ceremonia de “reconectar”.

Esa actualización de endpoint ocurre en ambos lados. El cliente también puede hacer roaming: si escucha de nuevo al servidor en una nueva dirección (menos común, pero relevante para anycast o servidores multihomed),
también actualiza su endpoint.

Handshake vs. paquetes de datos: qué actualiza qué

WireGuard usa un handshake basado en Noise. Un paquete de handshake está autenticado. Un paquete de datos también está autenticado.
El aprendizaje de endpoint ocurre cuando un paquete se autentica y descifra con éxito.
Ese es un detalle crítico: el spam UDP aleatorio no puede mover tu endpoint. Solo un peer que tenga las claves correctas puede hacerlo.

Así que roaming no es “aceptar paquetes desde cualquier lugar”. Es “aceptar paquetes desde cualquier lugar si demuestran quiénes son”.
Por eso puedes permitir con seguridad que clientes móviles se muevan entre Wi‑Fi, LTE, redes de hotel y el ocasional portal cautivo de aeropuerto de hace una década.

Por qué existen los keepalives si el roaming es tan bueno

El roaming arregla el problema del cambio de endpoint. No derrota los timeouts NAT por pura voluntad.
Si un cliente está detrás de un NAT e inactivo, el mapeo puede expirar. El servidor seguirá enviando respuestas al último endpoint conocido, que ahora apunta a nada.

La solución es PersistentKeepalive en el lado detrás del NAT (a menudo el cliente móvil).
Envía paquetes periódicos vacíos para mantener vivo el mapeo NAT.
Debes usarlo deliberadamente, no por superstición.

Los keepalives tienen un costo: batería, activaciones de radio y a veces mayor uso de datos.
Pero la alternativa es que tu túnel se convierta en un elemento decorativo de la interfaz.

Una cita que la gente de operaciones debería tatuar en sus runbooks

“La esperanza no es una estrategia.” — General Gordon R. Sullivan

Si tu VPN móvil depende de “el NAT suele mantener mapeos UDP por un tiempo”, estás funcionando con esperanza. La esperanza te despertará a las 2 a. m.

Hechos e historia que explican el diseño

WireGuard no apareció como una “mejor interfaz para OpenVPN”. Surgió de una frustración concreta: las pilas VPN eran grandes, difíciles de auditar y demasiado tolerantes con malos valores por defecto.
Aquí hay hechos concretos y puntos de contexto que hacen que el roaming parezca inevitable en lugar de sorprendente:

  1. WireGuard empezó alrededor de 2015 como un proyecto para construir un VPN más simple y auditable con valores criptográficos modernos.
  2. Usa el framework Noise (específicamente una variante del patrón Noise IK) para estructurar handshakes con fuertes propiedades de seguridad.
  3. Apunta a una base de código pequeña comparada con implementaciones legacy de VPN, lo que reduce la superficie de ataque y facilita las auditorías.
  4. Originalmente vivió fuera del árbol del kernel de Linux y luego llegó al kernel mainline en 2020, un gran voto de confianza y un acelerador de despliegue.
  5. Usa UDP por diseño para evitar el colapso TCP sobre TCP y porque UDP tolera mejor condiciones de red cambiantes.
  6. La identidad es una clave pública, no una dirección IP; las IPs solo se enrutan dentro del túnel como “AllowedIPs”.
  7. El roaming es un comportamiento de primera clase: los endpoints se aprenden dinámicamente basados en paquetes autenticados, no se fijan para siempre.
  8. Evita deliberadamente la negociación de cifrado; no hay un menú de “elegir entre 17 cifrados”. Esto previene juegos de degradación y deriva de configuraciones.
  9. Se implementa comúnmente en móviles usando las pilas de red nativas del SO (por ejemplo, proveedores de túnel), lo que ayuda a la estabilidad pero aún hereda políticas de energía del SO.

Qué configurar (y qué no)

El roaming “funciona por sí solo” solo si no lo saboteas con suposiciones equivocadas.
WireGuard es simple, pero esa simplicidad significa que estás más cerca del metal. Puedes definitivamente dispararte en el pie.
La pistola es pequeña. Sigue funcionando.

Decide la intención del túnel: túnel completo vs túnel dividido

Para usuarios móviles, el split tunnel suele ser la opción sensata por defecto salvo que tengas un requisito de cumplimiento específico.
El túnel completo resulta atractivo hasta que enrutas videollamadas por tu centro de datos, te conviertes accidentalmente en un ISP y descubres que los usuarios te juzgan por la física.

  • Túnel completo: client AllowedIPs incluye 0.0.0.0/0, ::/0. Debes proporcionar DNS, NAT de salida y manejar el MTU con cuidado.
  • Túnel dividido: client AllowedIPs incluye solo subredes internas (y quizá algunos rangos de servicios). Menos fallos, menos coste de ancho de banda.

Usa PersistentKeepalive en clientes detrás de NAT (usualmente móviles)

Si el cliente móvil está detrás de NAT y necesitas que sea alcanzable (para respuestas, tráfico push o simplemente sesiones confiables), configura:
PersistentKeepalive = 25 segundos en la entrada de peer del cliente hacia el servidor.

¿Por qué 25? Es un valor pragmático que supera muchos timeouts NAT sin ser absurdo. Pero no lo idolatres. Mide tus redes.

MTU: el silencioso asesino de tickets “se desconecta”

El roaming cambia rutas. Las rutas cambian MTU. LTE y algunas configuraciones Wi‑Fi pueden ser alérgicas a la fragmentación.
Cuando el MTU está mal, obtienes bloqueos, conectividad parcial y usuarios que describen “el VPN es inestable”.

Mi valor por defecto para WireGuard móvil es empezar alrededor de 1280 por compatibilidad con IPv6 y menos sorpresas.
En redes más limpias puedes subir (1420 es común). Pero si estás solucionando caídas móviles, reduce MTU antes de tocar la criptografía.

DNS: elige una historia y cuéntala consistentemente

Muchas “desconexiones” son en realidad fallos de resolución de nombres tras el roaming.
Decide si el DNS está:

  • Dentro del túnel: configura DNS en el cliente; asegura que el servidor DNS sea alcanzable vía AllowedIPs; asegura que el servidor reenvíe/responda.
  • Fuera del túnel: acepta el DNS local; entonces no finjas que los nombres internos funcionarán en todas partes.

Cortafuegos: permite lo que construiste

WireGuard usa UDP. Si tu perímetro piensa que UDP es sospechoso (suele ocurrir), debes permitirlo explícitamente.
Además: si ejecutas WireGuard en un puerto no estándar para “ocultarlo”, sé honesto sobre qué estás optimizando.
La seguridad por oscuridad es como ponerse un disfraz para una reunión de personal; sobre todo confunde a tus colegas.

Tareas prácticas: comandos, salidas, decisiones

Estas son tareas reales que ejecutaría durante la configuración o mientras depuro roaming y estabilidad móvil.
Cada una incluye un comando, una salida representativa, qué significa la salida y la decisión que tomas a continuación.

Tarea 1: Confirmar estado de la interfaz WireGuard en el servidor

cr0x@server:~$ sudo wg show
interface: wg0
  public key: 6E9q...yZ0=
  private key: (hidden)
  listening port: 51820

peer: oYt9...r3Q=
  allowed ips: 10.6.0.2/32
  latest handshake: 14 seconds ago
  transfer: 22.34 MiB received, 48.11 MiB sent
  persistent keepalive: every 25 seconds

Significado: El peer ha hecho handshake recientemente; hay transferencias; el keepalive está configurado.

Decisión: Si latest handshake es “never” o muy antiguo, deja de culpar al MTU o al DNS y céntrate en la alcanzabilidad (UDP/puerto/NAT).

Tarea 2: Comprobar si el servidor realmente escucha en el puerto UDP esperado

cr0x@server:~$ sudo ss -lunp | grep 51820
UNCONN 0      0            0.0.0.0:51820      0.0.0.0:*    users:(("wg",pid=1143,fd=6))

Significado: El kernel está escuchando en UDP/51820.

Decisión: Si nada está escuchando, tu problema es servicio/config local, no “roaming”. Arregla la unidad systemd o la configuración primero.

Tarea 3: Verificar que el firewall permite UDP de WireGuard

cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    iif "lo" accept
    udp dport 51820 accept
    ip protocol icmp accept
    ip6 nexthdr icmpv6 accept
  }
}

Significado: Política por defecto drop, pero UDP/51820 se acepta explícitamente.

Decisión: Si no ves una regla de aceptación, añade una. Si dependes de “probablemente lo permite el security group”, estás externalizando tu disponibilidad a buenas sensaciones.

Tarea 4: Observar handshakes en vivo para confirmar cambios de endpoint por roaming

cr0x@server:~$ sudo wg show wg0 latest-handshakes endpoints
peer: oYt9...r3Q=
  endpoint: 203.0.113.50:49213
  latest handshake: 1707142421

peer: 2xK1...a9c=
  endpoint: 198.51.100.77:61102
  latest handshake: 1707142414

Significado: Puedes ver el endpoint actual (IP:puerto) de cada peer. En móviles, ese puerto suele cambiar al hacer roaming.

Decisión: Si el endpoint nunca cambia aunque el usuario haga roaming, puede que veas tráfico fijado a través de un proxy, o que el cliente no envía nada tras el roaming (sueño/política de energía).

Tarea 5: Confirmar el reenvío de IP en el servidor (para tráfico enrutado)

cr0x@server:~$ sysctl net.ipv4.ip_forward net.ipv6.conf.all.forwarding
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

Significado: El servidor puede enrutar paquetes entre interfaces.

Decisión: Si forwarding es 0, los clientes pueden hacer handshake bien pero no alcanzar nada más allá del servidor. Arregla el forwarding antes de perseguir “bugs de roaming”.

Tarea 6: Confirmar que NAT está configurado (para túnel completo o egress a Internet)

cr0x@server:~$ sudo nft list table ip nat
table ip nat {
  chain postrouting {
    type nat hook postrouting priority 100; policy accept;
    oifname "eth0" ip saddr 10.6.0.0/24 masquerade
  }
}

Significado: El tráfico de la subred VPN se enmascara saliendo por eth0.

Decisión: Si haces túnel completo y falta NAT, los clientes se conectarán pero no llegarán a Internet. Eso se reporta como “VPN cae sitios”.

Tarea 7: Validar la tabla de enrutamiento para la subred de WireGuard

cr0x@server:~$ ip route show
default via 203.0.113.1 dev eth0
10.6.0.0/24 dev wg0 proto kernel scope link src 10.6.0.1

Significado: El servidor sabe que la subred VPN está directamente en wg0.

Decisión: Si falta la ruta de la subred VPN, la interfaz puede no estar activa o tener la dirección equivocada. Arregla eso primero.

Tarea 8: Comprobar MTU en wg0 y síntomas de path MTU

cr0x@server:~$ ip link show dev wg0
5: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/none

Significado: El MTU de la interfaz es 1420 (valor común).

Decisión: Si usuarios móviles reportan bloqueos en LTE, prueba a bajar el MTU (por ejemplo, 1280) en cliente y/o servidor. Luego vuelve a probar. Las correcciones de MTU parecen milagros porque son aburridas.

Tarea 9: Probar ping con “no fragmentar” a través del túnel (descubrimiento MTU)

cr0x@server:~$ ping -M do -s 1380 10.6.0.2 -c 3
PING 10.6.0.2 (10.6.0.2) 1380(1408) bytes of data.
ping: local error: message too long, mtu=1420
ping: local error: message too long, mtu=1420
ping: local error: message too long, mtu=1420

--- 10.6.0.2 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2046ms

Significado: El tamaño del paquete excede las restricciones de MTU de la interfaz; esto puede indicar que tu MTU de túnel no soporta la carga útil que intentas enviar sin fragmentación.

Decisión: Reduce MTU y repite hasta que tenga éxito. Si no consigues un tamaño “no fragmentar” estable, sospecha un agujero negro intermedio o filtrado ICMP.

Tarea 10: Capturar tráfico de WireGuard para ver si llegan paquetes durante el roaming

cr0x@server:~$ sudo tcpdump -ni eth0 udp port 51820 -c 10
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:13:01.112233 IP 203.0.113.50.49213 > 203.0.113.10.51820: UDP, length 148
12:13:01.113005 IP 203.0.113.10.51820 > 203.0.113.50.49213: UDP, length 92
12:13:26.144990 IP 198.51.100.22.60133 > 203.0.113.10.51820: UDP, length 148
12:13:26.145701 IP 203.0.113.10.51820 > 198.51.100.22.60133: UDP, length 92

Significado: Ves paquetes desde múltiples IPs/puertos de origen. Esto es exactamente lo que el roaming parece en el borde: misma clave de peer, endpoint diferente con el tiempo.

Decisión: Si ves paquetes entrantes pero wg show nunca actualiza tiempos de handshake, sospecha claves equivocadas o problemas de replay/reloj. Si no ves nada entrante, es red/firewall/NAT del operador.

Tarea 11: Confirmar la configuración del peer del cliente (en cliente Linux)

cr0x@server:~$ sudo wg showconf wg0
[Interface]
PrivateKey = (hidden)
Address = 10.6.0.2/32
DNS = 10.6.0.1

[Peer]
PublicKey = 6E9q...yZ0=
AllowedIPs = 10.0.0.0/8, 172.16.0.0/12
Endpoint = 203.0.113.10:51820
PersistentKeepalive = 25

Significado: Está configurado túnel dividido (solo rangos RFC1918), DNS apunta dentro del túnel, keepalive activado.

Decisión: Si AllowedIPs es demasiado amplio, podrías secuestrar redes locales (impresoras, portales cautivos). Si es demasiado estrecho, los servicios internos no se enrutarán.

Tarea 12: Buscar rutas conflictivas y policy routing en el cliente

cr0x@server:~$ ip rule show
0:      from all lookup local
32764:  from all lookup main
32765:  from all lookup default

cr0x@server:~$ ip route show table main | sed -n '1,12p'
default via 192.168.1.1 dev wlan0 proto dhcp metric 600
10.0.0.0/8 dev wg0 scope link
172.16.0.0/12 dev wg0 scope link

Significado: Rutas para subredes internas van por wg0; ruta por defecto queda en Wi‑Fi. Eso es comportamiento de split tunnel.

Decisión: Si la ruta por defecto apunta a wg0 inesperadamente, configuraste túnel completo. Confirma que eso era lo que querías antes de culpar a la “inestabilidad por roaming”.

Tarea 13: Confirmar el resolvedor DNS en efecto (ejemplo systemd-resolved)

cr0x@server:~$ resolvectl status | sed -n '1,80p'
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 5 (wg0)
    Current Scopes: DNS
         Protocols: +DefaultRoute
Current DNS Server: 10.6.0.1
       DNS Servers: 10.6.0.1

Significado: El DNS está fijado al servidor DNS del VPN en el enlace WireGuard.

Decisión: Si los servidores DNS siguen siendo el resolvedor de la red Wi‑Fi mientras esperas DNS internos, arregla la configuración DNS del cliente. Muchos reportes de “VPN caída” son “DNS incorrecto”.

Tarea 14: Comprobar timeouts de conntrack (por qué tu UDP desaparece)

cr0x@server:~$ sudo sysctl net.netfilter.nf_conntrack_udp_timeout net.netfilter.nf_conntrack_udp_timeout_stream
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 180

Significado: Los flujos UDP pueden expirar rápidamente (30s). En algunos firewalls/NATs esto es aún más corto.

Decisión: Si ves desconexiones por inactividad alrededor de 30 segundos, keepalive a 25 segundos típicamente lo estabilizará. Si la batería es un problema, ajusta según timeouts medidos.

Tarea 15: Confirmar sincronización horaria (los handshakes odian la deriva del reloj)

cr0x@server:~$ timedatectl
               Local time: Tue 2026-02-04 12:21:42 UTC
           Universal time: Tue 2026-02-04 12:21:42 UTC
                 RTC time: Tue 2026-02-04 12:21:42
                Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

Significado: El reloj está sincronizado. Bien.

Decisión: Si el reloj del sistema no está sincronizado, puedes ver rarezas en el handshake y rechazo por replay. Arregla NTP antes de inventar teorías nuevas.

Tarea 16: Verificar que los paquetes se enrutan entre el cliente VPN y la subred interna

cr0x@server:~$ ip route get 10.20.30.40 from 10.6.0.2 iif wg0
10.20.30.40 from 10.6.0.2 iif wg0
    via 10.0.0.1 dev eth0

Significado: El kernel enrutaría tráfico desde el cliente VPN hacia la red interna vía eth0 (ejemplo).

Decisión: Si esto apunta de nuevo a wg0 o a ninguna parte, tienes asimetría de enrutamiento. El roaming no te salvará de un enrutamiento malo.

Guía rápida de diagnóstico

Cuando un usuario móvil de WireGuard dice “el VPN se desconecta al salir del Wi‑Fi”, no empieces por la ideología.
Comienza por el camino más corto para aislar el cuello de botella: transporte, handshake, enrutamiento, MTU, DNS.

Primero: ¿Llega UDP al servidor en absoluto?

  • En el servidor: ejecuta una captura corta en el puerto de WireGuard mientras el usuario cambia Wi‑Fi → LTE.
cr0x@server:~$ sudo tcpdump -ni eth0 udp port 51820 -c 20
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:15:01.100001 IP 198.51.100.22.60133 > 203.0.113.10.51820: UDP, length 148
12:15:01.100550 IP 203.0.113.10.51820 > 198.51.100.22.60133: UDP, length 92

Si no ves nada: firewall, security group, filtrado ISP, endpoint/puerto equivocado, o el cliente no envía porque el SO lo suspendió. Arregla la alcanzabilidad.

Si ves paquetes: pasa a la validación del handshake.

Segundo: ¿WireGuard los acepta (actualiza handshakes)?

cr0x@server:~$ sudo wg show wg0
interface: wg0
  public key: 6E9q...yZ0=
  listening port: 51820

peer: oYt9...r3Q=
  endpoint: 198.51.100.22:60133
  latest handshake: 6 seconds ago
  transfer: 4.12 MiB received, 6.88 MiB sent

Si el handshake es reciente: el túnel está vivo. “Desconexión” probablemente sea comportamiento de enrutamiento/MTU/DNS/aplicación.

Si el handshake sigue viejo/never: claves incorrectas, configuración de peer equivocada o paquetes no válidos de WireGuard para esa interfaz. Verifica configuraciones.

Tercero: ¿El problema es solo cierto tráfico (MTU/DNS/enrutamiento)?

  • Prueba ping por IP (evita DNS).
  • Prueba resolución DNS a través del servidor DNS del VPN.
  • Prueba una conexión TCP con una carga pequeña, luego cargas mayores.

Si las solicitudes pequeñas funcionan pero las descargas grandes se atascan, MTU es tu sospechoso principal.
Si IP funciona pero los nombres fallan, DNS.
Si solo algunas subredes fallan, AllowedIPs o enrutamiento.

Errores comunes: síntoma → causa raíz → solución

Estos son los patrones recurrentes detrás de “el roaming de WireGuard no funciona”, que normalmente significa “construimos un túnel perfecto dentro de una red imperfecta”.

1) Síntoma: “Funciona en Wi‑Fi, falla en LTE”

Causa raíz: NAT del operador y timeouts UDP por inactividad cortos; el mapeo expira durante la inactividad, el servidor responde a un endpoint muerto.

Solución: Configura PersistentKeepalive = 25 en la entrada de peer del cliente móvil; opcionalmente bájalo (por ejemplo, 15) si el operador es más agresivo. Confirma con timestamps de handshake.

2) Síntoma: “Conectado, pero nada carga tras el roaming”

Causa raíz: El handshake está bien, pero hay un agujero negro MTU tras el cambio de ruta.

Solución: Baja MTU en el cliente (empezar en 1280) y/o en el servidor. Valida con ping -M do y transferencias reales de aplicaciones.

3) Síntoma: “Algunos servicios internos funcionan, otros se agotan”

Causa raíz: AllowedIPs faltantes en rutas, o solapamiento de rangos privados con la red local (la cafetería usa 10.0.0.0/8 también).

Solución: Usa rutas más específicas, evita enrutar todo RFC1918 si puedes, o replanifica redes internas si te gustan los proyectos largos. Si debes usar rutas amplias, añade excepciones de policy routing.

4) Síntoma: “El VPN dice conectado, pero el DNS está roto”

Causa raíz: El DNS no es aplicado por el SO del cliente, o el servidor DNS no es alcanzable vía AllowedIPs, o el DNS solo escucha en LAN.

Solución: Asegura que la IP del servidor DNS esté dentro de AllowedIPs y sea alcanzable; configura la integración del resolvedor (systemd-resolved, NetworkManager, campo DNS del cliente móvil). Verifica con el estado del resolvedor.

5) Síntoma: “El roaming causa un nuevo handshake y las sesiones mueren de todos modos”

Causa raíz: Las sesiones a nivel de aplicación no toleran cambios de ruta (algunas sesiones TCP se caen), o los cortafuegos stateful reinician los flujos.

Solución: Prefiere protocolos de aplicación que reintenten limpiamente; evita middleboxes stateful entre clientes y servidor cuando sea posible; mantén el servidor WireGuard cerca del borde.

6) Síntoma: “Varios clientes se ‘roban’ la conectividad entre sí”

Causa raíz: Claves de peer duplicadas o AllowedIPs duplicadas; WireGuard enruta por AllowedIPs y espera unicidad.

Solución: Una clave única por dispositivo; una AllowedIPs única por peer (al menos /32 o IP de túnel asignada). Audita configuraciones y rota claves.

7) Síntoma: “Handshake reciente, pero los paquetes no llegan a la red interna”

Causa raíz: Falta de IP forwarding, rutas faltantes, NAT faltante, o enrutamiento asimétrico en la red interna (la ruta de retorno no conoce 10.6.0.0/24).

Solución: Activa forwarding; añade la ruta interna de vuelta a la subred VPN; o usa NAT (menos elegante pero efectivo) según las restricciones de red.

8) Síntoma: “Muere cuando la pantalla del teléfono se apaga”

Causa raíz: La gestión de energía del SO suspende el proceso VPN o limita la red en segundo plano; la cadencia de keepalive se vuelve irrelevante si el proceso no se programa.

Solución: Usa configuraciones VPN always-on específicas de la plataforma; configura reglas on‑demand; en Android, excluye la app de optimización de batería donde la política lo permita.

Tres micro-historias corporativas desde el terreno

Micro-historia 1: El incidente causado por una suposición equivocada

Una empresa mediana desplegó WireGuard para un equipo de ingeniería móvil. La migración fue fluida—hasta que no lo fue.
Los usuarios se quejaron de que el VPN “se desconectaba al salir de la oficina”. El equipo supuso que era un bug de WireGuard porque la UI aún mostraba “conectado”.

El primer respondedor hizo lo que todos hacen bajo presión: reinició cosas. Ayudó, temporalmente.
El roaming de Wi‑Fi a LTE creó nuevos puertos de origen. El servidor vio paquetes llegando. Los handshakes se actualizaron. Pero el tráfico de aplicaciones aún moría tras un minuto de inactividad.

La suposición equivocada fue sutil: creían que el NAT delante del servidor WireGuard era “lo suficientemente stateful” y mantendría mapeos UDP vivos varios minutos.
En ese entorno no lo hacía. El timeout UDP del NAT era corto, y el comportamiento del carrier era aún más corto en inactividad.

La solución fue aburrida e inmediata: configurar PersistentKeepalive para los clientes móviles. Las “desconexiones” desaparecieron.
El postmortem no dijo “WireGuard necesita mejorar.” Dijo “mide la red que tienes, no la que recuerdas.”

También actualizaron su runbook: cualquier reporte de “desconexión tras inactividad” dispara primero una revisión de conntrack/keepalive.
El incidente no se repitió, que es la forma más alta de elogio en operaciones.

Micro-historia 2: La optimización que salió mal

Otra organización quiso reducir el consumo de batería. Alguien notó que los keepalives eran cada 25 segundos y decidió que era “derrochador”.
Cambiaron el valor para aumentarlo a 120 segundos para dispositivos móviles. En la oficina todo parecía bien; en casa con Wi‑Fi todo parecía bien.

Luego el equipo de ventas viajó. Hoteles, aeropuertos, tethering, LTE en desplazamiento—exactamente los entornos donde los timeouts NAT son menos predecibles.
Los tickets se dispararon: CRM no cargaba, paneles internos se agotaban, “VPN inestable.” La mesa de ayuda empezó a aconsejar togglear modo avión, que no es solución; es un ritual.

El revés tuvo dos partes. Primero, algunas redes expiraban estado UDP en menos de dos minutos.
Segundo, cuando los teléfonos dormían, el primer paquete tras despertar debía lidiar con nuevos mapeos NAT y a veces pérdida de paquetes; sin tráfico keepalive frecuente, el aprendizaje de endpoint quedaba por detrás de las expectativas del usuario.

Revirtieron a 25 segundos para esos usuarios e introdujeron una política: valores de keepalive por niveles según perfil de usuario.
Dispositivos sensibles a la batería obtuvieron 40 segundos tras pruebas; roles de alta movilidad se mantuvieron en 25. La respuesta correcta no fue “bajar keepalives para siempre.”
Fue “deja de optimizar sin un budget de fallos.”

También aprendieron a hacer pruebas de roaming fuera de la oficina. Un VPN que solo funciona en tu Wi‑Fi corporativo es una LAN con cosplay.

Micro-historia 3: La práctica aburrida pero correcta que salvó el día

Una financiera ejecutaba WireGuard como parte de su acceso remoto. Nada fancy: puerto estable, reglas de firewall explícitas, MTU conservador y gestión estricta de peers.
Su gestión de cambios era igual de poco glamorosa: configuraciones en control de versiones, despliegue por fases y una auditoría semanal para AllowedIPs duplicadas.

Un lunes, un lote nuevo de dispositivos fue provisionado por un equipo separado. Un error sutil introdujo IPs de túnel duplicadas para un puñado de clientes.
En WireGuard, AllowedIPs no son solo “qué enrutar al peer.” También determinan qué peer debe recibir paquetes.
Las duplicidades crean caos. No siempre instantáneo. El peor tipo.

Aquí las prácticas aburridas rindieron frutos. Su trabajo de auditoría marcó duplicados rápidamente.
Sus logs y snapshots de wg show ya se recopilaban en el mismo lugar, así que el on‑call pudo correlacionar “peer flaps” con el cambio de aprovisionamiento.

Pausaron el aprovisionamiento, rotaron los peers afectados y se recuperaron antes de que se volviera un incidente mayor.
Nadie escribió un post interno triunfal. Bien. El resultado no fue una “recuperación heroica.” El resultado fue “los clientes no lo notaron.”

En ops, lo aburrido es una característica. La emoción es un indicador adelantado de futuro papeleo.

Listas de verificación / plan paso a paso

Paso a paso: Desplegar WireGuard para usuarios móviles que hacen roaming

  1. Elige tu modelo de enrutamiento: split tunnel salvo que tengas una razón real para túnel completo.
  2. Asigna una subred de túnel estable: p. ej., 10.6.0.0/24, un /32 por dispositivo.
  3. Asegura unicidad: keypair único por dispositivo; IP de túnel única por dispositivo; no usar una “clave móvil” compartida.
  4. Establece MTU conservador: empieza en 1280 para despliegues mobile-heavy; sube solo tras probar en LTE reales.
  5. Activa keepalive para clientes detrás de NAT: empieza en 25 segundos, ajusta según timeouts observados y impacto en batería.
  6. Haz explícitas las reglas de firewall: permite UDP al puerto de WireGuard; registra drops durante el despliegue.
  7. Habilita forwarding y rutas: no dependas de NAT salvo que sea necesario; si haces túnel completo, configura NAT intencionalmente.
  8. Decide comportamiento DNS: si el DNS está dentro, asegura la alcanzabilidad y la integración cliente.
  9. Prueba roaming en el mundo real: Wi‑Fi → LTE, LTE → Wi‑Fi, sleep/wake, tethering, portales cautivos.
  10. Instrumenta lo básico: guarda snapshots periódicos de wg show, edades de handshake y estadísticas de interfaz; alerta en “handshake never” para usuarios activos.

Lista operativa: Cuando alguien reporta “VPN se desconecta en móvil”

  • ¿El servidor recibe UDP durante la ventana de fallo? (tcpdump)
  • ¿Avanzan los timestamps de handshake? (wg show)
  • ¿Cambia el endpoint cuando el usuario hace roaming? (wg show endpoints)
  • ¿Está keepalive configurado en el lado detrás del NAT? (wg showconf)
  • ¿Puedes hacer ping por IP a través del túnel? (ping a IP túnel / IP interna)
  • ¿Las búsquedas DNS funcionan por el DNS del VPN? (resolvectl / dig)
  • ¿Bajar MTU arregla transferencias grandes? (ip link + ping -M do)
  • ¿Hay AllowedIPs duplicadas o IPs de túnel duplicadas? (auditoría de config)

Broma #1: Si tu plan de troubleshooting empieza con “reinstala la app del VPN,” básicamente lo estás apagando y encendiendo con pasos extra.

Preguntas frecuentes

1) ¿Significa el roaming de WireGuard que no necesito keepalives?

No. El roaming maneja los cambios de endpoint cuando fluyen paquetes. Los keepalives manejan los timeouts NAT en inactividad para que los paquetes puedan fluir cuando retomes la actividad.
Si tu cliente está inactivo detrás de NAT, el keepalive suele ser la diferencia entre “estable” y “misteriosamente muerto.”

2) ¿Por qué mi cliente WireGuard dice “conectado” cuando nada funciona?

Porque “conectado” suele significar “la interfaz existe y la configuración está cargada”, no “los paquetes fluyen ahora mismo”.
Revisa latest handshake. Si es antiguo, no estás realmente conectado. Si es reciente, mira MTU, rutas y DNS.

3) ¿Cuál es un buen valor de PersistentKeepalive para teléfonos?

Empieza en 25 segundos. Si ves desconexiones por inactividad antes de eso, bájalo. Si el impacto en batería es un problema y tus redes son tolerantes, súbelo con cuidado.
No lo pongas a 0 a ciegas esperando que los operadores respeten tus objetivos de disponibilidad.

4) ¿Se reconecta WireGuard más rápido que IPsec/IKE al hacer roaming?

A menudo, sí—porque no requiere una renegociación pesada solo para aceptar un nuevo endpoint.
Pero la percepción del usuario también depende de DNS, MTU y la capacidad de la aplicación para reintentar. WireGuard elimina un gran obstáculo; no repavimenta toda la carretera.

5) ¿Cambiar de red durante una sesión SSH aún rompe la sesión?

Puede. WireGuard puede mantener el túnel vivo, pero las sesiones TCP pueden reiniciarse si se pierden paquetes o si middleboxes eliminan el estado.
Usa mosh para shells remotos cuando esperes roaming, o asegúrate de que tu ruta de red no involucre dispositivos stateful que entren en pánico ante cambios.

6) ¿Debo ejecutar WireGuard en el puerto 53/123/443 para “pasar por las redes”?

Evítalo salvo que tengas un requisito claro y probado. Camuflar el puerto puede chocar con servicios reales, activar filtrados y complicar el debug.
Si necesitas traversal confiable, resuélvelo con políticas de red adecuadas o un puerto permitido conocido—no te disfraces de DNS.

7) ¿Por qué algunos rangos IP internos fallan en Wi‑Fi público?

Solapamiento de espacios de direcciones privadas. Si tu empresa enruta 10.0.0.0/8 por el VPN y el hotel también usa 10.0.0.0/8 localmente,
has creado una pelea de enrutamiento. Reduce AllowedIPs o reordena direcciones.

8) ¿Es el MTU realmente un problema tan común con WireGuard?

Sí. Especialmente en móviles. El roaming cambia la ruta subyacente, y el descubrimiento de Path MTU no está soportado de forma fiable en todas las redes.
Si transferencias grandes se atascan o algunos sitios cargan y otros no, MTU es un sospechoso principal.

9) ¿WireGuard soporta “servidores multi-endpoint” para redundancia?

No en el sentido de listar múltiples endpoints para un mismo peer. Puedes construir redundancia con DNS, anycast, herramientas de failover o túneles múltiples,
pero WireGuard en sí espera un endpoint actual por peer que se actualiza según el aprendizaje.

10) ¿WireGuard es “sin estado”?

No. Mantiene estado para peers: claves, contadores, endpoints, tiempos de handshake. Simplemente es menos ceremonioso que muchos VPN.
La clave es que el estado se actualiza rápido y de forma segura cuando cambia el endpoint.

Broma #2: Los dispositivos NAT tienen dos pasatiempos: expirar mapeos UDP y enseñarte humildad.

Próximos pasos que puedes hacer esta semana

Si quieres menos tickets de VPN móvil y menos quejas de “se desconectó otra vez”, haz esto en orden:

  1. Mide la salud de los handshakes: recopila edades de handshake de wg show para usuarios activos; alerta en “never” o handshakes obsoletos durante horas laborales.
  2. Estandariza keepalive para móviles: configura PersistentKeepalive para clientes detrás de NAT y documenta cuándo te desvías del valor por defecto.
  3. Fija una base conservadora de MTU: elige 1280 para mobile-first; sube solo tras pruebas reales de roaming en LTE.
  4. Haz explícito el comportamiento DNS: o controlas DNS dentro del túnel de extremo a extremo o deja de prometer nombres internos fuera de la red.
  5. Audita configuraciones de peers: detecta claves duplicadas y AllowedIPs duplicadas; rota lo sospechoso inmediatamente.
  6. Practica la guía rápida de diagnóstico: tcpdump → handshake → MTU/DNS/enrutamiento. Entrénalo hasta que sea memoria muscular.

WireGuard roaming es la solución que elimina toda una categoría de desconexiones de VPN móviles.
Pero aún tienes que operarlo como un sistema de producción: mide, prueba en redes hostiles y manten tu configuración aburrida a propósito.

← Anterior
Redes en Linux: pérdida de paquetes ‘solo a veces’ — el flujo real de depuración
Siguiente →
Haz que WSL Arranque Rápido: Evita shells lentos y scripts init rotos

Deja un comentario