WireGuard hub-and-spoke para 3 oficinas a través de una puerta de enlace central

¿Te fue útil?

Tus tres oficinas no pueden “simplemente conectarse por VPN”. Una está detrás de doble NAT, otra tiene un router del ISP “útil” que no puedes tocar, y la tercera es la que tiene la sala de servidores que también guarda las decoraciones de Navidad. Aun así, todo el mundo espera servicios compartidos, VoIP estable y un archivo compartido que no parezca estar alojado en una tostadora.

El modelo hub-and-spoke con WireGuard es cómo obtienes un enrutamiento predecible sin convertir tu red en arte interpretativo. Pero solo se mantiene predecible si respetas cómo funciona WireGuard en realidad: es un túnel UDP seguro con una tabla de enrutamiento adjunta. Si lo tratas como una “casilla de verificación VPN” mágica, te permitirá enrutar paquetes incorrectamente hasta el día en que te llamen.

Elige la topología y sé sincero sobre las restricciones

Hub-and-spoke significa: cada oficina (spoke) construye un túnel WireGuard solo hacia la puerta de enlace central (hub). El hub enruta el tráfico entre spokes. Los spokes nunca necesitan alcanzarse directamente, que es todo el punto: menos túneles, gestión de claves más sencilla, menos agujeros en el firewall y menos sorpresas.

No es el único modelo. Existe la malla completa, pero escala como un chat de grupo donde todos pueden responder a todos. Para tres oficinas podrías hacer malla, pero seguirás queriendo un punto de control central para políticas, registro y “quién puede hablar con qué”. Hub-and-spoke gana en la realidad corporativa: control centralizado del egress, observabilidad centralizada y solo un lugar para aplicar “no, las impresoras no necesitan hablar con finanzas”.

Qué debe ser el hub

  • Un endpoint público estable (IP estática o DNS estable, pero trata las fallas de DNS como reales).
  • Un router con reenvío IP de Linux, filtrado y preferiblemente nftables o iptables que controles.
  • Una máquina con higiene operacional: sincronización de tiempo, logs, copias de seguridad, control de cambios y un responsable claro.

Qué deben ser los spokes

  • Un dispositivo capaz de ejecutar WireGuard y enrutar una LAN (máquina Linux, distro de router soportada o un pequeño appliance).
  • Consistencia: una interfaz para WAN, una para LAN, una para WireGuard. No te pongas creativo.
  • Subredes LAN conocidas (sin solapamientos). Los solapamientos son cómo las “soluciones temporales” se convierten en outages permanentes.

Decide temprano si el hub también será el “salto a Internet” para los spokes (los spokes enrutan 0.0.0.0/0 a través del hub) o si el hub solo enruta tráfico entre oficinas. Para tres oficinas, solo inter-oficina suele ser el primer paso; el breakout central puede llegar después cuando estés listo para asumir la carga de soporte.

Broma #1: Una VPN hub-and-spoke es como un organigrama corporativo: todos reportan al medio, y el medio pasa la vida enrutableando quejas.

Hechos interesantes (y por qué importan operacionalmente)

  • WireGuard es intencionalmente minimalista. No negocia algoritmos ni soporta un zoológico de cifrados; usa un conjunto moderno y pequeño para reducir la mala configuración y la superficie de ataque.
  • Usa el framework de protocolo Noise. No es trivia; explica por qué los handshakes son rápidos y por qué el estado es ligero comparado con pilas VPN antiguas.
  • WireGuard corre en el kernel en Linux. Por eso el rendimiento suele ser excelente y por eso aún debes preocuparte por actualizaciones de kernel y regresiones como con cualquier otro cambio en el datapath.
  • “AllowedIPs” es tanto ACL como enrutamiento. Muchos outages vienen de olvidar que este campo determina qué rutas se instalan y qué tráfico se acepta de un peer.
  • Roaming es un comportamiento de primera clase. Los peers pueden cambiar IP/puerto; WireGuard aprende el nuevo endpoint tras tráfico autenticado, lo cual es perfecto para oficinas detrás de NAT—hasta que faltan keepalives.
  • Es UDP. Lo que significa que puede pasar por muchas redes, pero también que los firewalls stateful y los timeouts de NAT se convierten en tu problema.
  • No tiene “autenticación de usuario” incorporada. Son claves máquina a máquina. Si alguien quiere acceso VPN por usuario, hazlo en otra capa (o construye una capa separada).
  • Es joven comparado con IPsec. IPsec tiene décadas de cicatrices e incompatibilidades. WireGuard tiene menos perillas, menos trampas y menos reuniones “pero el proveedor dijo…”.
  • Las configuraciones pequeñas son una ventaja. Cuando puedes imprimir toda la configuración VPN en una sola página, la depuración en on-call de repente es soportable.

Una idea para operaciones que se puede parafrasear viene de Werner Vogels (CTO de Amazon): paráfrasis: todo falla eventualmente; diseña para que la falla sea rutinaria y la recuperación aburrida. Esa es la mentalidad para VPNs también: asume que los NAT se reinician, los enlaces fluctúan y alguien edita el archivo equivocado a las 2 a.m.

Plan de direcciones y modelo de enrutamiento

Empieza por el plan de direcciones. Si lo omites, lo pagarás más tarde, con intereses.

Plan de red ejemplo (tres oficinas + hub)

  • LAN Oficina A: 10.10.10.0/24
  • LAN Oficina B: 10.10.20.0/24
  • LAN Oficina C: 10.10.30.0/24
  • Red de tránsito WireGuard: 10.99.0.0/24 (solo para las IPs de la interfaz del túnel)
  • Hub wg0: 10.99.0.1/24
  • Spoke A wg0: 10.99.0.11/32
  • Spoke B wg0: 10.99.0.12/32
  • Spoke C wg0: 10.99.0.13/32

