WireGuard es un protocolo VPN moderno integrado en el kernel de Linux desde la versión 5.6. Es rápido, usa criptografía fija (Curve25519, ChaCha20-Poly1305) y su configuración cabe en un único archivo por interfaz. En este tutorial conectarás dos redes privadas situadas en ubicaciones distintas mediante un túnel WireGuard entre dos gateways con Ubuntu 24.04, de forma que cualquier equipo de una red pueda llegar a los de la otra.

Requisitos previos

Necesitas dos servidores con Ubuntu 24.04 LTS, uno en cada sitio, que actuarán como gateways. Cada uno debe tener:

  • Una IP pública (o al menos uno de los dos debe ser alcanzable desde el otro por UDP).
  • Una interfaz conectada a la red local del sitio.
  • Un usuario no root con privilegios sudo.

A lo largo de la guía se usa este plan de direcciones. Sustitúyelo por el tuyo:

DatoSitio ASitio B
IP pública del gateway203.0.113.10198.51.100.20
Red local (LAN)10.10.0.0/2410.20.0.0/24
Interfaz LAN del gatewayeth1 (10.10.0.1)eth1 (10.20.0.1)
IP del túnel (wg0)10.99.0.1/3010.99.0.2/30

Las dos redes locales no pueden solaparse: si ambos sitios usan 192.168.1.0/24, renumera uno antes de empezar. Comprueba el nombre real de tus interfaces con ip -br addr.

Paso 1: Instalar WireGuard en los dos gateways

El módulo del kernel ya viene en Ubuntu 24.04; solo falta instalar las herramientas wg y wg-quick. Ejecuta en ambos gateways:

sudo apt update
sudo apt install wireguard

Comprueba que las herramientas están disponibles:

wg --version
wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/

Paso 2: Generar las claves

Cada gateway necesita su propio par de claves. El umask 077 hace que la clave privada solo sea legible por root. Ejecuta en cada gateway:

sudo -i
cd /etc/wireguard
umask 077
wg genkey | tee privatekey | wg pubkey > publickey
cat publickey
exit

Anota la clave pública de cada lado: la del sitio A se configura en el sitio B y viceversa. La clave privada nunca sale del servidor donde se generó.

Opcionalmente, genera una clave precompartida en uno de los gateways y cópiala al otro por un canal seguro. Añade una capa simétrica extra al intercambio de claves:

wg genpsk

Paso 3: Crear la configuración del sitio A

Crea el archivo de la interfaz en el gateway del sitio A:

sudo nano /etc/wireguard/wg0.conf
[Interface]
Address = 10.99.0.1/30
ListenPort = 51820
PrivateKey = CLAVE_PRIVADA_SITIO_A

[Peer]
# Sitio B
PublicKey = CLAVE_PUBLICA_SITIO_B
PresharedKey = CLAVE_PRECOMPARTIDA
Endpoint = 198.51.100.20:51820
AllowedIPs = 10.99.0.2/32, 10.20.0.0/24
PersistentKeepalive = 25

Sustituye CLAVE_PRIVADA_SITIO_A por el contenido de /etc/wireguard/privatekey de este servidor y CLAVE_PUBLICA_SITIO_B por la clave pública del otro gateway. Si no usas clave precompartida, elimina la línea PresharedKey.

AllowedIPs es la clave del site-to-site: cumple dos funciones a la vez. Define qué direcciones de origen se aceptan desde ese peer y, además, wg-quick crea automáticamente una ruta hacia esas redes a través de wg0. Por eso incluye la IP de túnel del otro extremo y su LAN completa.

PersistentKeepalive = 25 envía un paquete cada 25 segundos para mantener abierto el estado en firewalls y NAT intermedios. Solo es imprescindible en el lado que está detrás de NAT, pero no molesta en ambos.

Paso 4: Crear la configuración del sitio B

En el gateway del sitio B, crea el archivo equivalente con los valores invertidos:

sudo nano /etc/wireguard/wg0.conf
[Interface]
Address = 10.99.0.2/30
ListenPort = 51820
PrivateKey = CLAVE_PRIVADA_SITIO_B

[Peer]
# Sitio A
PublicKey = CLAVE_PUBLICA_SITIO_A
PresharedKey = CLAVE_PRECOMPARTIDA
Endpoint = 203.0.113.10:51820
AllowedIPs = 10.99.0.1/32, 10.10.0.0/24
PersistentKeepalive = 25

Si uno de los gateways no tiene IP pública (por ejemplo, está detrás del router de una oficina), omite la línea Endpoint en el peer que lo describe. El gateway sin IP pública iniciará la conexión y el otro aprenderá su dirección automáticamente.

Asegura los permisos del archivo en ambos gateways:

sudo chmod 600 /etc/wireguard/wg0.conf

Paso 5: Activar el reenvío de paquetes

Un gateway tiene que reenviar paquetes entre la LAN y el túnel, y Linux no lo hace por defecto. Crea un archivo de sysctl en ambos gateways:

sudo nano /etc/sysctl.d/99-wireguard.conf
net.ipv4.ip_forward = 1

Aplica el cambio sin reiniciar:

sudo sysctl --system

Verifica que está activo:

sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

Paso 6: Configurar UFW

Si usas UFW, abre el puerto de WireGuard para el gateway remoto. En el sitio A:

sudo ufw allow from 198.51.100.20 to any port 51820 proto udp

En el sitio B:

sudo ufw allow from 203.0.113.10 to any port 51820 proto udp

UFW bloquea el tráfico reenviado por defecto, así que también necesitas reglas de ruta entre la LAN y wg0. En el sitio A:

