Redes

Configuración de WireGuard VPN Punto a Punto en Linux: Guía Definitiva

Tengo dos servidores en datacenters distintos (un nodo de aplicación en Hetzner y una base de datos PostgreSQL en OVH) que necesitan hablar entre sí por un canal cifrado, y un worker de CI en casa que empuja artefactos al registry privado. Probé Tailscale y NetBird para no operar la VPN yo mismo, pero las dos capas de orquestación me agregaron modos de falla que no necesitaba para tres nodos. Volví a WireGuard pelado, topología punto a punto, una interfaz wg0 por par de nodos. Esta guía documenta exactamente esa configuración, con los seis errores que me costaron una tarde entera la primera vez y cómo detectarlos en cinco segundos con wg show y tcpdump si ya las quemaste.

Si tu caso de uso es estrictamente P2P entre nodos Linux con IPs conocidas, esta es la configuración más simple y debuggeable de WireGuard que existe. Si tienes cinco nodos, road warriors o CGNAT de por medio, saltá al final donde está la comparativa con Tailscale y NetBird.

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 25-40 minutos si tienes IPs públicas a mano, 1-2 horas si hay NAT de por medio.
  • Requisitos: Dos nodos Linux con kernel ≥5.6, root en ambos, un puerto UDP reachable (default 51820).
  • Resultado: Túnel cifrado Curve25519/AES-256/Chacha20 con latencia <1ms sobre LAN, 5-15ms sobre Internet, throughput ~950 Mbps en hardware moderno.
  • Troubleshooting típico: UDP bloqueado, AllowedIPs mal escrita, IP forwarding deshabilitado. Todos diagnosticables con un comando.

Por qué WireGuard punto a punto y no otra topología

WireGuard puede hacer tres cosas distintas: road warrior (clientes remotos entran a un servidor central), site to site (dos redes LAN se unen como si fueran una sola) y punto a punto (dos nodos Linux específicos se hablan entre sí, y nada más). Las guías rápidas suelen cubrir la primera porque es la más llamativa, pero la topología punto a punto es la más útil cuando tienes dos servidores que necesitan comunicarse de forma segura: un nodo de aplicación que habla con una base de datos, un worker de build que descarga artefactos de un registry privado, una réplica PostgreSQL que sincroniza con su primaria, un bridge entre un nodo de CI y un cluster on-prem. En todos esos casos, lo que quieres es un túnel limpio entre dos IPs que ya conoces de antemano, sin NAT traversal mágico, sin mesh, sin coordinador externo.

La ventaja operativa de P2P es brutal en debugging: cuando algo falla, hay exactamente dos lugares donde mirar. No hay tabla de routing que se confunda con 50 peers, no hay coordinadores que reescriben AllowedIPs, no hay magic DNS que resuelva mal. El precio es que necesitas saber las IPs (o al menos los hostnames) de los dos extremos antes de empezar, y uno de los dos nodos tiene que ser alcanzable desde el otro — punto. Si esa condición se cumple, esta es la topología más simple de WireGuard y la más rápida de operar.

Lo que necesitas antes de empezar

Antes de tocar wg-quick o wg set, asegúrate de tener estos datos a mano. Si tienes que detenerte a medio setup a buscar una IP pública o una clave, vas a perder el contexto y probablemente escribas mal una AllowedIPs:

  • Las dos máquinas Linux con kernel 5.6 o superior (WireGuard merged upstream en enero 2020, cualquier distro moderna lo trae). Para kernels más viejos hay que instalar wireguard-dkms + wireguard-tools.
  • Acceso root en ambas — WireGuard crea interfaces de red, no se puede hacer sin Capabilities de red o root completo.
  • La IP pública del Endpoint B (el que va a “escuchar” conexiones entrantes) y un puerto UDP que no esté bloqueado por tu ISP o firewall upstream. El default es 51820 pero cualquier alto (>1024) sirve.
  • Confirmá que ese puerto UDP está realmente abierto y reenviado si estás detrás de NAT. Un nc -uvz <ip-publica-b> 51820 desde el Endpoint A antes de configurar nada ahorra horas de troubleshooting.

Dos Endpoint A y B con IPs públicas con IPv4 estable es el caso ideal. Si uno de los dos está detrás de CGNAT (típico en ISP residenciales en LATAM, sobre todo Colombia y México con carriers como Claro o Telmex), la topología punto a punto se rompe y necesitas sí o sí un tercero que actúe como rendezvous — eso es Tailscale o NetBird, no WireGuard pelado. Asumimos en este artículo que ambos extremos tienen IPv4 pública.

Instalación en Debian, Ubuntu, RHEL y Arch