Usa direcciones /32 para peers en la interfaz del túnel y mantén la red de tránsito separada de las LANs de oficina. Quieres que la red del túnel sea su propio universo. Además: no reutilices rangos RFC1918 que ya usas en oficinas. Los subnets privados solapados son el equivalente corporativo de “vamos improvisando”.

Intención de enrutamiento

Tu intención en hub-and-spoke es simple:

  • Los spokes saben: “para alcanzar las LANs de otras oficinas, envía tráfico a wg0.”
  • El hub sabe: “para alcanzar cada LAN de oficina, envía tráfico por wg0 al peer correcto.”
  • Los clientes LAN en cada oficina saben: “para subredes de otras oficinas, la puerta de enlace por defecto es el router de la oficina.”

Eso es todo. No NAT entre oficinas salvo que tengas subredes solapadas que no puedas arreglar (y si no puedes arreglarlo, reserva tiempo para hacerlo de todos modos). NAT oculta problemas y los hace más difíciles de diagnosticar porque borra la identidad de origen—exactamente lo que quieres preservar para auditoría y políticas de seguridad.

Configuración del hub: la puerta de enlace central

Asume que el hub es una VM Linux en un datacenter o cloud con una IP pública. Nómbrala wg-hub-1. Tiene:

  • eth0 = interfaz pública/WAN
  • wg0 = interfaz WireGuard

Instalar WireGuard

En distribuciones modernas es instalar un paquete y un módulo de kernel que ya está allí. Manténlo sencillo.

Generar claves

Haz esto en el hub y en cada spoke; nunca copies claves privadas por apps de chat o comentarios de tickets. Trátalas como contraseñas root.

Hub: /etc/wireguard/wg0.conf

Este ejemplo enruta tres subredes de oficina. El hub será el único endpoint configurado; los spokes apuntarán a él.

cr0x@server:~$ sudo sed -n '1,200p' /etc/wireguard/wg0.conf
[Interface]
Address = 10.99.0.1/24
ListenPort = 51820
PrivateKey = HUB_PRIVATE_KEY_REDACTED
SaveConfig = false

# Enable NAT only if you want spokes to reach the hub's WAN or internet via hub.
# For pure site-to-site, you typically do not NAT between offices.
PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = nft add table inet wg; nft 'add chain inet wg forward { type filter hook forward priority 0; policy drop; }'
PostUp = nft add rule inet wg forward iif "wg0" oif "wg0" accept
PostUp = nft add rule inet wg forward iif "wg0" oif "eth0" accept
PostUp = nft add rule inet wg forward iif "eth0" oif "wg0" ct state established,related accept
PostDown = nft delete table inet wg

[Peer]
PublicKey = SPOKE_A_PUBLIC_KEY_REDACTED
AllowedIPs = 10.99.0.11/32, 10.10.10.0/24
PersistentKeepalive = 25

[Peer]
PublicKey = SPOKE_B_PUBLIC_KEY_REDACTED
AllowedIPs = 10.99.0.12/32, 10.10.20.0/24
PersistentKeepalive = 25

[Peer]
PublicKey = SPOKE_C_PUBLIC_KEY_REDACTED
AllowedIPs = 10.99.0.13/32, 10.10.30.0/24
PersistentKeepalive = 25

Notas que no debes omitir:

  • AllowedIPs en el hub es efectivamente la tabla de enrutamiento del hub para los spokes. Si está mal, el hub entenazará o entregará mal.
  • PersistentKeepalive en el hub no siempre es necesario, pero ayuda a mantener vivas las asignaciones NAT en el lado remoto. En la realidad de sucursales, las asignaciones NAT mueren cuando no las miras.
  • SaveConfig=false evita que los cambios en tiempo de ejecución se escriban. Esto evita “alguien usó wg set y ahora el archivo miente”.
  • Las reglas nftables anteriores son intencionalmente algo estrictas. Muchas configuraciones “aceptan todo forward”, lo cual está bien hasta que la VPN se convierte en un tránsito no supervisado para todo.

Habilitar y arrancar

Usa unidades systemd para coherencia. Quieres recuperación en el arranque sin scripts personalizados.

Configuración del spoke: el router de cada oficina

Cada oficina tiene un router/firewall (Linux) con:

  • eth0 = uplink WAN hacia el router/modem del ISP
  • eth1 = LAN hacia el switch de la oficina
  • wg0 = túnel WireGuard hacia el hub

Spoke A: /etc/wireguard/wg0.conf

cr0x@server:~$ sudo sed -n '1,200p' /etc/wireguard/wg0.conf
[Interface]
Address = 10.99.0.11/32
PrivateKey = SPOKE_A_PRIVATE_KEY_REDACTED
ListenPort = 51820
SaveConfig = false

PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = nft add table inet wg; nft 'add chain inet wg forward { type filter hook forward priority 0; policy drop; }'
PostUp = nft add rule inet wg forward iif "eth1" oif "wg0" accept
PostUp = nft add rule inet wg forward iif "wg0" oif "eth1" ct state established,related accept
PostUp = nft add rule inet wg forward iif "wg0" oif "wg0" accept
PostDown = nft delete table inet wg

[Peer]
PublicKey = HUB_PUBLIC_KEY_REDACTED
Endpoint = 203.0.113.10:51820
AllowedIPs = 10.99.0.1/32, 10.10.20.0/24, 10.10.30.0/24
PersistentKeepalive = 25

