El síntoma: “VPN conectada” y aun así Slack dice que estás desconectado, tu SSH caduca, o el DNS filtra silenciosamente al router de la cafetería que ahora lamentas. WireGuard es refrescantemente simple, pero las redes tienen una habilidad para convertir “simple” en “¿por qué está llorando este paquete?”
Esta es una guía orientada a producción para poner en marcha un cliente WireGuard en Windows, macOS y Linux—rápido—además de cómo diagnosticar los modos de fallo clásicos sin convertir tu portátil en un router accidental.
1) El modelo mental: qué hace realmente WireGuard en un cliente
WireGuard no es un interruptor mágico de “internet seguro”. Es un software muy pequeño y muy opinado que crea una interfaz de red virtual (normalmente wg0 en Linux, un adaptador “WireGuard Tunnel” en Windows, una interfaz utun en macOS). Cuando el túnel está arriba, tu SO enruta cierto tráfico hacia esa interfaz. El peer de WireGuard en el otro extremo desencripta y reenvía hacia adelante (a menudo hacia tu red corporativa, a veces hacia Internet pública).
Las tres palancas que realmente controlas
- Claves: quién puede hablar con quién.
- AllowedIPs: qué destinos se enrutan al túnel (y también cómo se emparejan los peers en el receptor).
- Endpoint: dónde está la otra parte ahora mismo (y si el NAT la mantiene alcanzable).
Todo lo que duele suele ser una de estas disfrazada: decisiones de enrutamiento, comportamiento DNS, estado de firewall/NAT o MTU. WireGuard es directo: monta la criptografía y empuja paquetes. No negociará rutas como una VPN empresarial parlanchina; no “arreglará” tu DNS a menos que se lo digas; no adivinará si querías enrutamiento dividido o túnel completo.
Una mentalidad operativa útil: trata a WireGuard como un cable de red punto a punto que enchufas y desenchufas. Si los paquetes no atraviesan el cable, inspeccionas (1) enlace arriba (handshake), (2) enrutamiento L3, (3) accesibilidad L4, (4) resolución de nombres. Mismo orden cada vez. Tu yo futuro te mandará una nota de agradecimiento.
Una cita para mantenerte honesto, de John Allspaw (idea parafraseada): La fiabilidad viene de cómo respondes al fallo, no de fingir que el fallo no ocurrirá.
Broma #1: WireGuard es como un portero bien entrenado—silencioso, eficiente y completamente desinteresado en tus sentimientos sobre el enrutamiento.
2) Hechos interesantes y contexto (para que dejes de pelear con la herramienta)
Esto no es trivia por el gusto de la trivia. Explican por qué WireGuard se comporta como lo hace—y por qué algunas “expectativas tradicionales de VPN” no se aplican.
- WireGuard fue diseñado para ser pequeño: muchas menos líneas de código que las pilas VPN clásicas, con el objetivo de reducir la superficie de ataque y la complejidad operativa.
- Usa primitivas modernas por defecto: no eliges suites de cifrado; el protocolo selecciona un conjunto estrecho y contemporáneo (NoiseIK, ChaCha20-Poly1305, Curve25519, BLAKE2s, HKDF).
- Es una VPN de capa 3: enruta paquetes IP (y puede manejar IPv6 limpiamente). No es un puente L2 a menos que construyas eso por encima.
- “AllowedIPs” es tanto enrutamiento como control de acceso: en el lado receptor, es el mapeo que decide a qué peer pertenece un paquete desencriptado; los solapamientos pueden causar comportamientos confusos.
- Roaming está integrado: si la IP pública del cliente cambia (Wi‑Fi a LTE), WireGuard puede seguirlo tan pronto como vea tráfico autenticado desde la nueva dirección.
- La compatibilidad con NAT no es magia: aún depende de que el estado UDP se mantenga vivo; por eso existe
PersistentKeepalive. - Primero Linux, pero realidad multiplataforma: la implementación en kernel de Linux es la referencia para rendimiento; otras plataformas usan integraciones nativas o una implementación en espacio de usuario con peculiaridades específicas del SO.
- WireGuard llegó pronto a Linux “mainstream”: se fusionó en el kernel de Linux (era 5.6), por eso se siente como ciudadano de primera clase en distros modernas.
- Evita intencionadamente características de negociación: no hay la complejidad estilo IKE. Genial para humanos. A veces incómodo para listas de verificación empresariales.
3) Claves, peers y el único archivo que importa
Una configuración de cliente WireGuard es un pequeño archivo tipo INI. Tiene dos secciones: [Interface] (tu interfaz virtual local) y una o más entradas [Peer] (los endpoints remotos a los que cifrarás).
Configuración mínima del cliente (ejemplo de túnel dividido)
Esta es la forma desde la que deberías empezar. Luego añade complejidad solo cuando haga falta. Especialmente en redes corporativas, cada línea extra es una nueva forma de perder una tarde.
cr0x@server:~$ cat wg-client.conf
[Interface]
PrivateKey = <client-private-key>
Address = 10.8.0.2/32
DNS = 10.8.0.1
[Peer]
PublicKey = <server-public-key>
Endpoint = vpn.example.net:51820
AllowedIPs = 10.8.0.0/24, 10.20.0.0/16
PersistentKeepalive = 25
Interpretación, en inglés operativo sencillo:
- Address: la IP del cliente en el túnel. El
/32no es un error; significa “esta interfaz posee solo esta IP,” lo que reduce comportamientos de enrutamiento accidentales. - DNS: qué resolver usar mientras el túnel está arriba. Sin él, a menudo tendrás “puedo hacer ping a IPs pero los nombres fallan”.
- AllowedIPs: lista de túnel dividido. Solo esos destinos se enrutarán al túnel. Si pones
0.0.0.0/0(y quizá::/0), estás tunelizando todo. - PersistentKeepalive: mantiene el estado NAT vivo para clientes detrás de NATs restrictivos (hoteles, LTE). 25 segundos es el número común que “simplemente funciona”.
Dos reglas que previenen la mayoría de las interrupciones
- No solapar AllowedIPs entre peers en la misma interfaz a menos que disfrutes la selección de peers no determinista.
- Decide túnel dividido vs completo desde el principio y codifícalo explícitamente. “Añadimos 0.0.0.0/0 y vemos” es la forma de romper la impresión, VoIP y tu propia paciencia.
4) Configuración del cliente en Windows (simple, con los habituales pies de plomo)
Enfoque recomendado: app oficial WireGuard para Windows
En Windows, sé aburrido: usa el cliente oficial de WireGuard con interfaz. Instala un adaptador de túnel WireGuard y gestiona rutas de forma limpia. Puedes importar un archivo de configuración, alternar el túnel y sobrevive a reinicios sin scripts creativos.
Pasos que funcionan en empresas reales
- Importa la configuración: usa “Import tunnel(s) from file”. No teclees claves a mano. Los humanos son malos con base64.
- Nombra el túnel de forma explícita: “corp-split” o “prod-breakglass.” “test” se vuelve permanente y luego se convierte en tu identidad.
- Activa on-demand solo si entiendes la red en Windows: es fácil crear estados “conectado pero inútil” cuando las redes cambian.
- Comprueba el comportamiento DNS: Windows tiene una larga historia de listas de búsqueda DNS y precedencia de resolvers que hacen cosas inesperadas cuando existen múltiples interfaces.
Peligros en Windows que deberías anticipar
- Handshakes funcionan, tráfico no: a menudo es un problema de rutas o firewall, no de WireGuard en sí. Windows puede tener múltiples rutas por defecto con métricas que te sorprenden.
- Fugas de DNS o resolver incorrecto: si no estableces
DNSen la config, Windows seguirá usando lo que le apetezca (a menudo el DNS de la NIC física). - Prioridad/métricas del adaptador: a veces Windows insiste en enviar tráfico fuera del túnel porque la interfaz física tiene una métrica más baja.
- Portales cautivos: hoteles y Wi‑Fi de invitados pueden bloquear UDP o requerir login web; el túnel no subirá hasta que el portal no esté satisfecho.
5) Configuración del cliente en macOS (app vs wg-quick y las trampas DNS)
macOS te ofrece dos opciones comunes: la app oficial de WireGuard (recomendada) o herramientas de línea de comandos (vía paquetes de terceros). Para la mayoría que quiere fiabilidad, la app gana: se integra con el sistema de extensiones de red de macOS y maneja el ciclo de vida de la interfaz sin que tengas que pegar launch agents.
Usa la app salvo que tengas una razón para no hacerlo
Wi‑Fi corporativa y ciclos frecuentes de suspensión/despertar son donde las herramientas de VPN “casi funcionan” mueren. La app suele recuperarse mejor de cambios de red y restablecer el estado DNS/rutas.
Realidades DNS específicas de macOS
El DNS en macOS no es “un archivo, un resolver”. Es una pila con resolvers por interfaz, dominios de búsqueda y resolución con ámbito. Un túnel WireGuard puede estar arriba y funcionando, mientras tu navegador sigue resolviendo nombres internos por el resolver equivocado debido al orden de resolvers o dominios de búsqueda faltantes.
Si tu empresa usa DNS dividido (dominios internos resueltos solo vía DNS interno), deberías establecer ambos:
- Servidor DNS (por ejemplo, 10.8.0.1), y
- Dominios de búsqueda (por ejemplo,
corp.example), cuando tu cliente lo soporte.
Sin dominios de búsqueda, los usuarios escriben nombres cortos y obtienen respuestas DNS públicas. Eso no es un “error del usuario”; es un resultado predecible de configuración.
Peligro en macOS: suspensión/despertar y rutas obsoletas
Tras despertar, puedes ver un túnel “conectado” pero sin tráfico. Normalmente es estado UDP o una tabla de rutas que no se actualizó limpiamente. Alternar el túnel suele arreglarlo; también ayuda establecer PersistentKeepalive para clientes en roaming.
6) Configuración del cliente en Linux (wg-quick, NetworkManager y la realidad del enrutamiento)
Linux es donde WireGuard parece que siempre debió existir. Tienes el módulo del kernel, las herramientas wg, y wg-quick que es un envoltorio pragmático que configura la interfaz, rutas y ganchos DNS.
El camino de “simplemente hacerlo funcionar”: wg-quick
Pones una config en /etc/wireguard/wg0.conf y ejecutas wg-quick up wg0. Eso es todo. Lo mejor es que es reversible: wg-quick down wg0 limpia rutas y estado de interfaz.
Integración con NetworkManager: buena, pero sabe qué hace
Si estás en un portátil con NetworkManager, puedes importar la config de WireGuard y dejar que lo gestione. Puede ser excelente para roaming, pero añade otra capa que puede sobrescribir rutas o DNS dependiendo de la distro y versión. Al depurar, ten siempre claro quién “posee” la interfaz—wg-quick o NetworkManager—no ambos.
Peligros en Linux que muerden a ingenieros con experiencia
- Interacciones con enrutamiento por políticas: los sistemas modernos pueden tener múltiples tablas de enrutamiento (especialmente con plugins de contenedor/red). Tus rutas del túnel pueden acabar en el lugar equivocado si no tienes cuidado.
- Filtrado de ruta inversa:
rp_filterpuede descartar tráfico legítimo en escenarios de enrutamiento asimétrico. - iptables/nftables NAT: para configuraciones de cliente esto suele ser irrelevante, pero para “cliente que además hace forward” o “cliente como gateway”, debes hacer NAT y forwarding explícitamente.
- systemd-resolved: el manejo de DNS puede sorprenderte si
resolv.confes un stub y esperas queDNS=funcione sin los ganchos adecuados.
7) Tareas prácticas: comandos, salida esperada y decisiones (12+)
Estas son las comprobaciones que realmente ejecuto cuando alguien dice “WireGuard está arriba pero nada funciona.” Cada tarea incluye: comando, qué significa la salida y qué decisión tomas después.
Tarea 1: Confirmar que la interfaz existe y está arriba (Linux)
cr0x@server:~$ ip link show wg0
7: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/none
Significado: La interfaz wg0 existe y está UP. mtu 1420 es típico. state UNKNOWN es normal para túneles.
Decisión: Si está DOWN o falta, tu túnel no está arriba. Arregla el servicio/UI primero. Si está arriba, pasa al handshake y al enrutamiento.
Tarea 2: Comprobar handshake y contadores de tráfico de WireGuard
cr0x@server:~$ sudo wg show
interface: wg0
public key: 5Z5Jw0y5mOQ4rGqgXwq8yW9q0l1bQp3m5G5m6l8P8xk=
private key: (hidden)
listening port: 51820
peer: 9sZxq2Qb7D2i2c8p9n5m0tTn0aVY7mXlCkQw1kVv0m4=
endpoint: 203.0.113.10:51820
allowed ips: 10.8.0.0/24, 10.20.0.0/16
latest handshake: 18 seconds ago
transfer: 12.34 MiB received, 9.87 MiB sent
persistent keepalive: every 25 seconds
Significado: Tienes un handshake reciente y paquetes moviéndose. Si el handshake es “never”, probablemente tengas problemas con endpoint/UDP/firewall/NAT.
Decisión: Si el handshake es reciente pero el transfer se queda en 0, sospecha de enrutamiento/AllowedIPs/firewall en el otro extremo.
Tarea 3: Validar la IP del túnel de tu cliente
cr0x@server:~$ ip addr show dev wg0
7: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
inet 10.8.0.2/32 scope global wg0
valid_lft forever preferred_lft forever
Significado: El cliente tiene asignada la 10.8.0.2/32. Bien.
Decisión: Si falta o es incorrecta, corrige la Address en la config y baja/sube el túnel.
Tarea 4: Confirmar que las rutas para AllowedIPs se instalaron
cr0x@server:~$ ip route show table main | grep wg0
10.8.0.0/24 dev wg0 scope link
10.20.0.0/16 dev wg0 scope link
Significado: Existen rutas de túnel dividido. El tráfico hacia esas CIDR va por wg0.
Decisión: Si faltan rutas, o wg-quick no corrió, o otro gestor removió rutas, o usaste un método que no las añade automáticamente. Arregla eso antes de tocar DNS.
Tarea 5: Ver qué ruta se usará para un destino específico
cr0x@server:~$ ip route get 10.20.5.10
10.20.5.10 dev wg0 src 10.8.0.2 uid 1000
cache
Significado: El SO enviará paquetes a 10.20.5.10 vía wg0.
Decisión: Si dice dev eth0 (o interfaz Wi‑Fi), tus AllowedIPs/rutas están mal. Arregla el enrutamiento primero; no “depures WireGuard” cuando no se está usando.
Tarea 6: Probar accesibilidad por IP (evitar DNS)
cr0x@server:~$ ping -c 2 10.20.5.10
PING 10.20.5.10 (10.20.5.10) 56(84) bytes of data.
64 bytes from 10.20.5.10: icmp_seq=1 ttl=63 time=28.3 ms
64 bytes from 10.20.5.10: icmp_seq=2 ttl=63 time=27.9 ms
--- 10.20.5.10 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 27.933/28.110/28.288/0.177 ms
Significado: La accesibilidad L3 funciona a través del túnel.
Decisión: Si el ping por IP falla pero hay handshake, sospecha de firewall remoto, rutas faltantes en el servidor o MTU. Si el ping funciona pero los nombres fallan, pasa a tareas de DNS.
Tarea 7: Probar una ruta de servicio TCP (porque ICMP engaña)
cr0x@server:~$ nc -vz 10.20.5.10 22
Connection to 10.20.5.10 22 port [tcp/ssh] succeeded!
Significado: TCP/22 accesible; los grupos de seguridad/firewalls probablemente lo permitan.
Decisión: Si el ping funciona pero TCP falla, tienes un problema a nivel de firewall/servicio, no “VPN rota.” Escala al propietario del servicio o a política de seguridad.
Tarea 8: Comprobar selección de resolver DNS (Linux con systemd-resolved)
cr0x@server:~$ resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Link 7 (wg0)
Current Scopes: DNS
Protocols: +DefaultRoute
Current DNS Server: 10.8.0.1
DNS Servers: 10.8.0.1
Significado: DNS para wg0 está establecido a 10.8.0.1. Bien.
Decisión: Si el servidor DNS sigue siendo el del router Wi‑Fi, espera fallos de nombres internos y fugas. Arregla DNS en la config o en los ajustes de resolved.
Tarea 9: Probar que el DNS interno funciona (y ver a dónde va)
cr0x@server:~$ dig @10.8.0.1 internal-api.corp.example A +short
10.20.5.10
Significado: El resolver interno devuelve una dirección interna.
Decisión: Si esto funciona pero dig internal-api.corp.example falla, el problema es la selección de resolver/dominios de búsqueda, no el servidor.
Tarea 10: Comprobar MTU y agujeros negros de PMTU
cr0x@server:~$ ping -M do -s 1380 -c 2 10.20.5.10
PING 10.20.5.10 (10.20.5.10) 1380(1408) bytes of data.
1388 bytes from 10.20.5.10: icmp_seq=1 ttl=63 time=28.9 ms
1388 bytes from 10.20.5.10: icmp_seq=2 ttl=63 time=29.1 ms
--- 10.20.5.10 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
Significado: Al menos paquetes ICMP de ~1408 bytes con DF pasan. Buena señal.
Decisión: Si ves “Frag needed and DF set” o timeouts a tamaños mayores, reduce el MTU de WireGuard (a menudo en el rango 1280–1420). Los problemas de MTU suelen presentarse como “SSH funciona pero git clone se queda” o “web carga mitad de la página”.
Tarea 11: Confirmar accesibilidad UDP al endpoint (lado cliente)
cr0x@server:~$ nc -vu -w 2 vpn.example.net 51820
Connection to vpn.example.net 51820 port [udp/*] succeeded!
Significado: Tu sistema puede enviar UDP a ese host/puerto. No garantiza respuestas (UDP), pero descarta algunos bloqueos de salida locales.
Decisión: Si esto falla en una red corporativa, puede que necesites una política de salida diferente o un endpoint/puerto alternativo. No pierdas tiempo ajustando Keepalive si UDP está bloqueado por completo.
Tarea 12: Inspeccionar el estado del firewall (cliente Linux)
cr0x@server:~$ sudo nft list ruleset | sed -n '1,80p'
table inet filter {
chain input {
type filter hook input priority 0; policy accept;
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Significado: Forwarding está en drop (por defecto común), pero para un cliente eso está bien. Input/output accept significa que el propio cliente puede comunicarse.
Decisión: Si output está restringido, WireGuard puede hacer handshake pero el tráfico hacia subredes internas puede estar bloqueado. Ajusta reglas con cuidado o usa un perfil de firewall de host que permita el túnel.
Tarea 13: Verificar sysctl que puede romper túneles enrutados (rp_filter)
cr0x@server:~$ sysctl net.ipv4.conf.all.rp_filter
net.ipv4.conf.all.rp_filter = 1
Significado: El filtrado de ruta inversa está en modo “estricto” (1). Esto puede descartar tráfico en situaciones de enrutamiento asimétrico.
Decisión: Para uso normal de cliente, suele estar bien. Para enrutamiento dividido complejo o multi-homing, considera ponerlo en 2 (loose) en interfaces relevantes tras entender las implicaciones de seguridad.
Tarea 14: Confirmar qué archivo DNS estás usando realmente
cr0x@server:~$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Jan 2 10:11 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
Significado: Estás en systemd-resolved stub. Editar /etc/resolv.conf directamente no persistirá y puede que no haga lo que piensas.
Decisión: Configura DNS mediante resolvectl, NetworkManager o tu gestor de WireGuard, no editando a mano archivos stub esperando que funcione.
8) Guion de diagnóstico rápido (primeras/segundas/terceras comprobaciones)
Si solo memorizas un flujo de trabajo, que sea este. Encuentra el cuello de botella rápido sin hacer cambios por imitación.
Primero: ¿el túnel realmente intercambia paquetes?
- Comprueba que la interfaz existe y está arriba.
- Comprueba latest handshake y los contadores de transferencia.
- Si el handshake es nunca: céntrate en endpoint, accesibilidad UDP, NAT y keepalive.
Segundo: ¿el SO está enrutando el tráfico correcto al túnel?
- Confirma que existen rutas para tus destinos previstos (AllowedIPs).
- Usa una búsqueda de ruta para una IP interna conocida (
ip route geten Linux). - Si el tráfico no se enruta al túnel: arregla AllowedIPs o conflictos con el gestor de rutas.
Tercero: ¿puedes alcanzar algo por IP y luego por nombre?
- Haz ping a una IP interna. Luego prueba un puerto TCP (SSH/HTTPS) porque ICMP puede estar permitido cuando TCP no.
- Si IP funciona pero nombres fallan: arregla DNS (servidor, dominios de búsqueda, prioridad de resolver).
Cuarto: MTU y fallos de “funciona para cosas pequeñas”
- Si el chat funciona pero las transferencias grandes cuelgan: sospecha de MTU/fragmentación.
- Reduce el MTU en el túnel cliente y vuelve a probar.
Quinto: el otro lado (enrutamiento/NAT/firewall del servidor)
- El cliente solo puede enviar paquetes cifrados. El servidor decide si los enruta hacia adelante.
- Si handshake y enrutamiento del cliente parecen bien, puede que al servidor le falten rutas de vuelta al subnet del cliente o esté descartando tráfico forzado.
9) Errores comunes: síntoma → causa raíz → solución
1) “Conectado” pero sin handshake
Síntoma: La UI del cliente dice activo, pero latest handshake es “never”.
Causa raíz: Endpoint host/puerto incorrecto, UDP bloqueado, portal cautivo o el mapeo NAT expira instantáneamente.
Solución: Verifica el endpoint, prueba egress UDP, completa el login del portal cautivo, añade PersistentKeepalive = 25 para clientes en roaming y asegúrate de que el servidor realmente escucha en ese puerto.
2) El handshake funciona, pero ningún tráfico llega a redes internas
Síntoma: El handshake se actualiza, pero no puedes hacer ping a ninguna IP interna; los contadores de transferencia se mueven muy poco.
Causa raíz: AllowedIPs no incluye las subredes internas, o no se instalaron rutas, o la métrica de ruta de Windows prefiere la interfaz física.
Solución: Añade las CIDR internas correctas a AllowedIPs en el cliente. Confirma rutas. En Windows, comprueba la tabla de rutas y métricas; asegúrate de que las rutas del túnel sean más específicas que la ruta por defecto cuando uses túnel dividido.
3) Conectividad IP funciona, pero los nombres fallan
Síntoma: Puedes ping 10.20.5.10 pero ssh internal-api falla por no resolver.
Causa raíz: DNS no establecido, dominio de búsqueda faltante, systemd-resolved/NetworkManager no aplicando DNS al túnel, o DNS establecido pero bloqueado por política.
Solución: Establece DNS = ... en la config del cliente y asegúrate de que tu plataforma lo aplique. En macOS, verifica que el resolver del túnel se use realmente. Añade dominios de búsqueda donde se soporte.
4) Todo funciona excepto transferencias “grandes” (Git, Docker, copias de archivos)
Síntoma: Pings pequeños tienen éxito, algunos sitios web cargan, pero descargas grandes se quedan o cuelgan.
Causa raíz: MTU/PMTU blackhole; fragmentación bloqueada en algún punto entre cliente y servidor.
Solución: Reduce el MTU del túnel (prueba 1380, luego 1360, luego 1280). Vuelve a probar con pings DF. Prefiere un MTU consistente en la flota de clientes cuando sea posible.
5) El túnel dividido se convirtió accidentalmente en túnel completo
Síntoma: La impresión falla, Zoom va raro, dispositivos locales desaparecen, la IP pública cambia al egress de oficina.
Causa raíz: AllowedIPs incluye 0.0.0.0/0 (y posiblemente ::/0), o se añadió una ruta por defecto a nivel OS.
Solución: Elimina AllowedIPs por defecto. Si necesitas enrutamiento selectivo de Internet, hazlo intencionalmente con enrutamiento por políticas—no finjas que una ruta por defecto es “temporal”.
6) Dos peers, un destino: el tráfico va al lugar equivocado
Síntoma: Algunas subredes internas se enrutan intermitentemente al peer “equivocado”; el comportamiento cambia tras reconectar.
Causa raíz: AllowedIPs solapados entre peers en la misma interfaz.
Solución: Haz AllowedIPs disjuntos. Si necesitas conmutación por fallo, implémentalo con un mecanismo de nivel superior; no confíes en la ambigüedad.
7) Funciona en Wi‑Fi, falla en LTE/hotspot
Síntoma: En casa va bien; en el hotspot del teléfono hace handshake una vez y luego muere.
Causa raíz: El mapeo NAT expira rápido; el roaming cambia endpoint; falta keepalive.
Solución: Establece PersistentKeepalive. Confirma que el servidor permite roaming (la mayoría lo hace por defecto). Considera mover el servidor a una red con manejo UDP estable.
8) Windows dice conectado, pero el tráfico interno sale por la NIC equivocada
Síntoma: Existen rutas internas pero no se usan; la búsqueda de ruta muestra la interfaz Wi‑Fi.
Causa raíz: Rutas competidoras y métricas; a veces una ruta más amplia con mejor métrica gana en Windows.
Solución: Asegura que las rutas del túnel sean correctamente específicas y que las métricas se comporten. Evita empujar rutas amplias que solapen rutas corporativas existentes a menos que lo quieras realmente.
10) Tres micro-historias del mundo corporativo (cosas que reconocerás)
Historia A: el incidente causado por una suposición incorrecta
Una empresa mediana desplegó WireGuard para reemplazar una VPN envejecida. El piloto fue suave: ingenieros en portátiles Linux, redes domésticas limpias, una única subred interna. La configuración usó túnel dividido y un DNS interno. Parecía un éxito.
Luego el despliegue más amplio llegó a usuarios de Windows. Llegaron tickets de soporte: “VPN conectada, nombres internos rotos.” El equipo de red asumió que el DNS era “parte de la VPN”, porque así se comportaba el cliente antiguo. Los archivos de configuración de WireGuard no incluían una directiva DNS, porque nadie lo notó durante el piloto—los usuarios Linux ya tenían DNS dividido configurado localmente vía otras herramientas.
Operaciones intentó “arreglarlo” añadiendo entradas en hosts para unos cuantos servicios críticos. Eso compró un día y creó un sitio arqueológico: IPs obsoletas, comportamiento inconsistente y una dependencia creciente de lo que debió haber sido un problema de resolutor.
La solución real fue aburrida: definir el comportamiento DNS explícitamente en la config del cliente (y añadir dominios de búsqueda donde se necesitara), luego verificar por SO que la selección del resolver realmente cambiara cuando el túnel subiera. La lección no fue “WireGuard es complejo.” La lección fue “tus expectativas se heredaron de otro producto”.
Historia B: la optimización que salió mal
Un equipo de seguridad quiso reducir la complejidad de egress. Su idea: tunelizar todo el tráfico de los portátiles a través de un gateway central WireGuard y aplicar DLP y logging en un único punto. Es un instinto corporativo común: si la red es un lío, canalízala y llámalo gobernanza.
El despliegue “funcionó” en el sentido de que los handshakes ocurrieron y el tráfico fluyó. Lo que falló fue todo lo que había alrededor: aplicaciones sensibles a latencia, acceso a la red local y cualquier cosa que dependa de CDNs geográficamente cercanas. Las videollamadas empezaron a salir por un egress distante y las quejas internas se convirtieron en ejecutivos pidiendo “actualizaciones de estado” cada hora.
El equipo entonces “optimizó” subiendo el MTU para exprimir rendimiento. En algunos caminos ayudó; en otros creó agujeros negros de PMTU. Ahora tenían una falla doble: algunos usuarios con lentitud general, otros con páginas que se cargan a medias. El túnel no estaba caído; era peor: estaba inconsistente y roto.
El plan de recuperación fue dejar de fingir que una política de túnel sirve a todos. Pasaron a túnel dividido para la mayoría, mantuvieron túnel completo solo para roles de alto riesgo, estandarizaron un MTU conservador y documentaron lo que “túnel completo” rompe. No fue tan bonito ideológicamente. Fue sensato operacionalmente.
Historia C: la práctica aburrida pero correcta que salvó el día
Un equipo de servicios financieros usó WireGuard para acceso de proveedores a un entorno restringido. La configuración era poco glamorosa: un conjunto pequeño de peers, AllowedIPs estáticas, control de cambios estricto y un “ejercicio mensual de comprobar que sigue funcionando” donde alguien validaba handshake, rutas, DNS y uno o dos flujos de aplicación.
Un lunes, un proveedor reportó fallo total: sin acceso interno. El cliente mostraba “conectado”, pero el tráfico de la aplicación murió. El equipo no empezó por conjeturas. Siguieron su propia lista: estado de handshake, contadores, búsqueda de rutas, resolución DNS y luego comprobaciones de MTU. Resultó no ser ninguno de esos.
El problema real estaba aguas arriba: un cambio en el firewall bloqueó UDP entrante al puerto de WireGuard desde un ASN de un socio específico. Porque tenían un ejercicio rutinario, también tenían salidas base para “saludable”. La ausencia de cualquier handshake dejó el problema evidente y acortó la discusión con el equipo de firewall.
La solución fue un ajuste de política dirigido. Sin heroicidades. El valor no fue la herramienta; fue tener un hábito repetible de verificación y una definición compartida de “funciona”.
11) Listas de comprobación / plan paso a paso
Lista de comprobación de cliente (todos los SO)
- Obtén una config limpia desde el servidor (o générala): clave privada del cliente, IP del túnel del cliente, clave pública del servidor, endpoint y AllowedIPs.
- Decide la política del túnel: túnel dividido (recomendado para la mayoría) o túnel completo (solo cuando lo necesites y aceptes el radio de impacto).
- Establece DNS explícitamente: resolver interno y dominios de búsqueda si tu entorno usa nombres cortos.
- Añade keepalive para clientes en roaming:
PersistentKeepalive = 25. - Sube el túnel.
- Verifica handshake y contadores.
- Verifica el enrutamiento para una IP interna.
- Verifica la resolución DNS para un nombre interno.
- Prueba un camino de aplicación real (HTTPS a un endpoint interno, SSH, o lo que importe).
- Documenta el comportamiento esperado (qué subredes son alcanzables, si Internet debe ir por el túnel, qué DNS usar).
Paso a paso Windows (solo cliente)
- Importa la config en la app WireGuard.
- Confirma que
AllowedIPses lo que pretendes (dividido vs completo). - Asegura que
DNSesté establecido si necesitas resolución interna. - Activa el túnel.
- Si “conectado” pero inútil: comprueba la tabla de rutas y el comportamiento DNS antes de tocar claves.
Paso a paso macOS (solo cliente)
- Importa la config en la app WireGuard.
- Activa el túnel y confirma que sobrevive a suspensión/despertar.
- Si los nombres internos fallan: comprueba si el resolver del túnel se usa realmente y si necesitas dominios de búsqueda.
- Si falla solo en algunas redes: añade keepalive y considera reducir MTU.
Paso a paso Linux con wg-quick
- Coloca la config en
/etc/wireguard/wg0.conf, con permisos restringidos. - Sube el túnel.
- Verifica handshake y rutas.
- Verifica la integración DNS (systemd-resolved vs la realidad de resolv.conf).
cr0x@server:~$ sudo install -m 600 wg-client.conf /etc/wireguard/wg0.conf
cr0x@server:~$ sudo wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.8.0.2/32 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] ip -4 route add 10.8.0.0/24 dev wg0
[#] ip -4 route add 10.20.0.0/16 dev wg0
[#] resolvconf -a wg0 -m 0 -x
[#] iptables -I OUTPUT -o wg0 -j ACCEPT
Significado: wg-quick creó la interfaz, aplicó la config, añadió la dirección y rutas, e intentó ganchos DNS. (El método del gancho varía por distro.)
Decisión: Si no ves rutas añadidas, AllowedIPs en tu config puede estar vacío/incorrecto, o estás usando otro gestor. Arregla eso antes de escalar.
Broma #2: Si tu problema de VPN desaparece cuando reduces el MTU, felicidades—has descubierto que Internet aún funciona con vibras y cinta adhesiva.
12) Preguntas frecuentes
Q1: ¿Qué hace realmente “AllowedIPs”?
En el cliente, es la lista de selección de rutas: destinos que deben enviarse al túnel. En el receptor, también es selección de peer: qué peer “posee” un rango de origen/destino dado. Trátalo como intención de enrutamiento y como mapa de control de acceso.
Q2: ¿Debo usar 0.0.0.0/0 en clientes?
Sólo si quieres un túnel completo y estás listo para los efectos secundarios (acceso a red local, cambios de geolocalización/CDN, latencia, puntos de estrangulamiento corporativos). El túnel dividido es operacionalmente más calmado para la mayoría de organizaciones de ingeniería.
Q3: ¿Por qué veo handshakes pero ningún tráfico?
Porque un handshake solo prueba que los dos peers pueden intercambiar mensajes autenticados. No prueba que tu SO esté enroutando tráfico al túnel, ni que el servidor esté enroutando hacia adelante. Comprueba rutas, AllowedIPs y forwarding/firewall del servidor.
Q4: ¿Necesito PersistentKeepalive?
Para clientes en roaming detrás de NAT (la mayoría de portátiles fuera de la oficina), sí. Si estás en redes estables y siempre inicias tráfico, quizá no. En la práctica, 25 segundos es un seguro barato.
Q5: ¿Por qué el DNS sigue filtrando fuera del túnel?
Porque el DNS es su propio subsistema y tu SO puede preferir el resolver de la interfaz física a menos que establezcas DNS explícitamente y tu gestor de cliente lo aplique correctamente. Arregla la selección de DNS, no la criptografía de WireGuard.
Q6: ¿Cuál es el MTU correcto para WireGuard?
No hay un valor universal. 1420 es común. Si ves bloqueos, prueba 1380, luego 1360, luego 1280. El MTU “correcto” es el mayor que no genera agujeros negros en el peor camino de red.
Q7: ¿Puedo tener múltiples peers en una configuración de cliente?
Sí, pero sé disciplinado: no solapes AllowedIPs. Si necesitas conmutación por fallo, diseñala explícitamente; no confíes en solapamientos ambiguos esperando que WireGuard “escoja lo mejor”.
Q8: ¿Por qué funciona en Wi‑Fi pero falla en redes de hotel?
A los hoteles les encantan los portales cautivos, el throttling de UDP y los timeouts NAT raros. Completa la autenticación del portal primero, luego usa keepalive. Si UDP está bloqueado por completo, necesitarás otra red o un endpoint alternativo aprobado por política.
Q9: ¿Es WireGuard “más seguro” que VPNs antiguas?
Es seguro cuando se configura correctamente y se beneficia de un diseño más pequeño y auditable. Pero la seguridad es una propiedad del sistema: gestión de claves, hardening de endpoints y política de enrutamiento importan tanto como el protocolo.
Q10: ¿Cuál es la forma más simple de evitar cortes auto-infligidos?
Mantén las configs mínimas, estandariza plantillas, evita AllowedIPs solapados, configura DNS intencionalmente y valida con una lista reproducible. La complejidad no escala; los hábitos operacionales sí.
13) Próximos pasos prácticos
- Elige tu política de túnel: túnel dividido para la mayoría de usuarios; túnel completo solo para roles que realmente necesitan control centralizado de egress.
- Estandariza una plantilla de config cliente: incluye DNS y keepalive por defecto; mantén AllowedIPs explícitos y documentados.
- Crea una “prueba conocida buena”: un ping a una IP interna, una comprobación TCP, una consulta DNS interna. Usa las mismas tres pruebas en Windows/macOS/Linux.
- Adopta el guion de diagnóstico rápido: handshake → enrutamiento → accesibilidad por IP → DNS → MTU → forwarding en servidor.
- Escribe qué significa “funcionar”: subredes alcanzables, comportamiento DNS esperado y si Internet debe ir por el túnel. Esto evita el próximo incidente causado por suposiciones.
Si haces todo eso, WireGuard se convierte en lo que prometía: una herramienta pequeña y afilada que se queda fuera de tu camino—hasta que la necesitas, momento en el que se comporta de forma predecible. Predecible es el mejor cumplido que pueden recibir los sistemas de producción.