Ce guide monte un serveur VPN WireGuard complet sur Linux : vous générez les clés, écrivez le fichier wg0.conf, activez le routage NAT, connectez un premier client et validez le handshake. Il s'adresse aux administrateurs débutants à intermédiaires qui veulent un tunnel chiffré pour accéder à distance à un serveur ou un réseau privé, sans dépendre d'un service tiers. Vous repartez avec une configuration fonctionnelle, durcie (clé pré-partagée, pare-feu), et une méthode de dépannage quand le tunnel refuse de monter. Toutes les commandes ont été déroulées sur un lab réel.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Installer WireGuard depuis les dépôts signés de votre distribution.
- Générer les paires de clés avec les bonnes permissions.
- Configurer un serveur (
wg0.conf, IP forwarding, NAT) et un client. - Valider le tunnel en lisant
wg showet différencier full tunnel et split tunnel. - Durcir l'installation et diagnostiquer un handshake ou un MTU récalcitrant.
Prérequis
Section intitulée « Prérequis »WireGuard fonctionne dans le noyau Linux (module intégré depuis la version 5.6). Vous avez besoin de :
- un serveur Linux avec une IP publique joignable (VPS, machine exposée) et un accès
sudo; - un client Linux pour ce guide (la config est identique sur les autres OS, seul l'outil change) ;
- la possibilité d'ouvrir un port UDP (par défaut 51820) sur le pare-feu et, le cas échéant, la box ou le Security Group cloud ;
- un noyau récent : la commande
lsmod | grep wireguardoumodinfo wireguardconfirme la présence du module.
WireGuard en bref
Section intitulée « WireGuard en bref »WireGuard est un protocole de VPN créé par Jason A. Donenfeld, intégré au noyau Linux, réputé pour sa simplicité (quelques milliers de lignes de code auditables) et ses performances supérieures à OpenVPN. Il chiffre le trafic avec de la cryptographie moderne (Curve25519 pour l'échange de clés, ChaCha20-Poly1305 pour le chiffrement, BLAKE2s pour le hachage) et fonctionne exclusivement en UDP.
Son modèle mental tient en une phrase : chaque machine possède une paire de clés, et deux machines communiquent dès qu'elles connaissent mutuellement leur clé publique. Il n'y a pas de notion de « client » et « serveur » dans le protocole : ce sont des pairs (peers). On parle de serveur simplement parce qu'une machine a une IP fixe, écoute sur un port et route le trafic des autres.
Installer WireGuard
Section intitulée « Installer WireGuard »Les paquets proviennent des dépôts officiels et signés de votre distribution. Aucun script curl | sh n'est nécessaire, et il vaut mieux l'éviter pour un composant réseau privilégié.
sudo apt updatesudo apt install wireguardLe méta-paquet wireguard tire wireguard-tools (les commandes wg et wg-quick) et le module adapté à votre noyau. Sur Debian antérieure à Bullseye, activez d'abord les backports.
sudo dnf install wireguard-toolsLe module est déjà présent dans le noyau ; seul le paquet wireguard-tools (espace utilisateur) est requis.
Vérifiez la version installée. Elle dépend de la distribution : les dépôts stables embarquent souvent une version plus ancienne que l'amont, ce qui est normal et sans danger, wireguard-tools évoluant très peu.
wg --version# wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/Générer les clés
Section intitulée « Générer les clés »Une clé privée ne doit jamais être lisible par d'autres comptes. On fixe donc un umask restrictif avant de générer quoi que ce soit, pour que les fichiers créés soient en permissions 600.
umask 077wg genkey | tee serveur.key | wg pubkey > serveur.pubwg genkeyproduit une clé privée aléatoire en base64.wg pubkeyen dérive la clé publique correspondante.teeenregistre la clé privée tout en la passant àwg pubkey.
Répétez l'opération pour le client (client.key / client.pub). Générez enfin une clé pré-partagée, une couche de chiffrement symétrique supplémentaire partagée par les deux pairs :
wg genpsk > tunnel.pskConfigurer le serveur
Section intitulée « Configurer le serveur »Le serveur se décrit dans /etc/wireguard/wg0.conf, un fichier au format INI. La section [Interface] décrit la machine locale, chaque section [Peer] décrit un pair autorisé.
# /etc/wireguard/wg0.conf (serveur)[Interface]Address = 10.10.0.1/24ListenPort = 51820PrivateKey = <CLE_PRIVEE_SERVEUR>PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADEPostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]PublicKey = <CLE_PUBLIQUE_CLIENT>PresharedKey = <CLE_PARTAGEE>AllowedIPs = 10.10.0.2/32Chaque directive a un rôle précis :
Address: l'IP du serveur dans le réseau privé du tunnel (ici10.10.0.0/24). Choisissez une plage peu commune (évitez192.168.0.0/24ou192.168.1.0/24, qui entrent en collision avec les box domestiques de vos clients).ListenPort: le port UDP d'écoute.PrivateKey: la clé privée du serveur.PostUp/PostDown: des commandes exécutées à la montée et à la descente de l'interface. Ici elles autorisent le forwarding et activent le NAT (masquerade) pour que le trafic des clients ressorte vers Internet ou le LAN. Le jeton%iest remplacé par le nom d'interface (wg0). Remplacezeth0par votre interface réseau publique (ip route get 1.1.1.1vous la donne).AllowedIPscôté serveur : les IP que ce pair a le droit d'utiliser. Pour un client unique, on met son /32.
Le NAT ne fonctionne que si le noyau route entre interfaces. Activez l'IP forwarding de façon persistante :
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-wireguard.confsudo sysctl --systemConfigurer un client et valider
Section intitulée « Configurer un client et valider »Le client déclare le serveur comme pair et pointe vers son Endpoint (l'IP publique et le port du serveur).
# /etc/wireguard/wg0.conf (client)[Interface]Address = 10.10.0.2/24PrivateKey = <CLE_PRIVEE_CLIENT>
[Peer]PublicKey = <CLE_PUBLIQUE_SERVEUR>PresharedKey = <CLE_PARTAGEE>Endpoint = 203.0.113.10:51820AllowedIPs = 10.10.0.0/24PersistentKeepalive = 25Deux directives méritent attention :
Endpoint: l'adresse publique du serveur. Un client peut se déplacer sans la préciser côté serveur, WireGuard apprend son adresse au premier paquet valide.PersistentKeepalive = 25: le client envoie un petit paquet toutes les 25 secondes pour garder ouvert le mapping de son NAT. Sans lui, un client derrière une box devient injoignable après quelques dizaines de secondes d'inactivité. On ne le met que sur le pair réellement derrière un NAT.
Montez le tunnel des deux côtés avec wg-quick, qui lit le fichier et crée l'interface :
sudo wg-quick up wg0# [#] ip link add wg0 type wireguard# [#] wg setconf wg0 /dev/fd/63# [#] ip -4 address add 10.10.0.1/24 dev wg0# [#] ip link set mtu 1420 up dev wg0Vérifiez l'état avec wg show. La ligne décisive est latest handshake : si elle est renseignée, le tunnel chiffré est établi.
sudo wg show# interface: wg0# public key: DoqtUJ4HD1prS9UbOBE8C4D7a/Yz6uq2tVKCy/B09wc=# listening port: 51820# peer: DVJfOZZrLnpgnUPf9laBkAOvDixxU+yE+mHwbInD/gQ=# endpoint: 203.0.113.50:41466# allowed ips: 10.10.0.2/32# latest handshake: 2 seconds ago# transfer: 660 B received, 476 B sentUn ping à travers le tunnel confirme la connectivité :
ping -c 3 10.10.0.1# 3 packets transmitted, 3 received, 0% packet lossPour lancer le tunnel au démarrage, activez l'unité systemd fournie par le paquet :
sudo systemctl enable --now wg-quick@wg0Full tunnel ou split tunnel
Section intitulée « Full tunnel ou split tunnel »Côté client, la directive AllowedIPs joue un double rôle : elle sert à la fois de table de routage (quel trafic entre dans le tunnel) et de filtre (quel trafic est accepté en retour). Sa valeur change tout :
Valeur d'AllowedIPs | Comportement | Usage |
|---|---|---|
10.10.0.0/24 | Split tunnel : seul le réseau du VPN passe par le tunnel | Accéder à un serveur ou un LAN distant |
0.0.0.0/0, ::/0 | Full tunnel : tout le trafic passe par le VPN | Masquer son IP, sortir via le serveur |
Sécurité et durcissement
Section intitulée « Sécurité et durcissement »WireGuard est sûr par conception, mais l'installation par défaut ne bloque rien. Quelques mesures complètent la configuration :
- Clé pré-partagée : déjà en place dans ce guide via
PresharedKey, elle ajoute une couche symétrique qui renforce la résistance aux attaques futures, y compris post-quantiques. - Pare-feu : n'ouvrez que le port d'écoute UDP. Sur le serveur, autorisez
51820/udpen entrée. Ouvrir le port (chaîne INPUT) et autoriser le routage (chaîne FORWARD) sont deux choses distinctes : les deux sont nécessaires pour un serveur passerelle. - Fuites DNS : en full tunnel, ajoutez une directive
DNS =côté client pour forcer le résolveur, et vérifiez qu'aucune requête ne s'échappe hors du tunnel. - Moindre privilège : le répertoire
/etc/wireguarddoit rester en700et les fichiers de config en600. Ne versionnez jamais une clé privée.
Dépannage
Section intitulée « Dépannage »La plupart des problèmes se diagnostiquent en quelques minutes avec la bonne méthode. Commencez toujours par confirmer, au tcpdump, que les paquets arrivent côté serveur : cela sépare un problème de réseau ou de pare-feu d'un problème de configuration.
sudo tcpdump -ni eth0 udp port 51820# IP 203.0.113.50.47059 > 203.0.113.10.51820: UDP, length 148# IP 203.0.113.10.51820 > 203.0.113.50.47059: UDP, length 92Un paquet de 148 octets (initiation du handshake) suivi d'une réponse de 92 octets signe un échange réussi. Si vous ne voyez que des paquets sortants sans réponse, le problème est en amont du serveur (port fermé, mauvaise IP).
| Symptôme | Cause probable | Correctif |
|---|---|---|
latest handshake reste vide | Clés inversées, ou clé mal copiée | Vérifier que la PublicKey d'un pair est bien la clé publique de l'autre |
Aucun paquet au tcpdump serveur | Port UDP fermé, mauvais Endpoint | Ouvrir 51820/udp, corriger l'IP publique |
| Handshake OK mais rien ne route | ip_forward désactivé, NAT absent | Activer net.ipv4.ip_forward, vérifier le masquerade |
| SSH gèle, HTTPS charge à moitié | MTU trop grand (PPPoE, 4G) | Baisser le MTU de wg0 (voir ci-dessous) |
| Tunnel meurt après 30 s d'inactivité | Client derrière NAT sans keepalive | Ajouter PersistentKeepalive = 25 côté client |
| Handshake rejeté malgré tout bon | Horloges désynchronisées | Vérifier NTP des deux côtés |
Le MTU est le piège le plus vicieux : le tunnel semble marcher (ping, DNS, petites pages), mais les gros paquets sont silencieusement jetés. WireGuard ajoute environ 60 à 80 octets d'en-tête, d'où un MTU par défaut de 1420. Sur une connexion PPPoE ou mobile, descendez à 1412, et en dernier recours à 1280 (le minimum garanti sur tout chemin) :
sudo ip link set mtu 1280 dev wg0Si le blocage disparaît, fixez la valeur dans wg0.conf avec la directive MTU.
Quand passer à un VPN mesh
Section intitulée « Quand passer à un VPN mesh »Ce montage est parfait pour quelques machines. Mais gérer les clés à la main, déclarer chaque pair chez chaque autre et router entre sites devient vite pénible dès que le nombre de nœuds grandit. C'est le moment de passer à une surcouche qui automatise WireGuard.
Ces outils reposent tous sur WireGuard et ajoutent un control plane : distribution automatique des clés, découverte des pairs, traversée de NAT et contrôle d'accès. Vous gardez le moteur que vous venez d'apprendre, sans la corvée d'administration.
FAQ : questions fréquentes sur WireGuard
Section intitulée « FAQ : questions fréquentes sur WireGuard »| Critère | WireGuard | OpenVPN |
|---|---|---|
| Vitesse | Plus rapide | Plus lent |
| Configuration | Simple (un fichier INI) | Plus complexe |
| Transport | UDP uniquement | UDP ou TCP |
| Code | Quelques milliers de lignes | Beaucoup plus volumineux |
ListenPort dans la section [Interface].Ce port doit être ouvert en entrée sur le pare-feu du serveur (51820/udp) et, le cas échéant, sur la box ou le Security Group cloud. Un port fermé est la cause la plus fréquente d'un handshake qui ne s'établit jamais.sudo apt update
sudo apt install wireguard
Le méta-paquet wireguard installe wireguard-tools (les commandes wg et wg-quick) et le module adapté au noyau. Sur Fedora ou RHEL 9+, utilisez sudo dnf install wireguard-tools. Évitez les scripts curl | sh pour un composant réseau privilégié.AllowedIPs côté client, qui sert à la fois de table de routage et de filtre.- Split tunnel (
AllowedIPs = 10.10.0.0/24) : seul le réseau du VPN passe par le tunnel, le reste du trafic sort normalement. Idéal pour accéder à un serveur ou un LAN distant. - Full tunnel (
AllowedIPs = 0.0.0.0/0, ::/0) : tout le trafic passe par le VPN. Utile pour masquer son IP.
PersistentKeepalive fait envoyer au pair un petit paquet authentifié à intervalle régulier, en général toutes les 25 secondes.Son but : garder ouvert le mapping NAT d'un pair situé derrière une box ou un routeur. Les NAT ferment les associations UDP inactives après quelques dizaines de secondes (souvent 30). Sans keepalive, le serveur ne sait plus comment joindre le client dès qu'il se tait.On ne l'active que sur le pair réellement derrière un NAT (typiquement le client), pas côté serveur à IP publique fixe.wg show affiche un latest handshake vide, procédez dans l'ordre :- tcpdump d'abord :
sudo tcpdump -ni eth0 udp port 51820. Les paquets arrivent-ils au serveur ? Cela sépare un problème réseau d'un problème de configuration. - Clés : la
PublicKeyd'un pair doit être la clé publique de l'autre, sans espace ni retour à la ligne parasite. C'est l'erreur numéro un. - Port :
51820/udpouvert en entrée sur le pare-feu et la box. - Endpoint : IP publique et port corrects côté client.
- Horloge : un décalage NTP fait rejeter le handshake.
À retenir
Section intitulée « À retenir »- WireGuard vit dans le noyau Linux, chiffre en ChaCha20-Poly1305 et fonctionne en UDP uniquement.
- Le modèle est pair à pair : chaque machine a une clé privée, et deux pairs se parlent dès qu'ils connaissent leur clé publique mutuelle.
- Un serveur passerelle a besoin de trois choses : IP forwarding, NAT (masquerade) et le port UDP ouvert.
AllowedIPsdécide du split tunnel (/24) ou du full tunnel (0.0.0.0/0) et sert aussi de filtre : attention aux plages qui se chevauchent.PersistentKeepalive = 25garde vivant un pair derrière un NAT.- Diagnostic :
tcpdumpd'abord (les paquets arrivent-ils ?), puis clés, port,AllowedIPs, et enfin le MTU pour les blocages partiels. - Au-delà de quelques nœuds, une surcouche mesh (Tailscale, NetBird) automatise la gestion des clés et des pairs.