Spoke B y C son idénticos excepto por su Address y las LANs de oficina en AllowedIPs que deben incluir “las otras oficinas”, no su propia LAN. Puedes incluir también la dirección wg del hub para hacer ping al hub.

Dos reglas para los spokes:

  1. No pongas 0.0.0.0/0 en AllowedIPs a menos que intencionalmente fuerces todo el tráfico por el hub (breakout central). No lo “pruebes” en producción y lo olvides.
  2. No NATees el tráfico inter-oficinas. Si necesitas NAT para que algo “funcione”, probablemente estás enroutando mal.

Enrutamiento, NAT y reglas de firewall que no te sorprenderán

WireGuard no hace enrutamiento por ti; solo cifra el tráfico que enrutas dentro de él. Linux enrutará basado en:

  • direcciones de interfaz (rutas conectadas),
  • rutas instaladas por wg-quick desde AllowedIPs, y/o
  • tus rutas estáticas explícitas.

Prefiere enrutamiento explícito sobre ingeniosidades

Cuando levantas wg0 con wg-quick, típicamente añadirá rutas para AllowedIPs. Eso es conveniente, pero debes entender exactamente qué rutas existen y por qué. La conveniencia se vuelve misterio durante un outage.

Reenvío: las tres puertas

Para que los paquetes atraviesen de la LAN de la Oficina A a la LAN de la Oficina B vía el hub, tres cosas deben ser verdad:

  1. Los clientes de la Oficina A envían tráfico a su router local (gateway por defecto).
  2. El router Spoke A reenvía a wg0 y cifra hacia el hub.
  3. El hub reenvía desde wg0 a wg0 (al otro peer) basado en enrutamiento.

Cada dispositivo necesita:

  • Reenvío IP habilitado (net.ipv4.ip_forward=1)
  • Reglas de firewall que permitan la ruta de reenvío
  • Rutas instaladas para las LANs remotas

Cuándo hacer NAT

Solo hay algunas razones para NAT en este diseño:

  • Breakout central a Internet. Los spokes enrutan 0.0.0.0/0 vía el hub, el hub hace NAT hacia la interfaz pública.
  • Subredes solapadas que no puedes renumerar. Deberías renumerar de todos modos, pero a veces tienes una fusión, un appliance de vendor o un sistema de automatización del edificio que se niega a moverse.
  • Migración temporal. Usa NAT como andamiaje con fecha de expiración, no como arquitectura.

Si haces NAT entre oficinas por defecto, eventualmente romperás algo que depende de la IP de origen (ACLs, logs, reglas de seguridad SMB, reglas SBC de VoIP). Peor: perderás la capacidad de responder “quién accedió a este sistema?” sin jugar a detective de traducción de paquetes.

MTU, fragmentación y por qué “a mí me funciona” no es una métrica

Los problemas de MTU son el problema más común de “se conecta pero algunas cosas se cuelgan” en WireGuard sitio a sitio. El túnel añade overhead. Si llevas paquetes demasiado grandes para algún segmento del camino, se fragmentarán o descartarán, y obtendrás fallos que parecen bugs de aplicaciones.

WireGuard encapsula IP en UDP. El overhead típico es alrededor de 60 bytes (varía). Si tu MTU WAN es 1500, un MTU seguro para WireGuard suele ser 1420. Muchas distros ponen 1420 por defecto en interfaces wg por exactamente esta razón.

Pero no puedes asumir 1500 en WAN. Enlaces PPPoE suelen tener 1492. Algunas conexiones LTE/5G se comportan de forma distinta. Algunos ISPs hacen cosas raras con ICMP, lo que rompe PMTU discovery y hace que todo “funcione más o menos”.

Broma #2: Los bugs de MTU son la versión adulta de pisar un Lego: todo duele y no puedes probar inmediatamente qué lo causó.

Mi postura en producción sobre MTU

  • Establece MTU = 1420 en wg0 a menos que tengas una razón medida para hacerlo diferente.
  • Si ves cuelgues en transferencias grandes o ciertos sitios/servicios, prueba PMTU agresivamente y ajusta.
  • No deshabilites ICMP globalmente. No estás “endureciendo”, te estás vendando los ojos.

Observabilidad: qué registrar, qué graficar

Una VPN que “funciona” pero no puede ser depurada es un futuro outage que ya estás pagando. Para hub-and-spoke, instrumenta el hub como si fuera infraestructura de enrutamiento de producción—porque lo es.

Qué vigilar en el hub

  • Timestamps de handshake por peer. Un peer que no ha hecho handshake en horas está ocioso (bien) o muerto (no bien). Correlaciona con contadores de tráfico.
  • Contadores RX/TX de bytes. Caídas súbitas a cero en horas laborales significan que alguien rompió enrutamiento o firewall.
  • CPU softirq y drops de NIC. Raro con tres oficinas, pero si la VM del hub es pequeña u oversubscrita, lo verás.
  • Contadores del firewall. Si no cuentas drops, discutirás contigo mismo a las 3 a.m.
  • Deriva del tiempo del sistema. La criptografía y los handshakes sensibles al tiempo no disfrutan los viajes temporales.

Logs: sé selectivo

WireGuard en sí es silencioso. Eso es bueno. No intentes “loggear cada paquete”. En su lugar:

  • registra eventos up/down de la interfaz,
  • registra drops del firewall a tasa muestreada o inspecciona contadores por regla,
  • mantén historial de cambios de configs y actualizaciones de kernel.

