Monta un clúster privado de VPS con una malla WireGuard
Conecta nodos VPS en un clúster privado con una malla completa de WireGuard: un plan de direcciones, un [Peer] por nodo, AllowedIPs /32, un firewall estricto y servicios ligados a wg0.
Respuesta corta: para convertir varios VPS en un clúster privado, da a cada nodo VPS una interfaz WireGuard con una dirección de una misma subred privada, añade cada uno de los demás nodos como `[Peer]` con su `Endpoint` público y un `/32` en `AllowedIPs`, permite el UDP 51820 solo desde tus propios nodos y liga las bases de datos y los servicios internos a la dirección de `wg0` en lugar de a la IP pública. Hasta unos diez nodos es fácil de mantener a mano o con una plantilla; a partir de ahí, usa herramientas que generen y distribuyan las configuraciones.
Esta guía da por hecho que ya conoces lo básico de la guía de VPN con WireGuard y que has bastionado SSH en todos los nodos como en la guía de hardening de SSH; para llegar a los nodos a través de un bastión sin agent forwarding, consulta la guía de StrictModes y agent forwarding.
Plan de direcciones para los nodos de la VPN
Elige un rango privado que no choque con nada más que uses (LAN doméstica, Docker, rangos de pods de Kubernetes). Un `/24` basta para un clúster pequeño y mantiene las direcciones legibles. Asigna a cada nodo una dirección fija y guarda el plan en control de versiones, porque todas las configuraciones se derivan de él.
| Nodo | Función | IP pública | Dirección wg0 | ListenPort |
|---|---|---|---|---|
| node1 | app | 203.0.113.11 | 10.88.0.1/24 | 51820 |
| node2 | app | 203.0.113.12 | 10.88.0.2/24 | 51820 |
| node3 | base de datos | 203.0.113.13 | 10.88.0.3/24 | 51820 |
| node4 | monitorización | 203.0.113.14 | 10.88.0.4/24 | 51820 |
Configuración por peer en cada nodo VPS
En una malla completa, cada nodo habla directamente con todos los demás, así que cada configuración tiene un `[Interface]` y N-1 secciones `[Peer]`. Cuatro nodos suponen seis túneles en total; diez nodos, 45. Todos los nodos tienen IP pública, así que normalmente no hace falta `PersistentKeepalive`; los detalles están en la guía de keepalive y PresharedKey.
- 01.En cada nodo ejecuta `apt install wireguard` y luego `umask 077; wg genkey | tee /etc/wireguard/wg0.key | wg pubkey > /etc/wireguard/wg0.pub`.
- 02.Reúne en un solo lugar todas las claves públicas y el plan de direcciones.
- 03.Si quieres, genera una clave `wg genpsk` por cada par de nodos como protección frente a la computación cuántica.
- 04.Escribe `/etc/wireguard/wg0.conf` en cada nodo como se muestra abajo.
- 05.Ejecuta `systemctl enable --now wg-quick@wg0` y comprueba en `wg show` que hay un handshake reciente con cada peer.
# /etc/wireguard/wg0.conf on node1
[Interface]
Address = 10.88.0.1/24
ListenPort = 51820
PrivateKey = <node1 private key>
[Peer]
# node2
PublicKey = <node2 public key>
Endpoint = 203.0.113.12:51820
AllowedIPs = 10.88.0.2/32
[Peer]
# node3
PublicKey = <node3 public key>
Endpoint = 203.0.113.13:51820
AllowedIPs = 10.88.0.3/32
[Peer]
# node4
PublicKey = <node4 public key>
Endpoint = 203.0.113.14:51820
AllowedIPs = 10.88.0.4/32Cómo funciona AllowedIPs en una malla
`AllowedIPs` cumple dos funciones a la vez. En salida, es una tabla de enrutamiento: los paquetes para `10.88.0.3` van al peer que lista `10.88.0.3/32`. En entrada, es una lista de acceso: un paquete que llega de ese peer solo se acepta si su dirección de origen está dentro de los `AllowedIPs` de ese peer. Por eso cada peer recibe exactamente su propio `/32`, no todo el `/24`.
El `/24` de la línea `Address` solo crea la ruta del kernel para la subred en `wg0`; después WireGuard elige el peer adecuado para cada destino.
- ▹Dos peers nunca deben compartir un rango de `AllowedIPs` solapado en la misma interfaz; gana el último.
- ▹Si un nodo también enruta una subred privada (por ejemplo Docker en node3), añade esa subred a los `AllowedIPs` de node3 en los demás nodos.
- ▹No pongas `0.0.0.0/0` en un peer de la malla salvo que realmente quieras que todo el tráfico salga por ese nodo.
Firewall: solo tus nodos llegan al túnel
WireGuard no responde a paquetes no autenticados, pero limitar el UDP 51820 a las IP de nodos conocidos sigue reduciendo el ruido. Dentro del túnel, abre solo los puertos que necesite cada servicio. Este ejemplo de nftables para Debian 12/13 y Ubuntu 24.04 va en `/etc/nftables.conf`; cárgalo con `nft -f /etc/nftables.conf` y activa `nftables.service`. Mantén abierta una sesión SSH mientras pruebas.
table inet filter {
set mesh_peers {
type ipv4_addr
elements = { 203.0.113.11, 203.0.113.12, 203.0.113.13, 203.0.113.14 }
}
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
meta l4proto { icmp, ipv6-icmp } accept
tcp dport 22 accept
udp dport 51820 ip saddr @mesh_peers accept
iifname "wg0" ip saddr 10.88.0.0/24 tcp dport { 5432, 6379, 9100 } accept
}
}Liga los servicios a la interfaz wg
Un firewall es una capa; la segunda es no escuchar en absoluto en la dirección pública. Liga los servicios internos a la dirección `wg0` del nodo para que un error en el firewall no los exponga. Como `wg0` debe existir antes de que el servicio se ligue, ordena las unidades con un drop-in de systemd, o permite ligarse a direcciones que todavía no están activas con `net.ipv4.ip_nonlocal_bind = 1`.
# PostgreSQL on node3: postgresql.conf
listen_addresses = '10.88.0.3'
# pg_hba.conf
host all all 10.88.0.0/24 scram-sha-256
# Redis: /etc/redis/redis.conf
bind 10.88.0.3
# systemctl edit postgresql (repeat for other services)
[Unit]
[email protected]
[email protected]Note · Comprueba el resultado con `ss -tlnp`: los servicios internos deben mostrar `10.88.0.x`, nunca `0.0.0.0` ni la IP pública.
Escalado: cuándo pasarse a herramientas
Una malla escrita a mano está bien mientras haya pocos nodos y los cambios sean raros. Cada nodo nuevo obliga a editar todas las configuraciones existentes, así que el trabajo crece de forma cuadrática. Cuando eso se convierta en una carga, genera las configuraciones en lugar de escribirlas.
En NoctisNode, todos los nodos VPS nuevos se despliegan en FI-1 (Finlandia), cada uno con una IPv4 dedicada y un puerto de 1 Gbps sin medición, y la facturación por horas junto con la API de agentes (con un TTL de autodestrucción) abaratan añadir y eliminar nodos de prueba. Los planes empiezan en el nivel Wisp; consulta los planes VPS.
| Tamaño del clúster | Enfoque |
|---|---|
| 2–5 nodos | Configuraciones escritas a mano, plan de direcciones en un archivo de texto |
| 5–15 nodos | Ansible u otra herramienta de configuración que genere wg0.conf a partir de un único inventario |
| 15+ nodos o cambios frecuentes | Un gestor de malla que distribuya claves y peers automáticamente, o un diseño hub-and-spoke |
Preguntas frecuentes
Q¿Cómo conecto varios VPS en una red privada?
AInstala WireGuard en cada VPS, da a cada nodo una dirección de una misma subred privada y añade cada uno de los demás nodos como peer con su endpoint público y un AllowedIPs /32. Después, liga los servicios internos a la dirección de WireGuard.
Q¿Los nodos de una malla WireGuard necesitan PersistentKeepalive?
ANormalmente no, porque todos los nodos VPS tienen IP pública y son accesibles directamente. Añade `PersistentKeepalive = 25` solo para un nodo que esté detrás de NAT.
Q¿Qué AllowedIPs debe tener cada nodo VPS?
ACada peer recibe solo su propia dirección WireGuard como /32, más cualquier subred que enrute ese nodo. Usar la subred completa del clúster para todos los peers provoca rutas solapadas y rompe la malla.
Q¿Cuántos nodos puede tener una malla WireGuard?
AWireGuard en sí maneja muchos peers, pero una malla completa mantenida a mano se vuelve tediosa a partir de unos diez nodos, porque cada nodo necesita la configuración de todos los demás. Más allá de eso, genera las configuraciones con automatización o usa un gestor de malla.