WireGuard se divide en dos paquetes: el módulo del kernel (wireguard-dkms o built-in) y las herramientas de userspace (wireguard-tools que provee wg y wg-quick). En kernels modernos el módulo ya está incluido y solo necesitas las tools. verifica siempre qué tienes cargado antes de instalar — instalar wireguard-dkms sobre un kernel que ya lo trae no rompe nada pero suma MB innecesarios y un rebuild en cada update de kernel.

Debian 12+ y Ubuntu 22.04+

# Verificar si el módulo ya está en el kernel
modinfo wireguard 2>&1 | head -3
# Si NO está (kernel custom o muy viejo):
sudo apt update
sudo apt install -y wireguard-tools wireguard-dkms
# Si SÍ está (caso típico en kernels stock):
sudo apt install -y wireguard-tools
# Verificar
wg --version

RHEL 9+, Rocky Linux, AlmaLinux, Fedora

# RHEL 9+, Rocky 9, Alma 9, Fedora 36+
sudo dnf install -y wireguard-tools
# En RHEL puede requerir EPEL si el módulo no está en el kernel stock
sudo dnf install -y epel-release elrepo-release
sudo dnf install -y kmod-wireguard
# Verificar
sudo wg --version

Arch Linux y derivados

sudo pacman -S --needed wireguard-tools
# El módulo viene built-in en el kernel oficial
sudo wg --version

Si tienes una distribución corporativa exótica (SUSE, Oracle Linux, AlmaLinux 8 con kernel 4.18) o un kernel custom compilado, el camino es wireguard-dkms + headers del kernel. El proceso es estándar pero doloroso — espera 5-10 minutos de compilación y reza para que ningún patch de tu vendor rompa la firma del módulo.

Generación de claves: hazlo en cada endpoint, no centralizado

WireGuard usa Curve25519 para el intercambio de claves, igual que SSH ed25519 en concepto (no confundir con la implementación). Cada endpoint necesita un par de claves: una privada que nunca sale del endpoint y una pública que se le entrega al otro peer. La regla de oro: genera las claves en el endpoint que las va a usar, no en una máquina central y después distribuirlas. La clave privada es el secreto que protege todo el túnel; si la transmitís por un canal inseguro o la dejás en un backup automatizado que sale a S3 sin cifrar, perdiste.

En el Endpoint A

umask 077
wg genkey | tee /etc/wireguard/endpoint-a.key | wg pubkey > /etc/wireguard/endpoint-a.pub
chmod 600 /etc/wireguard/endpoint-a.key
chmod 644 /etc/wireguard/endpoint-a.pub

En el Endpoint B

umask 077
wg genkey | tee /etc/wireguard/endpoint-b.key | wg pubkey > /etc/wireguard/endpoint-b.pub
chmod 600 /etc/wireguard/endpoint-b.key
chmod 644 /etc/wireguard/endpoint-b.pub

El umask 077 antes de genkey es importante: garantiza que el archivo se cree con permisos 600 (solo root) y no 644 (legible por todos). Un wg genkey sin umask adecuado crea un archivo que cualquier usuario local puede leer, y como contiene la clave privada, eso es game over para la seguridad del túnel.

Después de esto, cada endpoint tiene dos archivos. La clave privada se queda en el endpoint y nunca se transmite. La clave pública es lo que le pasás al otro — puede viajar por email, chat, escrito en un post-it, lo que sea, porque la pública no sirve para nada si no se tiene la privada correspondiente. Cuando configures los peers, vas a poner la clave pública del otro en tu config, nunca la tuya.

Preshared key: capa extra contra post-quantum

WireGuard tiene una segunda capa opcional llamada preshared key (PSK) que se aplica encima del handshake Curve25519. Es una clave de 32 bytes que se negocia fuera de banda y se incluye en cada peer. Su valor: aunque en el futuro alguien construya una computadora cuántica capaz de romper Curve25519, sin la PSK no puede descifrar el tráfico. Hoy es defensa en profundidad, no es estrictamente necesaria, pero suma cero overhead y se configura en una línea. Si puedes distribuirla por un canal seguro (sealed envelope, password manager compartido, age-encrypted file), hazlo:

# En CUALQUIER máquina, una sola vez:
wg genpsk > /tmp/psk-a-b.key
chmod 600 /tmp/psk-a-b.key
# Distribuir este archivo a ambos endpoints y borrarlo de la máquina intermedia

En la sección de cada peer, después vamos a ver dónde va PresharedKey = ....

Configuración del Endpoint A