Tareas prácticas: comandos, salidas y decisiones

Estas son tareas reales que ejecutarás en producción. Cada una incluye un comando, salida de ejemplo, qué significa y qué decisión tomar a continuación. Úsalas en hub y en spokes. La consistencia gana outages.

Tarea 1: Verificar el estado de la interfaz WireGuard

cr0x@server:~$ sudo wg show
interface: wg0
  public key: 3kN9...REDACTED
  listening port: 51820

peer: zZp2...REDACTED
  endpoint: 198.51.100.24:60433
  allowed ips: 10.99.0.11/32, 10.10.10.0/24
  latest handshake: 1 minute, 12 seconds ago
  transfer: 1.42 GiB received, 1.87 GiB sent
  persistent keepalive: every 25 seconds

Significado: El túnel está lo bastante arriba para handshakes; el endpoint muestra dónde está actualmente el peer (puerto NATeado es esperado). Los contadores de transferencia prueban tráfico real.

Decisión: Si latest handshake es “never” o está muy antiguo mientras los usuarios se quejan, pasa inmediatamente a comprobar reachability de firewall/NAT y rutas.

Tarea 2: Levantar la interfaz y confirmar estado systemd

cr0x@server:~$ sudo systemctl status wg-quick@wg0
● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
     Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; preset: enabled)
     Active: active (exited) since Sat 2025-12-27 10:11:02 UTC; 7min ago
       Docs: man:wg-quick(8)
             man:wg(8)
    Process: 1724 ExecStart=/usr/bin/wg-quick up wg0 (code=exited, status=0/SUCCESS)

Significado: wg-quick es one-shot; “active (exited)” es normal. No falló durante la creación de la interfaz.

Decisión: Si el estado es failed, lee el journal por errores de sintaxis o módulo de kernel faltante antes de tocar más la red.

Tarea 3: Inspeccionar logs de wg-quick por errores

cr0x@server:~$ sudo journalctl -u wg-quick@wg0 -n 50 --no-pager
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] ip link add wg0 type wireguard
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] wg setconf wg0 /dev/fd/63
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] ip -4 address add 10.99.0.1/24 dev wg0
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] ip link set mtu 1420 up dev wg0
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] sysctl -w net.ipv4.ip_forward=1

Significado: Interfaz creada, MTU seteada, forwarding habilitado. Si no ves que se haya seteado MTU, podrías estar dependiendo de defaults—está bien, pero consiéntelo.

Decisión: Si los logs muestran “RTNETLINK answers: File exists” o fallos de nft, tienes estado residual. Limpia y reinicia limpio.

Tarea 4: Confirmar que forwarding está realmente habilitado

cr0x@server:~$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

Significado: El kernel reenviará paquetes IPv4. Sin esto, tu VPN se vuelve un caro juguete de ping.

Decisión: Si es 0, habilítalo de forma persistente en /etc/sysctl.d/ y deja de pretender que se “mantendrá seteado”.

Tarea 5: Validar que existan rutas a subredes de oficina en el hub

cr0x@server:~$ ip route show | egrep '10\.10\.(10|20|30)\.0/24|10\.99\.0\.0/24'
10.10.10.0/24 dev wg0 scope link
10.10.20.0/24 dev wg0 scope link
10.10.30.0/24 dev wg0 scope link
10.99.0.0/24 dev wg0 proto kernel scope link src 10.99.0.1

Significado: El hub cree que todas las LANs de oficina son alcanzables vía wg0. Eso es necesario para el enrutamiento del hub.

Decisión: Si faltan rutas, tus AllowedIPs en los peers del hub están mal o wg-quick no instaló rutas (customizaciones de policy routing pueden hacer eso).

Tarea 6: Validar rutas en un spoke

cr0x@server:~$ ip route show | egrep '10\.10\.(20|30)\.0/24|wg0'
10.10.20.0/24 dev wg0 scope link
10.10.30.0/24 dev wg0 scope link
10.99.0.1 dev wg0 scope link

Significado: El Spoke A enviará tráfico para las oficinas B y C dentro del túnel.

Decisión: Si las subredes de oficina están enroutadas en otro lado (o no están), corrige AllowedIPs o añade rutas explícitas. No lo “arregles” con NAT.

Tarea 7: Confirmar que el hub puede alcanzar la IP wg de cada spoke

cr0x@server:~$ ping -c 3 10.99.0.11
PING 10.99.0.11 (10.99.0.11) 56(84) bytes of data.
64 bytes from 10.99.0.11: icmp_seq=1 ttl=64 time=18.6 ms
64 bytes from 10.99.0.11: icmp_seq=2 ttl=64 time=18.4 ms
64 bytes from 10.99.0.11: icmp_seq=3 ttl=64 time=18.9 ms

--- 10.99.0.11 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms

Significado: Conectividad encriptada al router spoke existe.

Decisión: Si esto falla pero el handshake existe, comprueba el firewall en el spoke (INPUT/FORWARD) para ICMP, o verifica que el spoke asignó la IP wg que esperabas.

Tarea 8: Trazar el enrutamiento desde el hub hasta un host en la Oficina B

cr0x@server:~$ traceroute -n 10.10.20.50
traceroute to 10.10.20.50 (10.10.20.50), 30 hops max, 60 byte packets
 1  10.99.0.12  20.112 ms  20.098 ms  20.085 ms
 2  10.10.20.50  21.004 ms  20.992 ms  20.980 ms

Significado: El hub está enroutando al spoke correcto (10.99.0.12) y luego al host destino.