sudo ufw route allow in on wg0 out on eth1 from 10.20.0.0/24 to 10.10.0.0/24
sudo ufw route allow in on eth1 out on wg0 from 10.10.0.0/24 to 10.20.0.0/24

En el sitio B, lo mismo con las redes invertidas:

sudo ufw route allow in on wg0 out on eth1 from 10.10.0.0/24 to 10.20.0.0/24
sudo ufw route allow in on eth1 out on wg0 from 10.20.0.0/24 to 10.10.0.0/24

Revisa las reglas:

sudo ufw status verbose

Paso 7: Levantar el túnel

Arranca la interfaz y déjala habilitada al inicio en los dos gateways:

sudo systemctl enable --now wg-quick@wg0

Comprueba el estado del túnel:

sudo wg show
interface: wg0
  public key: Hq8...=
  private key: (hidden)
  listening port: 51820

peer: 7Zm...=
  preshared key: (hidden)
  endpoint: 198.51.100.20:51820
  allowed ips: 10.99.0.2/32, 10.20.0.0/24
  latest handshake: 12 seconds ago
  transfer: 1.24 KiB received, 1.48 KiB sent
  persistent keepalive: every 25 seconds

La línea latest handshake confirma que los dos extremos se han autenticado. Si no aparece, revisa la sección de solución de problemas.

Verifica también las rutas que ha creado wg-quick:

ip route show dev wg0
10.20.0.0/24 scope link
10.99.0.0/30 proto kernel scope link src 10.99.0.1

Paso 8: Dar a conocer la ruta a los equipos de la LAN

Los equipos de cada red local tienen que saber que la otra red se alcanza a través del gateway. Hay dos casos:

  • El gateway WireGuard es la puerta de enlace predeterminada de la LAN: no hay que hacer nada, el tráfico ya pasa por él.
  • La LAN usa otro router como puerta de enlace: añade en ese router una ruta estática hacia la red remota (en el sitio A, 10.20.0.0/24 vía 10.10.0.1). Si no puedes tocar el router, añade la ruta en cada equipo.

En un equipo Ubuntu del sitio A que use netplan, por ejemplo, la ruta se declara en su archivo de netplan dentro de la interfaz:

      routes:
        - to: 10.20.0.0/24
          via: 10.10.0.1

Aplica con sudo netplan apply. Para una prueba rápida y temporal puedes usar:

sudo ip route add 10.20.0.0/24 via 10.10.0.1

Paso 9: Comprobar la conectividad entre sitios

Desde el gateway A, haz ping a la IP del túnel del gateway B y a su IP LAN:

ping -c 3 10.99.0.2
ping -c 3 10.20.0.1

Después, desde un equipo de la LAN del sitio A, haz ping a un equipo de la LAN del sitio B y traza la ruta:

ping -c 3 10.20.0.50
tracepath -n 10.20.0.50
 1?: [LOCALHOST]                      pmtu 1500
 1:  10.10.0.1                                             0.412ms
 1:  10.10.0.1                                             0.389ms
 2:  10.10.0.1                                             0.401ms pmtu 1420
 2:  10.99.0.2                                            18.204ms
 3:  10.20.0.50                                           18.561ms reached

El salto por 10.99.0.2 y el pmtu 1420 muestran que el tráfico cruza el túnel WireGuard.

Añadir más sitios

Para un tercer sitio (por ejemplo, 10.30.0.0/24) tienes dos opciones:

  • Hub and spoke: el sitio A actúa como concentrador. Añade un bloque [Peer] para el sitio C en A, y en B añade 10.30.0.0/24 a los AllowedIPs del peer A (y en C, 10.20.0.0/24 a su peer A). El tráfico B a C pasa por A, que necesita las reglas ufw route correspondientes.
  • Malla completa: cada gateway tiene un [Peer] por cada otro sitio con la LAN de ese sitio en AllowedIPs. Es más eficiente, pero el número de peers crece con cada sede.

Dos peers de la misma interfaz no pueden compartir un rango en AllowedIPs; si ocurre, WireGuard asigna la red solo al último peer configurado.

Para aplicar cambios del archivo sin cortar el túnel existente:

sudo bash -c 'wg syncconf wg0 <(wg-quick strip wg0)'

Si has cambiado AllowedIPs, reinicia con sudo systemctl restart wg-quick@wg0 para que wg-quick recalcule las rutas.

Solución de problemas

No aparece latest handshake. Casi siempre es el firewall o las claves. Comprueba que el puerto UDP 51820 está abierto en ambos lados (y en cualquier firewall del proveedor), que cada PublicKey es la del otro gateway y que el Endpoint es correcto. Puedes ver si llegan paquetes con sudo tcpdump -ni any udp port 51820.

Hay handshake pero no llegas a la LAN remota. Revisa que net.ipv4.ip_forward vale 1, que existen las reglas ufw route en los dos gateways y que la red remota aparece en AllowedIPs. Si el ping desde el gateway funciona pero no desde un equipo de la LAN, falta la ruta de retorno del paso 8.

SSH o HTTPS se cuelgan pero el ping funciona. Es un problema de MTU. WireGuard usa 1420 por defecto; si hay PPPoE u otro túnel en el camino, baja el valor añadiendo MTU = 1380 en la sección [Interface] de ambos lados y reinicia el servicio.

Ver los registros del servicio.

sudo journalctl -u wg-quick@wg0

Conclusión

Tienes dos redes privadas unidas por un túnel WireGuard cifrado, con reenvío controlado por UFW y rutas creadas automáticamente a partir de AllowedIPs. Como siguientes pasos, puedes restringir las reglas ufw route a los servicios que realmente se usan entre sedes, añadir un tercer sitio en topología hub and spoke o monitorizar el túnel vigilando la antigüedad del último handshake con wg show wg0 latest-handshakes.