El archivo de configuración va en /etc/wireguard/wg0.conf con permisos 600. El nombre wg0 es arbitrario, puedes usar wg-p2p o wg-db si quieres algo más descriptivo — pero wg0 es la convención que vas a encontrar en 99% de los tutoriales y ejemplos, así que te recomiendo respetarlo a menos que tengas razón fuerte.

sudo tee /etc/wireguard/wg0.conf > /dev/null <<EOF
[Interface]
PrivateKey = $(cat /etc/wireguard/endpoint-a.key)
Address = 10.0.0.1/32
ListenPort = 51820
# Opcional: si Endpoint A NATea tráfico de su LAN hacia Endpoint B
# PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
# Endpoint B
PublicKey = <CONTENIDO_DE_endpoint-b.pub>
PresharedKey = <CONTENIDO_DE_psk-a-b.key>
Endpoint = <IP_PUBLICA_B>:51820
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25
EOF
sudo chmod 600 /etc/wireguard/wg0.conf

Las AllowedIPs son la regla de seguridad más importante y la que más errores genera. En WireGuard, AllowedIPs cumple dos funciones a la vez: (1) qué IPs del peer remoto están permitidas como source/dest encriptado, y (2) qué tráfico de este endpoint se encripta y se manda al peer. Por eso en P2P estricto van /32 (solo la IP del otro extremo dentro del túnel) — si pusieras 0.0.0.0/0, estarías mandando TODO tu tráfico por el túnel, que en P2P no es lo que quieres (eso es la topología road warrior con un solo peer haciendo de gateway). El PersistentKeepalive = 25 es importante si Endpoint B está detrás de NAT — un keepalive cada 25 segundos mantiene la mapping NAT viva.

Configuración del Endpoint B

Misma estructura, espejada. En este ejemplo B no expone ningún servicio a la LAN, solo recibe el túnel.

sudo tee /etc/wireguard/wg0.conf > /dev/null <<EOF
[Interface]
PrivateKey = $(cat /etc/wireguard/endpoint-b.key)
Address = 10.0.0.2/32
ListenPort = 51820
[Peer]
# Endpoint A
PublicKey = <CONTENIDO_DE_endpoint-a.pub>
PresharedKey = <CONTENIDO_DE_psk-a-b.key>
AllowedIPs = 10.0.0.1/32
# Sin PersistentKeepalive si A no está detrás de NAT estricto
EOF
sudo chmod 600 /etc/wireguard/wg0.conf

Nótese la asimetría: A tiene Endpoint = ... y PersistentKeepalive porque es el que inicia el túnel (B está “escuchando”). B no tiene Endpoint en el peer porque A puede tener IP dinámica — WireGuard aprende la IP de A del primer paquete que llega. Si los dos extremos tienen IP pública fija, puedes poner Endpoint en ambos y la conexión es bidireccional sin keepalives.

Levantar el túnel y verificar que funciona

En ambos endpoints, después de copiar las claves públicas y tener los archivos wg0.conf correctos, levanta la interfaz:

sudo wg-quick up wg0
sudo systemctl enable --now [email protected]

El systemctl enable es fundamental: sin él, el túnel muere cada reboot y tú lo descubres cuando la réplica de base de datos lleva 4 horas caída. El unit file de systemd espera a que la red esté arriba antes de levantar wg0, así que no hay race condition con la NIC principal.

Verificación rápida en Endpoint A:

sudo wg show
# Esperado: interface wg0 con latest handshake reciente, transfer rx/tx creciendo
ping -c 3 10.0.0.2
# Esperado: 3 packets transmitted, 3 received
traceroute 10.0.0.2
# Esperado: primer hop directo a 10.0.0.2, no sale por la red pública

Si ping falla pero wg show muestra el peer con latest handshake haz menos de 2 minutos, el túnel está levantado y encriptado, pero algo en la capa 3 está bloqueando. Casi siempre es una de tres cosas: (1) firewall local en Endpoint B (iptables -L -n o ufw status), (2) AllowedIPs mal escrita en uno de los dos lados, (3) IP routing conflict — el kernel no sabe que 10.0.0.2 está en wg0. Para diagnosticar el (3), ip route get 10.0.0.2 debe devolver dev wg0 src 10.0.0.1.

Routing entre las LAN de cada endpoint (site-to-site light)

Hasta ahora tienes un túnel entre las IPs 10.0.0.1 y 10.0.0.2 dentro de WireGuard. Si quieres que además las LAN de cada endpoint se vean entre sí (por ejemplo, Endpoint A en 192.168.1.0/24 puede hablar con la 192.168.200.0/24 de B), necesitas ajustar AllowedIPs y agregar ip route y forwarding. Esto convierte la topología pura P2P en una híbrida P2P + route, sigue siendo simple pero requiere que el kernel reenvíe paquetes.