Decisión: Si el hop 1 es incorrecto, tienes un solapamiento de AllowedIPs en el hub (dos peers reclamando la misma subred) o rutas faltantes.

Tarea 9: Comprobar AllowedIPs solapados en el hub

cr0x@server:~$ sudo wg show wg0 allowed-ips
zZp2...REDACTED	10.99.0.11/32 10.10.10.0/24
aPq8...REDACTED	10.99.0.12/32 10.10.20.0/24
mK1r...REDACTED	10.99.0.13/32 10.10.30.0/24

Significado: Cada subred de oficina está reclamada por un único peer. Eso es lo que quieres.

Decisión: Si dos peers listan la misma subred, arréglalo inmediatamente; el enrutamiento será no determinista y recibirás tickets de “a veces funciona”.

Tarea 10: Validar accesibilidad UDP (puerto abierto) en el hub

cr0x@server:~$ sudo ss -ulnp | grep 51820
UNCONN 0      0            0.0.0.0:51820      0.0.0.0:*    users:(("wireguard",pid=1724,fd=3))

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

Decisión: Si nada está escuchando, tu interfaz no está arriba, o cambiaste puertos y no reiniciaste el servicio.

Tarea 11: Inspeccionar reglas y contadores nftables

cr0x@server:~$ sudo nft list table inet wg
table inet wg {
	chain forward {
		type filter hook forward priority filter; policy drop;
		iifname "wg0" oifname "wg0" counter packets 18392 bytes 24581231 accept
		iifname "wg0" oifname "eth0" counter packets 0 bytes 0 accept
		iifname "eth0" oifname "wg0" ct state established,related counter packets 2901 bytes 501832 accept
	}
}

Significado: La política de forward es drop por defecto; se permiten rutas específicas. Los contadores muestran reenvío inter-oficina real (wg0→wg0).

Decisión: Si los contadores en wg0→wg0 se quedan en cero mientras los usuarios se quejan, el hub no está reenrutando—o las rutas están mal o el tráfico nunca llega al hub.

Tarea 12: Capturar tráfico para probar si los paquetes llegan

cr0x@server:~$ sudo tcpdump -ni wg0 host 10.10.20.50 -c 5
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
10:22:18.114331 IP 10.10.10.25.53422 > 10.10.20.50.445: Flags [S], seq 13922311, win 64240, options [mss 1360,sackOK,TS val 2911221 ecr 0,nop,wscale 7], length 0
10:22:19.120482 IP 10.10.10.25.53422 > 10.10.20.50.445: Flags [S], seq 13922311, win 64240, options [mss 1360,sackOK,TS val 2912227 ecr 0,nop,wscale 7], length 0

Significado: El tráfico está llegando al wg0 del hub desde la Oficina A destinado al host de la Oficina B. Si no hay SYN-ACK, o el host destino no responde o el tráfico no se está reenrutando correctamente hacia adelante.

Decisión: Si ves paquetes en el hub pero no llegan a la oficina lejana, comprueba el enrutamiento del hub hacia el peer correcto, luego verifica el reenvío del spoke B y el firewall de la LAN B.

Tarea 13: Comprobar comportamiento MTU con pings “do not fragment”

cr0x@server:~$ ping -M do -s 1372 -c 3 10.10.20.50
PING 10.10.20.50 (10.10.20.50) 1372(1400) bytes of data.
1372 bytes from 10.10.20.50: icmp_seq=1 ttl=63 time=22.1 ms
1372 bytes from 10.10.20.50: icmp_seq=2 ttl=63 time=22.0 ms
1372 bytes from 10.10.20.50: icmp_seq=3 ttl=63 time=21.8 ms

--- 10.10.20.50 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms

Significado: Un paquete de 1400 bytes llega de extremo a extremo sin fragmentación. Eso es una buena señal para el tamaño típico de MSS en TCP.

Decisión: Si esto falla con “Frag needed”, reduce el MTU de wg (p. ej., 1380) y vuelve a probar, o investiga restricciones de MTU en WAN.

Tarea 14: Verificar que policy routing no esté secuestrando tráfico silenciosamente

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

Significado: Reglas por defecto solamente. Eso es bueno a menos que hayas añadido routing complejo intencionalmente.

Decisión: Si ves reglas extra, confirma que son necesarias. El policy routing es poderoso y también una forma fiable de confundir al Futuro Tú.

Tarea 15: Confirmar que reverse path filtering no esté descartando tráfico asimétrico

cr0x@server:~$ sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.wg0.rp_filter
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.wg0.rp_filter = 0

Significado: rp_filter está apagado aquí, evitando drops cuando la ruta de retorno difiere de la interfaz esperada. En routers, rp_filter estricto suele romper el reenvío VPN.

Decisión: Si está 1 o 2 y ves tráfico unidireccional, ponlo a 0 para wg0 (o ajústalo con cuidado) y documenta el motivo.

Guía rápida de diagnóstico

Este es el orden que encuentra el cuello de botella rápidamente, sin perderse en la fantasía de “quizá es DNS”. Trabaja desde el centro hacia afuera, porque el hub es tu punto de estrangulamiento y tu mejor punto de vista.

Primero: ¿está vivo el túnel?

  1. En el hub: wg show — verifica la edad del handshake y los contadores de transferencia por peer.
  2. En el hub: ss -ulnp | grep 51820 — confirma que está escuchando.
  3. En el spoke: wg show — confirma que ve al hub, que los handshakes se actualizan y que AllowedIPs coincide con la intención.

Si el handshake es “never”: suele ser reachability del endpoint (UDP bloqueado), claves erróneas, puerto equivocado, o spoke detrás de NAT sin keepalive y la asignación NAT expiró.

