Créer un cluster VPS privé avec un maillage WireGuard
Reliez des nœuds VPS en un cluster privé avec un maillage complet WireGuard : un plan d'adressage, un [Peer] par nœud, des AllowedIPs en /32, un pare-feu strict et des services liés à wg0.
En bref : pour transformer plusieurs VPS en cluster privé, donnez à chaque nœud une interface WireGuard avec une adresse issue d'un même sous-réseau privé, ajoutez chaque autre nœud comme `[Peer]` avec son `Endpoint` public et un `/32` dans `AllowedIPs`, n'autorisez UDP 51820 que depuis vos propres nœuds, et liez les bases de données et services internes à l'adresse `wg0` plutôt qu'à l'IP publique. Jusqu'à une dizaine de nœuds, c'est facile à maintenir à la main ou avec un modèle ; au-delà, utilisez un outil qui génère et distribue les configurations.
Ce guide suppose que vous connaissez déjà les bases présentées dans le guide VPN WireGuard et que vous avez durci SSH sur chaque nœud comme dans le guide de durcissement SSH ; pour joindre les nœuds via un bastion sans transfert d'agent, voir le guide StrictModes et transfert d'agent.
Plan d'adressage des nœuds VPN
Choisissez une plage privée qui n'entre en collision avec rien d'autre (réseau local domestique, Docker, plages de pods Kubernetes). Un `/24` suffit pour un petit cluster et garde des adresses lisibles. Attribuez à chaque nœud une adresse fixe et versionnez le plan, car chaque configuration en découle.
| Nœud | Rôle | IP publique | Adresse wg0 | ListenPort |
|---|---|---|---|---|
| node1 | application | 203.0.113.11 | 10.88.0.1/24 | 51820 |
| node2 | application | 203.0.113.12 | 10.88.0.2/24 | 51820 |
| node3 | base de données | 203.0.113.13 | 10.88.0.3/24 | 51820 |
| node4 | supervision | 203.0.113.14 | 10.88.0.4/24 | 51820 |
Configuration par pair sur chaque nœud VPS
Dans un maillage complet, chaque nœud communique directement avec tous les autres : chaque configuration comporte une section `[Interface]` et N-1 sections `[Peer]`. Quatre nœuds représentent six tunnels au total ; dix nœuds, 45. Chaque nœud ayant une IP publique, `PersistentKeepalive` n'est généralement pas nécessaire ; les détails sont dans le guide keepalive et PresharedKey.
- 01.Sur chaque nœud, lancez `apt install wireguard`, puis `umask 077; wg genkey | tee /etc/wireguard/wg0.key | wg pubkey > /etc/wireguard/wg0.pub`.
- 02.Rassemblez toutes les clés publiques et le plan d'adressage en un seul endroit.
- 03.Générez éventuellement une clé `wg genpsk` par paire de nœuds comme protection post-quantique.
- 04.Écrivez `/etc/wireguard/wg0.conf` sur chaque nœud comme ci-dessous.
- 05.Lancez `systemctl enable --now wg-quick@wg0` et vérifiez dans `wg show` une poignée de main récente avec chaque pair.
# /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/32Comment fonctionne AllowedIPs dans un maillage
`AllowedIPs` remplit deux rôles à la fois. En sortie, c'est une table de routage : les paquets pour `10.88.0.3` vont au pair qui liste `10.88.0.3/32`. En entrée, c'est une liste d'accès : un paquet arrivant de ce pair n'est accepté que si son adresse source fait partie des `AllowedIPs` de ce pair. C'est pourquoi chaque pair reçoit exactement son propre `/32`, et non tout le `/24`.
Le `/24` de la ligne `Address` ne fait que créer la route noyau du sous-réseau sur `wg0` ; WireGuard choisit ensuite le bon pair selon la destination.
- ▹Deux pairs ne doivent jamais avoir de plages `AllowedIPs` qui se chevauchent sur la même interface ; la dernière l'emporte.
- ▹Si un nœud route aussi un sous-réseau privé (par exemple Docker sur node3), ajoutez ce sous-réseau aux `AllowedIPs` de node3 sur les autres nœuds.
- ▹Ne mettez pas `0.0.0.0/0` sur un pair du maillage, sauf si vous voulez vraiment que tout le trafic sorte par ce nœud.
Pare-feu : seuls vos nœuds atteignent le tunnel
WireGuard ne répond pas aux paquets non authentifiés, mais limiter UDP 51820 aux IP de nœuds connues réduit tout de même le bruit. À l'intérieur du tunnel, n'ouvrez que les ports nécessaires à chaque service. Cet exemple nftables pour Debian 12/13 et Ubuntu 24.04 se place dans `/etc/nftables.conf` ; chargez-le avec `nft -f /etc/nftables.conf` et activez `nftables.service`. Gardez une session SSH ouverte pendant les tests.
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
}
}Lier les services à l'interface wg
Le pare-feu est une couche ; la seconde consiste à ne pas écouter du tout sur l'adresse publique. Liez les services internes à l'adresse `wg0` du nœud pour qu'une erreur de pare-feu ne les expose pas. Comme `wg0` doit exister avant que le service ne s'y lie, ordonnez les unités avec un drop-in systemd, ou autorisez la liaison à des adresses pas encore actives avec `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 · Vérifiez le résultat avec `ss -tlnp` : les services internes doivent afficher `10.88.0.x`, jamais `0.0.0.0` ni l'IP publique.
Passer à l'échelle : quand adopter un outil
Un maillage écrit à la main convient tant que le nombre de nœuds reste faible et que les changements sont rares. Chaque nouveau nœud implique de modifier toutes les configurations existantes : le travail croît de façon quadratique. Dès que cela devient une corvée, générez les configurations au lieu de les écrire.
Chez NoctisNode, tous les nouveaux nœuds VPS sont déployés en FI-1 (Finlande), chacun avec une IPv4 dédiée et un port 1 Gbps non mesuré, et la facturation à l'heure ainsi que l'API agent (avec TTL d'auto-destruction) rendent peu coûteux l'ajout et la suppression de nœuds de test. Les offres démarrent au niveau Wisp ; voir offres VPS.
| Taille du cluster | Approche |
|---|---|
| 2–5 nœuds | Configurations écrites à la main, plan d'adressage dans un fichier texte |
| 5–15 nœuds | Ansible ou un autre outil de configuration générant wg0.conf à partir d'un inventaire unique |
| 15+ nœuds ou renouvellement fréquent | Un gestionnaire de maillage qui distribue automatiquement clés et pairs, ou une architecture en étoile |
FAQ
QComment relier plusieurs VPS en réseau privé ?
AInstallez WireGuard sur chaque VPS, donnez à chaque nœud une adresse issue d'un même sous-réseau privé et listez chaque autre nœud comme pair avec son endpoint public et des AllowedIPs en /32. Liez ensuite les services internes à l'adresse WireGuard.
QLes nœuds VPN d'un maillage WireGuard ont-ils besoin de PersistentKeepalive ?
AGénéralement non, car chaque nœud VPS a une IP publique et peut être joint directement. Ajoutez `PersistentKeepalive = 25` uniquement pour un nœud situé derrière un NAT.
QQuelles AllowedIPs définir pour chaque nœud VPS ?
AChaque pair reçoit uniquement sa propre adresse WireGuard en /32, plus tout sous-réseau que ce nœud route. Utiliser le sous-réseau entier du cluster pour chaque pair crée des routes qui se chevauchent et casse le maillage.
QCombien de nœuds un maillage WireGuard peut-il compter ?
AWireGuard gère lui-même de nombreux pairs, mais un maillage complet maintenu à la main devient fastidieux au-delà d'une dizaine de nœuds, car chaque nœud a besoin de la configuration de tous les autres. Au-delà, générez les configurations par automatisation ou utilisez un gestionnaire de maillage.