Redes mesh con WireGuard sin volverte loco
Índice de contenidos
- Puntos clave
- Por qué una malla no es solo repetir enlaces
- Patrones que funcionan para pocos nodos
- Dónde el patrón manual se rompe
- Cuándo subir a Tailscale
- Cómo elegir entre los tres
- Los errores comunes que he visto
- Cómo pensar la decisión
- Preguntas frecuentes
- ¿Hasta cuántos nodos aguanta una malla WireGuard configurada a mano?
- ¿Puedo poner AllowedIPs = 0.0.0.0/0 en todos los peers para no complicarme?
- ¿Qué pasa si un nodo está detrás de NAT y persistent-keepalive no basta?
- Fuentes
WireGuard es simple por cable, pero montar una malla de varios nodos a mano se convierte rápido en un enredo de claves y rutas. Patrones que funcionan, cuándo merece WireGuard puro y cuándo conviene apoyarse en Tailscale o Headscale.
WireGuard resolvió en 2019 un problema real con las VPN: los protocolos existentes (OpenVPN, IPsec) funcionaban pero tenían configuración complicada, rendimiento mediocre y superficie de ataque grande. WireGuard llegó con menos de 4.000 líneas de código, según su documento técnico original[1]. OpenVPN supera las 110.000 líneas y una pila IPsec típica pasa de las 400.000. WireGuard trae criptografía moderna y un modelo tan simple que cabe en dos páginas de documentación.
Para un enlace punto a punto entre dos nodos, montar WireGuard es cuestión de media hora. Para una malla de cinco, diez o veinte nodos comunicándose entre ellos, la cosa se complica rápido y aparecen patrones repetidos, ciertos modos de fallo y decisiones que conviene entender antes de empezar.
Para el contexto de red en el que WireGuard opera, el análisis de Nebula y redes VPN de empresa describe la alternativa de plano de control distribuido. La relación de WireGuard con redes privadas 5G se trata en redes 5G privadas empresa. Los patrones de seguridad de red que complementan la capa VPN se cubren en Zero Trust y SIEM integración.
Puntos clave
-
El coste organizativo de una malla manual crece cuadráticamente con el número de nodos; para más de diez nodos o cambios frecuentes, conviene una capa de control.
-
El patrón manual con tres o cinco nodos estables y IPs públicas funciona bien durante años con una plantilla Jinja para generar configuraciones.
-
allowed-ipses el punto más delicado: un rango mal puesto puede crear bucles de enrutado o dejar tráfico caído sin aviso visible. -
Tailscale resuelve la complejidad operativa a cambio de un plano de control externo; Headscale da control total a cambio de mantener ese plano de control.
-
Monitorizar la malla con checks básicos de ping y métricas de bytes en Prometheus evita depurar a ciegas.
Por qué una malla no es solo repetir enlaces
El modelo mental de WireGuard es simple. Cada nodo es un peer con una clave pública y una clave privada, y tiene una lista de otros peers con sus claves y sus rangos de IP permitidos. Para dos nodos, esto se resuelve con un peer en cada lado. Para diez nodos, cada uno debe conocer los otros nueve, lo que significa que cada vez que añades o quitas un nodo tienes que actualizar la configuración en todos los demás.
El coste no es técnico, es organizativo: olvidarse de un nodo al retirar uno antiguo deja una puerta abierta que nadie está vigilando.
La segunda complicación es el enrutado. Si los nodos están en redes distintas, cada uno necesita saber qué subredes le llegan por qué peer. Cuando además quieres que cualquier nodo pueda hablar con servicios detrás de cualquier otro, la configuración de allowed-ips se vuelve delicada. Una línea mal puesta enruta los paquetes por el peer equivocado, el tráfico cae y te pasas una tarde haciendo tcpdump en tres sitios a la vez.
La tercera complicación es NAT. Si todos los nodos están en servidores con IP pública estable, todo funciona. En cuanto alguno está detrás de NAT (un portátil, un servidor en un domicilio, un dispositivo móvil), los otros nodos no pueden iniciar conexión hacia él.
Hay soluciones: mantener el túnel activo con persistent-keepalive, usar un nodo público como rendezvous, o usar alguna de las técnicas de hole-punching descritas en el RFC 5128[2] del IETF. Ninguna es mala pero cada una añade configuración que hay que entender.
Patrones que funcionan para pocos nodos
Si la malla tiene entre dos y cinco nodos y todos tienen IP pública estable, el patrón manual es razonable y funciona bien. Una convención clara de claves, un repositorio git privado con los ficheros wg0.conf generados por una plantilla, y revisiones cruzadas cuando cambia algo. En este tamaño la malla se mantiene sola y los errores se detectan rápido porque cualquier fallo afecta inmediatamente a todo el sistema.
El patrón que funciona en estos casos tiene tres piezas:
-
Esquema de direcciones claro: 10.10.0.0/24, con los nodos numerados 10.10.0.1, 10.10.0.2, etc. Nada de subredes anidadas ni mapeos indirectos; la dirección privada del nodo es su identidad.
-
Plantilla Jinja que genera el
wg0.confcon los peers a partir de una lista central. -
Revisión manual cuando cambia algo: dos personas leen el diff antes de aplicarlo.
En cada nodo, el fichero wg0.conf tiene esta forma:
[Interface]
PrivateKey = <clave privada>
Address = 10.10.0.1/24
ListenPort = 51820
[Peer]
PublicKey = <clave publica peer>
AllowedIPs = 10.10.0.2/32
Endpoint = peer.example:51820
PersistentKeepalive = 25
Con una sección Peer adicional por cada nodo vecino.
Dónde el patrón manual se rompe
El patrón manual se rompe con claridad cuando la malla pasa de diez nodos o cuando la lista de nodos no es estable. En una malla con doce servidores y tres portátiles, la administración manual se convierte en trabajo semanal y aparecen los errores humanos. Un nodo retirado hace tres meses sigue listado en cinco configuraciones olvidadas. Un portátil nuevo tarda medio día en añadirse porque hay que coordinar cinco cambios.
También se rompe cuando la malla involucra máquinas que no puedes tratar como servidores estables (portátiles con usuarios diferentes, móviles con cambio de red, dispositivos IoT) y cuando las políticas de acceso son granulares. WireGuard puro no tiene concepto de grupos de peers ni reglas por aplicación. Si necesitas que el peer A hable con el peer B solo por el puerto 443, añade reglas iptables en cada nodo.
Cuándo subir a Tailscale
Tailscale responde a estos problemas con un plano de control centralizado que gestiona claves, IPs y políticas. El plano de datos sigue siendo WireGuard puro entre los nodos[3], según su propia documentación.
Con Tailscale, añadir un nodo es instalar un agente y autenticarse. Los cambios en la malla se propagan solos en segundos. Las políticas de acceso se declaran en un fichero central y se distribuyen a todos los nodos.
La pega de Tailscale es que el plano de control vive en sus servidores. Esto no es problema mientras el coordinador solo intercambie claves y candidatos de conexión: no ve el tráfico real, que viaja de nodo a nodo por WireGuard. Para equipos con requisitos de soberanía o industrias con cumplimiento estricto, depender de un proveedor externo para la coordinación de VPN es un no automático.
Headscale[4] es una reimplementación de código libre del plano de control de Tailscale, mantenida por la comunidad. Los nodos siguen usando el cliente oficial de Tailscale, pero el servidor de coordinación lo controlas tú. Esto da lo mejor de ambos mundos: la comodidad de Tailscale, sin dejar fuera de tu infraestructura ni las claves ni las políticas.
Cómo elegir entre los tres
La decisión entre WireGuard puro, Tailscale y Headscale se puede resumir en pocas preguntas:
| Criterio | WireGuard puro | Tailscale | Headscale |
|---|---|---|---|
| Pocos nodos estables | Ideal | Innecesario | Innecesario |
| Muchos nodos o cambios frecuentes | Costoso | Ideal | Ideal |
| Soberanía de datos estricta | Válido | No válido | Válido |
| Equipo sin experiencia en redes | Complejo | Ideal | Moderado |
| Acceso remoto de personas | Funcional | Ideal (MagicDNS, SSH) | Bueno |
| Nodos servidores estables | Ideal | Innecesario | Innecesario |
Los errores comunes que he visto
Hay errores que se repiten cuando un equipo monta una malla WireGuard por primera vez:
-
Confiar en que
persistent-keepaliveresuelva cualquier problema de NAT: si el NAT es simétrico los paquetes entrantes se bloquean y necesitas un nodo público como rendezvous. -
Configurar
allowed-ipscomo0.0.0.0/0en todos los peers: cada nodo se convierte en puerta por defecto para los demás y aparecen bucles de enrutado sorprendentes. Los rangos enallowed-ipsdeben ser mínimos. -
Olvidar que
wg-quickreinicia la interfaz al aplicar cambios y eso mata conexiones activas; conviene coordinar estos reloads. -
No monitorizar la malla: un túnel caído no grita, simplemente deja de pasar tráfico y nadie se entera hasta que alguien intenta usarlo. Añadir checks básicos a Prometheus evita depurar a ciegas.
Cómo pensar la decisión
Mi consejo si no sabes por dónde empezar es montar una malla mínima con WireGuard puro entre dos o tres servidores de prueba. En una tarde entiendes el modelo, ves cómo se comportan las claves, las IPs y el enrutado. Con ese entendimiento básico ya puedes decidir si el patrón manual te vale o si necesitas una capa de control.
Si decides que necesitas capa de control, la elección entre Tailscale y Headscale es casi ideológica: Tailscale es más cómodo y funciona inmediatamente, Headscale da control total a cambio de mantener un servicio más. Ambos son válidos en contextos distintos.
WireGuard es una herramienta excelente pero no es magia. Su poder aparece cuando se usa con disciplina: claridad sobre la identidad de cada nodo, reglas mínimas para el enrutado y un plan claro para cuando la malla crezca. Con estas tres piezas, una malla WireGuard puede durar años sin drama.
Este artículo también está disponible en inglés: Mesh networks with WireGuard without losing your mind.
Fuentes:
- WireGuard: documento técnico oficial (Next Generation Kernel Network Tunnel)[1]
- Tailscale: Control and data planes[3]
- Headscale: repositorio oficial en GitHub[4]
- IETF RFC 5128: State of Peer-to-Peer (P2P) Communication across NATs[2]
Preguntas frecuentes
¿Hasta cuántos nodos aguanta una malla WireGuard configurada a mano?
Entre dos y cinco nodos con IP pública estable, el patrón manual funciona bien durante años. Necesita un esquema de direcciones claro tipo 10.10.0.0/24, una plantilla Jinja que genere el wg0.conf desde una lista central y la revisión del diff por dos personas. Se rompe con claridad al pasar de diez nodos o cuando la lista de nodos no es estable, porque cada nodo debe conocer a todos los demás y el coste organizativo crece cuadráticamente.
¿Puedo poner AllowedIPs = 0.0.0.0/0 en todos los peers para no complicarme?
No. Si cada peer tiene allowed-ips a 0.0.0.0/0, cada nodo se convierte en puerta por defecto para los demás y aparecen bucles de enrutado sorprendentes. Una línea mal puesta enruta los paquetes por el peer equivocado y el tráfico cae sin aviso visible. Los rangos deben ser mínimos, como AllowedIPs = 10.10.0.2/32 por peer, de modo que la dirección privada del nodo sea su identidad.
¿Qué pasa si un nodo está detrás de NAT y persistent-keepalive no basta?
Con NAT simétrico los paquetes entrantes se bloquean aunque uses PersistentKeepalive, así que necesitas un nodo con IP pública como rendezvous o alguna técnica de hole-punching de las descritas en el RFC 5128. Si además hay portátiles o móviles que entran y salen, esa es la señal para subir a una capa de control. Elige Tailscale si aceptas su plano de control externo, o Headscale si necesitas mantenerlo en tu infraestructura.