Segundo: ¿el enrutamiento es correcto?

  1. En hub y spoke: ip route show — confirma que las subredes remotas apuntan a wg0.
  2. En hub: wg show wg0 allowed-ips — confirma que no hay reclamaciones solapadas.
  3. Ejecuta un traceroute desde el hub a un host LAN remoto — confirma que el primer hop es el spoke correcto.

Si las rutas existen pero los traceroutes muestran hops incorrectos: tienes AllowedIPs en conflicto o policy routing.

Tercero: ¿el reenvío/firewall está bloqueando el tránsito?

  1. Comprueba sysctl net.ipv4.ip_forward en hub y spokes.
  2. Inspecciona reglas nftables/iptables y contadores en cada nodo.
  3. Ejecuta tcpdump en wg0 del hub y en wg0 del spoke para ver dónde se detienen los paquetes.

Si los paquetes llegan al hub pero no al spoke lejano: desajuste de enrutamiento/AllowedIPs en el hub o drop del firewall del hub. Si los paquetes llegan al spoke lejano pero no a la LAN, es reenvío del spoke o firewall de la LAN.

Cuarto: si “funciona para cosas pequeñas”

  1. Prueba MTU con ping -M do en varios tamaños.
  2. Revisa el clamping de MSS TCP (si lo usas) y confirma que coincide con el MTU efectivo.
  3. Busca ICMP bloqueado a lo largo del camino (PMTU lo necesita).

Quinto: quejas de rendimiento (comparticiones lentas, llamadas entrecortadas)

  1. Revisa CPU del hub y drops de NIC: sar, ethtool -S, ss -s.
  2. Mira RTT y pérdida (pings simples están bien; también revisa jitter).
  3. Confirma que no existe un breakout central accidental para tráfico pesado.

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

1) “El handshake nunca ocurre”

Síntomas: wg show muestra latest handshake: (none). Los contadores de tráfico no incrementan.

Causa raíz: UDP/51820 bloqueado inbound al hub, endpoint/puerto del hub equivocado, clave pública incorrecta, o spoke detrás de NAT sin keepalive y la asignación NAT expiró.

Solución: Verifica ss -ulnp en el hub, permite UDP en el firewall cloud, confirma IP/puerto público del hub, revisa claves y pon PersistentKeepalive=25 en los spokes (y opcionalmente en las entradas de peers del hub).

2) “Hace ping, pero SMB/RDP/VoIP es inestable o se cuelga”

Síntomas: Pings pequeños funcionan; transferencias grandes se estancan; algunas aplicaciones conectan y luego se congelan.

Causa raíz: PMTU/MTU en agujero negro; ICMP bloqueado; MTU del túnel demasiado alto para el camino WAN.

Solución: Ajusta MTU de wg a 1420 (o menor), prueba con ping -M do, evita bloquear mensajes ICMP de fragmentación necesitados. Si es necesario, aplica clamping de MSS TCP en los bordes.

3) “Oficina A puede alcanzar Oficina B, pero no Oficina C”

Síntomas: Una subred remota funciona; otra no. El handshake está bien.

Causa raíz: Falta de ruta/entrada AllowedIPs para la subred que no funciona en el spoke o en el hub.

Solución: Añade la subred faltante al AllowedIPs correcto y confirma rutas. Revisa wg show allowed-ips por solapamientos.

4) “Solo funciona en una dirección”

Síntomas: Un host en la Oficina A puede alcanzar Oficina B, pero las respuestas nunca regresan (o viceversa).

Causa raíz: Reverse path filtering, enrutamiento asimétrico por otra VPN, o un firewall LAN que no conoce las subredes remotas.

Solución: Desactiva rp_filter para las interfaces wg, asegura rutas de retorno y actualiza políticas de firewall LAN para permitir subredes remotas.

5) “Funcionó ayer, ahora nadie puede conectar después de ‘cambios menores’”

Síntomas: Tras un reboot o actualización, los túneles no suben o el enrutamiento es distinto.

Causa raíz: Cambios en tiempo de ejecución guardados inesperadamente, conflictos de nombres de tablas nftables, o forwarding sysctl no persistente.

Solución: Usa SaveConfig=false, define reglas de firewall en un sistema dedicado e idempotente (unidad systemd o gestión de configuración), y establece sysctl en /etc/sysctl.d/.

6) “Cambia aleatoriamente qué oficina recibe tráfico para una subred”

Síntomas: Algunas sesiones van al destino equivocado; el primer hop de traceroute cambia; accesibilidad intermitente.

Causa raíz: AllowedIPs solapados en el hub. Dos peers reclamando la misma subred es una pelea de enrutamiento sin ganador.

Solución: Haz AllowedIPs mutuamente exclusivos y haz que se revisen. Trátalo como una tabla de enrutamiento: la unicidad no es negociable.

7) “La VPN está arriba, pero los clientes en la oficina no alcanzan redes remotas”

Síntomas: El router spoke puede hacer ping a hosts remotos; los escritorios de la oficina no pueden.

Causa raíz: Los clientes de la oficina carecen de ruta a subredes remotas (gateway por defecto equivocado), o el firewall del spoke no reenvía LAN→wg0.

Solución: Asegura que los clientes usen el router de la oficina como gateway (DHCP), o añade rutas estáticas en el switch core si haces L3 internamente; arregla reglas de forward y verifica con contadores.

Listas de verificación / plan paso a paso