Habilitar IP forwarding en ambos endpoints

# Temporal (pierde efecto al reiniciar)
sudo sysctl -w net.ipv4.ip_forward=1
# Persistente
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-wireguard-forward.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard-forward.conf

Actualizar AllowedIPs para incluir la LAN remota

En Endpoint A, agregar la LAN de B en AllowedIPs del peer:

[Peer]
PublicKey = ...
Endpoint = <IP_PUBLICA_B>:51820
AllowedIPs = 10.0.0.2/32, 192.168.200.0/24
PersistentKeepalive = 25

Y al revés en Endpoint B: AllowedIPs = 10.0.0.1/32, 192.168.1.0/24.

Agregar la ruta estática para la LAN remota

# En Endpoint A: ruta hacia la LAN de B a través del peer WireGuard
sudo ip route add 192.168.200.0/24 dev wg0
# Para que sobreviva reboots, agregar al PostUp en wg0.conf:
# PostUp = ip route add 192.168.200.0/24 dev wg0
# PostDown = ip route del 192.168.200.0/24 dev wg0

NAT si la LAN remota no sabe volver

Si la máquina en la LAN de B (digamos 192.168.200.22) intenta responder a un ping desde A, manda el reply a su default gateway — y ese gateway no sabe nada de WireGuard, así que el paquete se cae. Para evitarlo, en Endpoint B tienes que source-NATear el tráfico que viene por wg0 y sale por la LAN:

sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -d 192.168.200.0/24 -j MASQUERADE

Esto le miente al host de la LAN de B: el reply dice “viene de 10.0.0.1”, no de 192.168.1.X, así que vuelve por el túnel sin que el host de la LAN tenga que saber nada de WireGuard. Es el mismo truco que usa un router convencional para dar internet a la LAN.

Con esto ya tienes las dos LAN comunicándose como si estuvieran en el mismo segmento — sin mesh, sin coordinador, sin daemon corriendo fuera de WireGuard. Para escenarios más complejos (más de dos nodos, full mesh entre N servidores) la topología se vuelve BGP sobre WireGuard, pero eso es otro artículo.

Troubleshooting: el 90% de los problemas son estos 4

Después de configurar docenas de túneles WireGuard P2P para clientes y homelabs, los problemas que aparecen una y otra vez son siempre alguno de estos. La diferencia entre un sysadmin frustrado y uno eficiente es saber cuál de los cuatro está mirando cuando algo no anda.

Síntoma Causa más probable Verificación rápida
Túnel no levanta, wg show no muestra el peer Endpoint IP/puerto mal escrita o firewall upstream bloqueando UDP nc -uvz <ip-b> 51820 desde A antes de tocar wg
latest handshake aparece pero ping falla AllowedIPs mal escrita o IP forwarding deshabilitado ip route get 10.0.0.2 + sysctl net.ipv4.ip_forward
Túnel anda, pero se cae cada 2-3 minutos NAT mapping en endpoint detrás de CGNAT se vence Reducir PersistentKeepalive a 15 o 20 segundos
Túnel anda en una dirección pero no en la otra Firewall local (iptables/ufw) en el endpoint receptor bloquea el source del túnel sudo iptables -L INPUT -n -v buscar DROP en 10.0.0.0/24

El caso (1) es el más común en setups nuevos. La gente asume que “ya abre el puerto en el firewall” sin verificarlo de verdad. nc -uvz toma 2 segundos y te ahorra 30 minutos de confusión.

El caso (4) es el más insidioso: en distros modernas con ufw o firewalld activo, el firewall agrega una zona por defecto que DROP todo lo que no sea SSH. Cuando WireGuard levanta la interfaz wg0, esos paquetes llegan pero la regla por defecto los tira. El fix es agregar la subred WireGuard a la zona trusted: sudo ufw allow in on wg0 to any o el equivalente en nftables. La guía de UFW vs firewalld cubre los detalles de cada uno.

Hardening: lo mínimo antes de producción

Un túnel WireGuard configurado según los pasos anteriores es funcional, pero si lo vas a tener corriendo 24/7 hay cuatro cosas más que hacer que te van a ahorrar incidentes a futuro.

Primero, monitorea el handshake. Un latest handshake que no se actualiza en 3-5 minutos significa que el peer está caído o unreachable. Inyectá esto en cualquier monitor que ya tengas (Prometheus con el exporter de node, Datadog, Zabbix) — es un counter de una línea y te avisa antes de que la app note la desconexión.

