Divulgación de afiliados - Esta publicación contiene enlaces de afiliado de Contabo. Si contratas un VPS a través de ellos, ganamos una comisión sin coste adicional para ti. Cada comando y configuración a continuación está documentado desde fuentes oficiales de WireGuard y escrito para ser reproducible en tu propio VPS.
Escribes wg show, ves tu peer, y justo debajo está la línea que te arruina la tarde: latest handshake está vacía, o wg-quick te avisa handshake did not complete. Tu túnel está levantado sobre el papel pero no circula tráfico. La buena noticia: WireGuard falla por una lista corta y finita de razones, y aparecen en un orden predecible. Esta guía recorre ese orden de lo más común a lo más raro, para que dejes de adivinar y lo arregles en minutos.
WireGuard es silencioso por diseño - no envía nada hasta que hay datos que transportar, y nunca registra un amable «connection refused». Ese silencio es lo que hace que un handshake fallido parezca misterioso. Casi siempre es un problema de alcanzabilidad de red (firewall, puerto, NAT, enrutamiento), no de criptografía. Recorre la lista de arriba abajo y lo cazarás.
Primero, lee el estado real con wg show
Antes de cambiar nada, mira lo que WireGuard ya te dice. En ambos extremos:
sudo wg show
Estás leyendo tres cosas:
latest handshake- vacío o más viejo de ~2 minutos = túnel caído. Sano = en los últimos 120 segundos.transfer-0 B receivedsignifica que tus paquetes nunca volvieron. Enviado-pero-nada-recibido es la firma de un firewall o NAT de un solo sentido.endpoint- en el servidor, debe mostrar la IP:puerto pública actual del cliente en cuanto llega un paquete. Si nunca se rellena, la iniciación del cliente no te alcanzó.
Mantén este terminal abierto. Tras cada solución de abajo, vuelve a ejecutar wg show y vigila la línea latest handshake. Es tu única fuente de verdad - no el icono de conexión, no la app.
wg show latest-handshakes - la forma legible por máquina
Un wg show a secas imprime un latest handshake: 1 minute, 12 seconds ago pensado para el ojo humano. Cómodo de leer, inservible en un script. El manual wg(8) permite añadir un atributo para acotar la salida:
show { <interface> | all | interfaces } [public-key | private-key | listen-port |
fwmark | peers | preshared-keys | endpoints | allowed-ips |
latest-handshakes | persistent-keepalive | transfer | dump]
Así que la forma de referencia es:
sudo wg show wg0 latest-handshakes
Imprime una línea por peer: la clave pública en base64 del peer, un tabulador, y luego el último handshake en segundos desde la época Unix. Es literalmente lo que hace la herramienta: en wireguard-tools, src/show.c contiene printf("%s\t%llu\n", key(peer->public_key), peer->last_handshake_time.tv_sec);:
xTIBd0Kx3Hs9tPmVvQ4ZlLxYcE8nRr2A6WKsPqUvT1s= 1750684173
9QzrN7bLyF0mXaHcJdSoEuIgYkTvW3pB5nRfZ1AhQ0M= 0
Dos cosas que conviene saber sobre ese número:
- Un
0significa que ese peer nunca ha completado un handshake desde que subió la interfaz. No es una marca de tiempo caduca: es una marca ausente. Ese es justo el estado que estás depurando en esta página. - Es un tiempo de época absoluto, no una antigüedad. Réstalo de
date +%spara obtener los segundos transcurridos desde el último handshake:
now=$(date +%s)
sudo wg show wg0 latest-handshakes | while read -r peer ts; do
if [ "$ts" -eq 0 ]; then
echo "$peer nunca"
else
echo "$peer $((now - ts))s"
fi
done
Dos detalles que muerden al escribir el script. wg show all latest-handshakes antepone el nombre de la interfaz como primera columna separada por tabulador, así que tu read necesita una tercera variable. Y wg show wg0 dump te da la misma marca de tiempo junto al endpoint, los allowed-ips y los contadores de transferencia en una línea por peer separada por tabuladores: esa es la forma que hay que parsear si construyes un monitor de verdad y no un one-liner.
Cualquier valor por encima de ~180 segundos en un peer que debería estar activo significa que el túnel está caído. Ese es el umbral para alertar, y el resto de esta página es la lista ordenada de por qué se cayó.
Causa 1 - El puerto UDP está bloqueado (el culpable n.º 1)
WireGuard habla UDP en un único puerto - 51820 por defecto. Si ese puerto está filtrado en algún punto de la ruta, el paquete de iniciación muere y obtienes exactamente tu síntoma. Para entender ese valor por defecto, cómo cambiarlo y abrirlo correctamente, consulta qué puerto usa WireGuard y cómo abrirlo. Normalmente hay dos firewalls que comprobar, y la gente olvida el primero:
Firewall del proveedor cloud (el más olvidado). Contabo, Hetzner, OVH, AWS - todos tienen un firewall de red o grupo de seguridad delante de tu VPS. Una regla que permita UDP 51820 desde cualquier lugar debe existir ahí, separada del firewall del sistema. En la mayoría de imágenes de VPS de Contabo no hay firewall de proveedor por defecto (bien), pero si activaste uno, añade la regla UDP.
Firewall del sistema en el servidor. Comprueba y permite:
# ufw (Debian/Ubuntu)
sudo ufw allow 51820/udp
sudo ufw reload
# firewalld (Rocky/Alma/Fedora)
sudo firewall-cmd --add-port=51820/udp --permanent
sudo firewall-cmd --reload
Prueba rápida de que el puerto es alcanzable desde fuera - desde tu máquina cliente:
# envía una sonda UDP; "open|filtered" sin respuesta no es concluyente,
# pero "open" o un paquete devuelto confirma la alcanzabilidad
nc -u -z -v IP_DE_TU_SERVIDOR 51820
Prueba más limpia: ejecuta sudo tcpdump -n -i eth0 udp port 51820 en el servidor, luego conecta desde el cliente. Si ves paquetes entrantes, el puerto está abierto y pasas a la siguiente causa. Si no ves nada, el paquete se descarta antes de llegar a WireGuard - quédate en esta causa.
Causa 2 - Endpoint incorrecto en el cliente
El bloque [Peer] del cliente necesita la IP pública real del servidor (o su nombre DNS) y el ListenPort exacto:
[Peer]
PublicKey = CLAVE_PUBLICA_SERVIDOR
Endpoint = 203.0.113.10:51820
AllowedIPs = 0.0.0.0/0
Errores frecuentes que producen un handshake muerto:
- El Endpoint apunta a la IP LAN privada del servidor (
10.x/192.168.x) en lugar de la pública. - Una errata en el puerto, o el servidor escucha en realidad en otro
ListenPort. - La IP pública del servidor cambió (algunas reinstalaciones de VPS la reasignan). Confirma con
curl -4 ifconfig.coen el servidor, luego compara con el Endpoint del cliente.
El bloque del peer en el servidor no lleva línea Endpoint (el servidor la aprende cuando llega el paquete del cliente) - añadir una ahí es un error de copiar-pegar frecuente.
Causa 3 - AllowedIPs incorrectos
AllowedIPs es una tabla de enrutamiento criptográfica, no una lista de permisos, y un error rompe en silencio el tráfico de vuelta:
- En el servidor, el
AllowedIPsdel peer debe listar solo la dirección de túnel de ese cliente, p. ej.10.66.66.2/32. Si dos peers comparten un rango que se solapa, el servidor envía las respuestas al equivocado y el handshake «se completa» y luego muere. - En el cliente,
AllowedIPs = 0.0.0.0/0enruta todo por el túnel (VPN completa). Para split tunneling, lista solo las subredes que realmente enrutas - mira nuestra guía de enrutamiento en split-tunnel.
Un handshake que tiene éxito brevemente y luego se cala es la firma clásica de AllowedIPs que se solapan en el servidor. Haz único el rango de cada peer.
Causa 4 - Timeout NAT (funciona 2 minutos, luego muere)
Si tu cliente está detrás de NAT (router doméstico, 4G/5G, Wi-Fi de hotel) y el enlace queda inactivo, el router elimina el mapeo UDP. El servidor ya no tiene ruta de vuelta al cliente y el handshake expira en silencio. La solución vive en el peer que está detrás del NAT:
[Peer]
PublicKey = CLAVE_PUBLICA_SERVIDOR
Endpoint = 203.0.113.10:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
PersistentKeepalive = 25 envía un paquete diminuto cada 25 segundos, manteniendo abierto el mapeo NAT. Veinticinco segundos está por debajo de todo timeout NAT común. Añádelo en clientes nómadas y en cualquier peer detrás de un router restrictivo. El peer del servidor normalmente no lo necesita.
Causa 5 - El reenvío IP está apagado en el servidor
Si el handshake se completa pero no alcanzas Internet por el túnel, el servidor no reenvía paquetes entre la interfaz WireGuard y eth0. Actívalo:
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system
Confirma: sysctl net.ipv4.ip_forward debe devolver 1. Combínalo con la regla de masquerade en tu PostUp (las plantillas de configuración listas para usar incluyen estas líneas correctamente):
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
Causa 6 - Desfase de reloj
El handshake de WireGuard usa marcas de tiempo para bloquear ataques de repetición. Si el reloj del servidor se desvía más de un par de minutos - común en imágenes de VPS recién creadas o VM que se pausaron - los handshakes se rechazan por caducados. Corrige el reloj:
sudo timedatectl set-ntp true
timedatectl status # System clock synchronized: yes
Esta es traicionera porque todo lo demás parece perfecto. Si triple-comprobaste el puerto, las claves y el enrutamiento y sigues sin nada, revisa el reloj antes de desesperar.
Causa 7 - Claves no coincidentes (comprueba esto al final)
La gente va primero a las claves; compruébalas al final, porque un error de clave es más raro que las seis causas anteriores y produce el mismo síntoma. La regla es simple:
- La
[Peer] PublicKeydel servidor = la clave pública derivada de la PrivateKey del cliente. - La
[Peer] PublicKeydel cliente = la clave pública derivada de la PrivateKey del servidor.
Regenera y vuelve a derivar para asegurarte:
# en cada máquina, deriva la clave pública de su propia clave privada
echo "CLAVE_PRIVADA_DE_ESTE_HOST" | wg pubkey
Compara esa salida con la PublicKey que el otro lado tiene para ti. Una sola clave invertida o truncada rompe el handshake por completo. De paso, una PresharedKey (si se usa) debe ser idéntica en ambos peers - una diferencia ahí también mata el handshake.
Causa 8 - El MTU rompe el túnel justo tras el handshake
En rigor, el MTU rara vez bloquea el handshake (sus paquetes son pequeños). Pero suele romper cosas en cuanto fluye tráfico real: el handshake se completa, el ping funciona, luego las páginas web se cuelgan para siempre. Eso es fragmentación. Baja el MTU del cliente:
[Interface]
MTU = 1380
Encuentra el valor correcto con un ping «do-not-fragment» a la IP de túnel del servidor, reduciéndolo hasta que pase:
ping -M do -s 1372 10.66.66.1
1420 sirve para la mayoría de enlaces de fibra; 1380 es un valor por defecto seguro; PPPoE y algunos operadores móviles necesitan 1280. Nuestra guía de plantillas de configuración explica el ajuste del MTU por tipo de enlace. Si el túnel conecta pero se cuelga con transferencias grandes, la guía dedicada arreglar el MTU de WireGuard muestra cómo medir el valor exacto con un ping sin fragmentación y ajustarlo por tipo de enlace.
El orden de diagnóstico en 60 segundos
Cuando un handshake falla, ejecuta esta secuencia exacta y detente en lo primero que esté mal:
wg showen ambos lados - ¿hay algúnlatest handshake, algún bytereceived?tcpdump udp port 51820en el servidor mientras el cliente conecta - ¿llegan paquetes?- Si no llega ningún paquete → firewall / puerto / Endpoint (causas 1-2).
- Si llegan paquetes pero ninguna respuesta vuelve →
AllowedIPsdel servidor, NAT, ruta de vuelta (causas 3-4). - Si el handshake se completa pero no hay Internet →
ip_forward+ masquerade (causa 5). - Si todo parece correcto y aún nada → desfase de reloj, luego claves, luego MTU (causas 6-8).
Este orden sigue la frecuencia real de cada causa en instalaciones auto-alojadas reales - recórrelo de arriba abajo y no perderás tiempo.
Constrúyelo bien desde el principio
La mayoría de handshakes fallidos vienen de coser a mano una config con tres tutoriales contradictorios. Partir de una base sana en un VPS limpio elimina el 90 % de las sorpresas. Un Contabo Cloud VPS 10 a 5,50 €/mes te da una IPv4 pública, root completo, y ningún firewall de proveedor que combatir - exactamente las condiciones donde WireGuard «simplemente funciona». Sigue la configuración Contabo + WireGuard paso a paso y pega una config verificada de la guía de plantillas, y el handshake se completa al primer intento.
Para profundizar
- PersistentKeepalive: qué hace de verdad el ajuste de 25 segundos
- WireGuard multihop: encadenar dos servidores autoalojados
- WireGuard detrás de CGNAT: por qué el handshake nunca llega
- WireGuard en Windows: configuración paso a paso
- WireGuard en iPhone y iPad: la configuración completa en iOS
- Auto-alojar VPN en Contabo: guía completa de WireGuard 2026
- Plantillas de configuración WireGuard listas para usar 2026
- Fugas DNS en WireGuard: detectar, diagnosticar, eliminar
- Kill-switch WireGuard en Linux: iptables + systemd
- VPN en split-tunnel con tablas de enrutamiento
- Glosario de VPN auto-alojada - AllowedIPs, MTU, NAT explicados
Fuentes y referencias:
- Whitepaper de WireGuard - Jason A. Donenfeld
- Quickstart de WireGuard y docs de wg-quick
- Páginas de manual wg(8) y wg-quick(8)
- Arch Wiki - solución de problemas de WireGuard
Publicado el 2026-06-23. Orden de diagnóstico validado en servidores Debian 12 y Ubuntu 24.04 con un Contabo Cloud VPS 10, frente a clientes WireGuard en Linux, Windows 11, macOS y Android. Tus condiciones de enlace pueden variar - confirma siempre con wg show y tcpdump antes de dar por definitiva una solución.
Recordatorio: ejecutar WireGuard y auto-alojar una VPN es legal en la UE, EE. UU., Canadá y la mayoría de países democráticos. VPNSmith publica este contenido con fines educativos.
También conviene auditar donde residen las claves: un aviso de CISA de julio de 2026 cubre un fallo de RouterOS que permite leer una clave privada WireGuard estática desde el propio router. Consulta por qué desactivar la API no lo deshace.
★ Datacenter Núremberg GDPR · ✓ IPv4 dedicada incluida · 200+ Mbps garantizados
Aloja tu VPN en tu propio VPS → ContaboAcceso root completo · IPv4 pública · elige tu región→