Plan de despliegue paso a paso (haz esto, en este orden)

  1. Inventario de restricciones. Para cada oficina: tipo de WAN, presencia de NAT, quién controla el router y si es posible UDP inbound. Asume “no” hasta que se demuestre lo contrario.
  2. Bloquea el plan de IPs. Elige subredes de oficina no solapadas y un rango de tránsito WireGuard dedicado.
  3. Construye el hub primero. Endurece lo básico del OS: actualizaciones, NTP, línea base de firewall, copias de seguridad de /etc/wireguard.
  4. Genera claves por peer. Lleva las claves públicas en un lugar controlado. Nunca roten las claves a la ligera sin coordinación.
  5. Configura wg0 en el hub. Añade peers con AllowedIPs únicos (su wg /32 y su subred de oficina).
  6. Configura un spoke (piloto). Habilita forwarding, rutas y reglas de firewall. Levanta el túnel.
  7. Prueba desde hub al wg IP del spoke. Haz ping, luego traceroute a un host piloto en la oficina.
  8. Prueba desde un cliente de oficina a otra oficina. Verifica ambas direcciones y al menos un protocolo “real” (SMB o HTTPS), no solo ping.
  9. Confirma MTU. Ejecuta pings DF alrededor de 1400. Si falla, ajusta MTU ahora, no después de las quejas.
  10. Añade los demás spokes. Repite la misma validación para cada oficina.
  11. Instrumenta. Como mínimo, un cron/systemd timer que capture snapshots de wg show, además de contadores del firewall.
  12. Control de cambios. Trata las ediciones de config de WireGuard como cambios de firewall: revisados, escalonados y con rollback.

Lista operativa (semanal, aburrida, efectiva)

  • Comprueba la frescura del handshake y contadores de tráfico en horas laborales.
  • Confirma espacio en disco del hub (logs y core dumps no tienen sentimientos).
  • Revisa actualizaciones de kernel/red aplicadas al hub o spokes.
  • Verifica que las copias de seguridad incluyan claves y configs de WireGuard, cifradas y con control de acceso.
  • Revisa muestreos de contadores nftables por drops inesperados.

Lista de seguridad (práctica, no performativa)

  • Restringe inbound al hub a UDP/51820 y acceso administrativo (SSH) desde IPs de gestión conocidas.
  • En el hub, default-drop en forward y permite explícitamente solo lo que pretendes entre spokes.
  • Mantén claves por sitio; no reutilices claves entre oficinas.
  • Documenta qué subredes de oficina pueden acceder a qué servicios; haz cumplir eso en el hub.
  • Planifica rotación de claves (trimestral/semestral) y ensáyala. El ensayo es donde descubres dependencias ocultas.

Tres mini-historias corporativas desde el terreno

Mini-historia 1: El outage causado por una suposición equivocada

Estandarizaron las tres sucursales comprando el mismo paquete ISP en todos lados. Mismo modelo de modem/router. Mismo plan. Mismas promesas de marketing. La suposición fue que el comportamiento de NAT también sería “el mismo”, así que se saltaron los keepalives persistentes. Total, WireGuard es moderno y maneja roaming. ¿Qué podría salir mal?

Dos semanas después, la Oficina C comenzó a reportar tickets: “La VPN cae aleatoriamente.” No era aleatorio. El dispositivo del ISP tenía un timeout UDP agresivo y eliminaba la asignación NAT tras un breve periodo de inactividad. Cuando la oficina estaba tranquila (almuerzos, primeras horas), la asignación expiraba. El siguiente paquete desde la Oficina C salía, pero la respuesta entrante del hub volvía a un mapeo de puerto muerto.

En el hub, el endpoint del peer parecía obsoleto. El handshake solo se actualizaba después de que alguien en la Oficina C intentara repetidamente, dando al NAT suficiente tráfico saliente para recrear la asignación. El equipo persiguió DNS, luego la CPU del hub, y discutieron si UDP debería ser “más fiable”.

La solución fue embarazósamente pequeña: PersistentKeepalive = 25 en el spoke. La lección fue mayor: no asumas que el comportamiento de NAT es consistente solo porque la caja de plástico se parece. Los timeouts NAT varían por firmware, configuración y humor.

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

Un ingeniero de red decidió que las reglas de firewall del hub eran “demasiado estrictas”. Su lógica: si el túnel está cifrado, ¿por qué no aceptar todo el forward desde wg0? Reemplazó reglas explícitas por un amplio accept, y luego—porque le gustaba la simetría—permitió forward de wg0 a eth0 también. “A prueba de futuro”, lo llamó.

Funcionó durante meses. Entonces llegó una migración SaaS. Una oficina tenía una ruta mal configurada en una VLAN de pruebas que apuntaba un gran volumen de tráfico a Internet dentro de la VPN. El hub lo encaminó felizmente a Internet. El egress del hub se saturó en horas laborales.

Los síntomas fueron clásicos: jitter en VoIP, transferencias de archivos lentas y tickets vagos de “la red se siente lenta”. Porque el hub ahora era un breakout a Internet no intencional, el problema parecía “rendimiento de WireGuard” cuando en realidad era “convertiste tu hub en un ISP transitivo”.

El rollback fue reintroducir reglas de forwarding restrictivas y bloquear explícitamente wg0→eth0 salvo para subredes de gestión conocidas. La optimización—“menos reglas de firewall”—ahorró exactamente cero minutos a largo plazo y creó un modo de falla difícil de ver. Mantén tu hub honesto: enruta solo lo que pretendes.

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

Otra compañía tenía una costumbre que parecía dolorosamente aburrida: cada cambio de red requería una pequeña captura “antes/después” de wg show, ip route y reglas de firewall. Lo almacenaban junto al ticket de cambio. Sin heroísmos, sin misterio.

Un viernes, una oficina perdió acceso a dos servicios internos alojados en otra sucursal. Los túneles estaban arriba. Los pings funcionaban a los routers. Pero el tráfico de aplicación fallaba. El ingeniero on-call sacó el último snapshot “conocido bueno” y lo comparó con el estado actual.

El diff fue obvio: una subred de oficina se había cambiado de 10.10.30.0/24 a 10.10.30.0/23 durante una “expansión menor”, pero los AllowedIPs del hub aún reclamaban solo el /24. La mitad de los hosts de la oficina quedaron fuera del rango enrutado. Esos hosts podían iniciar algunas sesiones (dependiendo de la IP origen), pero otras quedaron en agujero negro. Parecía aleatorio, porque era aleatorio respecto a la asignación DHCP.

La solución tomó minutos: actualizar AllowedIPs en el peer del hub y reiniciar la interfaz. Lo que salvó la situación no fue la genialidad; fue la traza documental. Las prácticas aburridas no obtienen aplausos. Evitan que pases tu fin de semana demostrando que tenías razón.

Preguntas frecuentes

1) ¿Necesito malla completa para solo tres oficinas?

No. Puedes hacerlo, pero hub-and-spoke es más fácil de operar. Un hub para asegurar, monitorizar y depurar. La malla se vuelve “todos responsables de la alcanzabilidad de todos”.

2) ¿Debe el hub hacer NAT entre oficinas?

No por defecto. Enruta subredes reales de extremo a extremo para que los logs y ACLs sigan teniendo sentido. NAT es aceptable para breakout central a Internet o mitigación temporal de solapamientos, no como camino estándar.

3) ¿Dónde debo poner PersistentKeepalive?

En los spokes, casi siempre, especialmente detrás de NAT. 25 segundos es un valor común. Si tu enlace es medido o caro, puedes aumentarlo, pero no lo elimines a la ligera.

4) ¿Puedo usar nombres DNS en lugar de IP estática para el endpoint del hub?

Sí, pero no finjas que el DNS es infalible. Si usas un nombre DNS, asegúrate de que los spokes puedan resolverlo de forma fiable y considera cómo manejarás un cambio de IP del hub sin intervención humana.

5) ¿Por qué usas direcciones /32 en los spokes para wg0?

Porque reduce la ambigüedad. La interfaz del túnel no necesita una sensación de segmento L2 compartido; necesita un identificador estable por peer. /32 es limpio, y el enrutamiento se basa en AllowedIPs de todos modos.

6) ¿Cuál es el mejor MTU para WireGuard sitio a sitio?

Empieza en 1420. Si tienes PPPoE o caminos WAN raros, puede que necesites menos. Mide con pings DF y valida con tráfico real (SMB/HTTPS) antes de declarar victoria.

7) ¿Puedo limitar qué oficinas pueden hablar entre sí?

Sí, y deberías. Hazlo en el hub con reglas en la cadena forward (wg0→wg0) que coincidan fuente/destino por subred. No confíes en “probablemente no lo harán”.

8) ¿Cómo manejo subredes solapadas sin renumerar?

Puedes hacer NAT en un lado o usar mapeo 1:1, pero es deuda operacional. Pasarás tiempo depurando identidad y problemas de ACL. Si es permanente, planifica un proyecto de renumeración.

9) ¿WireGuard ofrece control de acceso a nivel de usuario?

No. Son claves de peer y AllowedIPs. Para VPN de usuario normalmente terminas en un sistema separado e integras identidad, MFA y posture de dispositivo.

10) ¿Necesito alta disponibilidad para el hub?

Si las oficinas dependen de él para operaciones núcleo, sí. Al mínimo: backups, reconstrucción automatizada y un plan de failover probado (hub secundario, o IP flotante en entornos que lo soporten). “Lo restauraremos” no es un plan hasta que lo hayas temporizado.

Siguientes pasos que realmente reducen alertas

WireGuard hub-and-spoke es un diseño sólido, pero solo si tratas el hub como infraestructura, no como un proyecto lateral. Aquí tienes qué hacer a continuación, en orden práctico:

  1. Escribe la intención. Qué subredes existen, cuáles deben enrutar por WireGuard y qué oficinas pueden acceder a qué servicios.
  2. Haz revisable AllowedIPs. Mantén configs en control de versiones, exige revisión y aplica “sin solapamientos” como un elemento de checklist humano.
  3. Codifica la política de firewall. Default-drop en forward en el hub, luego permite solo los flujos inter-oficina que quieres. Cuenta los drops.
  4. Mide MTU una vez, correctamente. Pruebas DF ping y una transferencia real de archivos. Luego fija MTU y no lo toques salvo que cambie la WAN.
  5. Construye una rutina de diagnóstico repetible. El playbook arriba es tu primer respondedor. Imprímelo, pégalo y úsalo.
  6. Decide si quieres breakout central. Si sí, hazlo intencionalmente con rutas explícitas y NAT, y planifica ancho de banda y aplicación de políticas.

Si haces estas cosas, tus tres oficinas dejarán de comportarse como tres planetas separados. Y cuando algo falle—porque eventualmente fallará—tendrás suficiente señal para arreglarlo sin sacrificios rituales a los dioses de la red.

← Anterior
MySQL vs PostgreSQL: «Se puso lento de repente» — plan de diagnóstico de 15 minutos para ambos
Siguiente →
Antivirus que deja inutilizables los PCs: la ironía que se repite

Deja un comentario