Segundo, rota las claves anualmente. WireGuard no tiene un mecanismo de rotación automática built-in (a diferencia de OpenVPN con easy-rsa), así que es un proceso manual. Regenerá el par de claves en cada endpoint, actualiza el PublicKey en el peer remoto, recarga con wg syncconf wg0 <(wg-quick strip wg0) y listo. El túnel no se cae durante la rotación — los handshakes viejos siguen siendo válidos hasta que expire el session timer (default 2 minutos).

Tercero, usa un puerto no estándar. 51820 es tan visible como 22 en SSH — los scanners de botnets lo buscan activamente. Cambialo a algo random (>30000) y no publiques tu IP WireGuard en DNS records. El “security through obscurity” no es seguridad real, pero reduce el ruido de logs y te protege de exploits zero-day que apunten a versiones específicas de WireGuard.

Cuarto, documenta la topología en el repo de infra. Aunque sean solo dos nodos, un README con las IPs públicas (privadas y públicas), los ports, los hashes de las claves públicas y un diagrama ASCII de la relación vale oro cuando vuelves al setup 8 meses después. Y si trabajas en equipo, le ahorra a tu compañero la hora de “¿alguien se acuerda cómo está configurado este túnel?”.

Cuándo NO usar WireGuard pelado

WireGuard en topología punto a punto es excelente para casos donde conoces los dos extremos, ambos tienen IP accesible y la cantidad de nodos es fija y chica. Si alguno de esos supuestos se rompe, el ROI de seguir con WireGuard pelado cae rápido y conviene pasar a una capa de orquestación encima.

Si necesitas acceder a la red desde un laptop o celular que cambia de IP todo el tiempo, no puedes tener IP fija en el peer, y ahí WireGuard pelado se vuelve tedioso. La solución más simple es Tailscale o NetBird, que corren un coordinator que mantiene el mapeo de IPs / keys. La comparativa WireGuard vs Tailscale vs NetBird entra en detalle de cuándo cada uno brilla, pero la regla de dedo es: si tienes que configurar menos de 5 nodos y todos son tuyos, WireGuard pelado es lo más simple. Si tienes usuarios remotos cambiando de red, Tailscale te ahorra headaches.

Si tienes que conectar más de 5-6 nodos entre sí en mesh, la gestión manual de claves y AllowedIPs se vuelve inmanejable. Ahí se justifica saltar a BGP sobre WireGuard con algo como BIRD o FRR, que automatiza el intercambio de rutas y deja WireGuard como mero transporte. Para una red de 50 nodos, esta es la única forma sensata de mantenerlo.

Si estás en un ISP con CGNAT y ninguno de tus dos nodos tiene IPv4 pública, WireGuard pelado no funciona — necesitas sí o sí un tercer nodo con IP pública que haga de rendezvous. Tailscale y NetBird resuelven esto automáticamente; si quieres algo self-hosted, la opción clásica es usar un VPS barato de Hetzner u OVH como relay y configurar los dos nodos detrás de NAT para que ambos marquen el relay como endpoint. Funciona, pero ya no es estrictamente “P2P” — es hub-and-spoke disfrazado.

Resumen

WireGuard en topología punto a punto es la forma más simple y debuggeable de tener un túnel VPN entre dos nodos Linux. Los pasos son siempre los mismos: instalar wireguard-tools en ambos extremos, generar un par de claves en cada uno (umask 077, permisos 600), intercambiar las claves públicas, escribir el wg0.conf con AllowedIPs = 10.0.0.X/32 y levantar con wg-quick up wg0 + systemctl enable. Para habilitar la comunicación entre las LAN, agregar IP forwarding, AllowedIPs de la LAN remota y una ruta estática. El 90% de los problemas son UDP bloqueado, AllowedIPs mal escrita, IP forwarding deshabilitado o firewall local tirando paquetes del source de WireGuard — todos diagnosticables con un comando de cinco segundos. Si tu caso de uso se aleja del P2P estricto (más de 5 nodos, usuarios móviles, CGNAT), considera subir a Tailscale, NetBird o BGP-sobre-WireGuard en lugar de seguir forzando WireGuard pelado.

Preguntas frecuentes

¿Por qué Configuración de WireGuard VPN Punto a Punto en Linux: Guía Definitiva es relevante para sysadmins Linux?

Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.

¿Qué necesito para empezar con Configuración de WireGuard VPN Punto?

Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.

¿Cuáles son los errores más comunes con Configuración de WireGuard VPN Punto?

Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.

¿Cuándo usar Configuración de WireGuard VPN Punto y cuándo una alternativa?

Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.

¿Cómo migro desde una configuración previa a Configuración de WireGuard VPN Punto?

Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *