NetworkGuide

VPN auto-hébergé avec WireGuard : guide complet

Sur cette page
  1. Pourquoi WireGuard, et pas OpenVPN ou IPsec, en 2026
  2. Choisissez votre topologie : split contre full-tunnel
  3. Étape 1 : installation du serveur (VPS Debian / Ubuntu)
  4. Étape 2 : générer les clés et écrire la config
  5. Étape 3 : config client sous Linux, macOS, Windows, mobile
  6. Étape 4 : firewall, NAT et DNS
  7. Sous le capot : le handshake WireGuard
  8. Durcissement et exploitation
  9. Pièges courants
  10. Puis-je utiliser un seul fichier de config pour le split et le full-tunnel ?

Monter un VPN WireGuard auto-hébergé, c'est le premier setup VPN que je prends vraiment plaisir à faire tourner. L'ensemble tient en moins de 4 000 lignes de code noyau, il cause ChaCha20-Poly1305 par-dessus UDP, et le tunnel se monte en un seul aller-retour depuis un fichier de config qui tient sur un écran. Voilà comment je le construis : serveur sur un VPS à 5 EUR, clients sous Linux, macOS, Windows, iOS et Android. La plupart des lignes vont aux deux décisions qui finissent par vous mordre, split-tunnel contre full-tunnel, et au fait de garder un laptop ou un téléphone derrière le NAT maison sans laisser le tunnel tomber. Les morceaux firewall, sysctl et DNS ont droit à un coup d'œil aussi.

The short answer

Un VPN WireGuard auto-hébergé tourne sur n'importe quel VPS à 5 EUR avec une décision en amont : le split-tunnel (AllowedIPs = 10.0.0.0/24) n'envoie que votre LAN maison, le full-tunnel (AllowedIPs = 0.0.0.0/0, ::/0) envoie tout. Générez une paire de clés Curve25519 par pair, écrivez wg0.conf, activez le forwarding IP et le MASQUERADE, et le tunnel est debout.

~4 000 lignesde code noyau
5 EUR/moisde VPS suffisent
1-RTTpour se connecter
Carte réponse pour un VPN WireGuard auto-hébergé : VPS à 5 EUR, split contre full-tunnel décidé par une ligne AllowedIPs, clés Curve25519, NAT et DNS.
Un seul champ de config décide de tout. Le split-tunnel n'envoie que les destinations que vous listez, le full-tunnel pousse tout 0.0.0.0/0 à travers le VPS. PNG

J'ai monté pas mal de VPN dans ma vie. WireGuard est le premier que je prends vraiment plaisir à faire tourner, et honnêtement je ne m'attendais pas à ressentir ça pour un VPN. L'ensemble tient en moins de 4 000 lignes de code noyau. Il cause ChaCha20-Poly1305 par-dessus UDP, et le tunnel se monte en un seul aller-retour à partir d'un fichier de config qui tient sur un écran. Voilà donc comment je construis la version auto-hébergée : serveur sur un VPS à 5 EUR, clients sous Linux, macOS, Windows, iOS et Android. La plupart des lignes qui suivent vont aux deux décisions qui finissent par vous mordre, split-tunnel contre full-tunnel, et au fait d'empêcher un laptop ou un téléphone derrière le NAT de la maison de laisser le tunnel tomber en douce. La crypto qu'il y a dessous a droit à un coup d'œil aussi. Tout comme les morceaux firewall, sysctl et DNS, parce que ce sont eux qui séparent le « ça marche sur mon laptop » d'un tunnel toujours debout six semaines plus tard.

Pourquoi WireGuard, et pas OpenVPN ou IPsec, en 2026

Je garde quelques raisons en tête, à peu près dans l'ordre où vous allez les ressentir. D'abord, la taille du code. WireGuard tourne autour de 4 000 lignes. OpenVPN est plus proche de 600 000, et strongSwan / IPsec se situe vers 400 000. Moins de code, c'est moins de surface d'attaque et moins de CVE. C'est aussi un audit qu'un humain peut réellement boucler d'une traite. Ensuite, le débit. Le chemin de données vit dans le noyau et utilise ChaCha20-Poly1305, moins coûteux qu'AES sur n'importe quel CPU sans AES-NI, du coup sur un VPS pas cher je vois couramment 2 à 4 fois ce qu'OpenVPN me donne sur la même machine. Et puis il y a celle que je n'ai vraiment appréciée qu'après avoir vécu un moment avec : le roaming. WireGuard associe un pair à sa clé publique, pas à son IP, donc quand mon téléphone saute du Wi-Fi à la 4G le tunnel continue, point. OpenVPN coupe la session. IPsec hoquette. WireGuard ne cligne même pas de l'œil.

Ce que vous lâchez en échange, c'est de la souplesse. Pas de nom d'utilisateur ni de mot de passe. Pas de certificats, pas de PKI. Vous distribuez des clés publiques exactement comme vous distribuez des clés SSH, par un canal en qui vous avez déjà confiance. Pour un homelab ou une petite équipe, je vois ça comme un gain, une pièce mobile de moins susceptible de casser. Maintenant, si vous câblez cinq mille postes, ce même minimalisme est précisément la raison pour laquelle vous mettriez Tailscale ou Cloudflare WARP par-dessus WireGuard plutôt que d'éditer des configs brutes à la main jusqu'à loucher.

Choisissez votre topologie : split contre full-tunnel

Tranchez ça en premier, avant de taper la moindre ligne. La config client se plie autour de la réponse, et changer d'avis plus tard veut dire tout réécrire.

QuestionSplit-tunnelFull-tunnel
Qu'est-ce que vous tunnelez ?Seulement les destinations que vous listez (LAN maison, SaaS interne, jump host)Tout, y compris Netflix et votre banque
Valeur de AllowedIPs10.0.0.0/24 (ou votre plage privée)0.0.0.0/0, ::/0
DébitPlein débit FAIPlafonné à l'uplink du VPS
Risque de fuite DNSRésolveur local, fuites possiblesRésolveur VPN, privé par conception
Déblocage géoNonOui
Idéal pourAccès distant à la maison / au bureauWi-Fi non fiable, réseaux hostiles

Et vous n'êtes pas obligé de choisir une fois pour toutes non plus. Je garde deux profils sur mon laptop et je bascule de l'un à l'autre selon l'endroit où je suis assis ce jour-là. Vous voulez du plus fin que ça ? Les apps macOS et iOS savent router par application, donc seuls les outils de boulot passent par le tunnel.

Étape 1 : installation du serveur (VPS Debian / Ubuntu)

Prenez n'importe quel VPS à 5 EUR avec une IPv4 publique propre. J'ai fait tourner ça chez Hetzner, OVH, DigitalOcean, Vultr, et tous font l'affaire. La machine ne transpire même pas. Debian 12 ou Ubuntu 24.04 LTS, un vCPU, 1 Go de RAM, et c'est largement suffisant. Mettez-la à jour, installez WireGuard, puis verrouillez le répertoire de config avant que quoi que ce soit d'autre ait une chance d'y atterrir.

sudo apt update
sudo apt install -y wireguard wireguard-tools qrencode iptables-persistent
sudo install -d -m 0700 /etc/wireguard
cd /etc/wireguard

Un truc qui déroute les gens venant d'OpenVPN : il n'y a pas de démon ici. Aucun. WireGuard est intégré à tout noyau >= 5.6, donc la seule chose que vous « démarrez », c'est wg-quick, l'unité systemd qui lit votre fichier de config et monte l'interface. C'est tout le service, croyez-le ou non.

Étape 2 : générer les clés et écrire la config

Une paire de clés par pair. Ne partagez jamais la même entre deux clients (on verra plus loin pourquoi ça fait mal). wg crache des paires Curve25519.

# on the server
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
wg genkey | tee client1.key | wg pubkey > client1.pub

# inspect (private keys never leave the machine they were generated on)
ls -l /etc/wireguard/
cat server.pub client1.pub

Maintenant écrivez la config serveur dans /etc/wireguard/wg0.conf. Le bloc [Interface] contient la clé privée du serveur lui-même et son adresse sur le tunnel. Ensuite vous avez un bloc [Peer] par client, et chacun associe la clé publique de ce client aux IP de tunnel qu'il a le droit d'utiliser. Voilà le détail que les gens ratent : cette ligne AllowedIPs fait double emploi. C'est du routage et une liste de contrôle d'accès en même temps. Soyez précis avec.

[Interface]
PrivateKey = <contents of server.key>
Address    = 10.8.0.1/24
ListenPort = 51820
SaveConfig = false
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]
# laptop
PublicKey  = <contents of client1.pub>
AllowedIPs = 10.8.0.2/32

Activez le forwarding IP ensuite. Le serveur route pour ses clients désormais, donc sautez cette étape et le tunnel se monte puis ne mène précisément nulle part. Puis montez l'interface.

sudo sysctl -w net.ipv4.ip_forward=1
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-wg.conf
sudo systemctl enable --now wg-quick@wg0
sudo wg show wg0

Étape 3 : config client sous Linux, macOS, Windows, mobile

Bonne nouvelle. Le client tient dans un seul fichier, et il a la même tête que vous soyez sous Linux, sur un Mac, sur un téléphone, peu importe. Ce que vous voyez ci-dessous, c'est la variante split-tunnel. Elle ne pousse que le LAN maison à travers WireGuard et laisse le reste de votre trafic tranquille. Vous voulez plutôt la version full-tunnel ? Remplacez AllowedIPs par 0.0.0.0/0, ::/0. C'est tout.

[Interface]
PrivateKey = <contents of client1.key>
Address    = 10.8.0.2/24
DNS        = 1.1.1.1, 9.9.9.9
# DNS        = 10.0.0.1   # use the LAN resolver instead, on split-tunnel

[Peer]
PublicKey           = <contents of server.pub>
Endpoint            = vps.example.com:51820
AllowedIPs          = 10.0.0.0/24, 10.8.0.0/24
PersistentKeepalive = 25

Cette ligne PersistentKeepalive = 25 gagne sa place. Elle envoie un minuscule paquet UDP de 32 octets toutes les 25 secondes, juste assez souvent pour empêcher un routeur domestique d'oublier le mapping NAT et de tuer votre tunnel en silence. Sur un poste de bureau filaire avec une vraie IP publique ? Virez-la, ce n'est que du bruit là. Sur tout ce qui se balade, un laptop ou un téléphone, laissez-la. À chaque fois, sans exception.

Par plateforme, voilà comment ça se passe :

  • Linux : déposez le fichier dans /etc/wireguard/wg0.conf, puis sudo wg-quick up wg0 et vous êtes connecté. Vous voulez que ça survive aux reboots ? systemctl enable --now wg-quick@wg0.
  • macOS : récupérez l'app WireGuard sur l'App Store et importez le fichier avec « Add Tunnel from File… ». La clé file dans le trousseau système, donc vous ne la laissez pas traîner en clair à la vue de n'importe qui.
  • Windows : lancez l'installeur WireGuard.exe depuis wireguard.com, cliquez sur « Add Tunnel », collez la config. Le driver basé sur TunSafe vient avec, donc il n'y a rien d'autre à installer.
  • iOS / Android : c'est la méthode classe. Sur le serveur, lancez qrencode -t ansiutf8 < client1.conf, pointez la caméra de l'app WireGuard sur le pâté de carrés, et toute la config atterrit sur le téléphone. Pas besoin de taper au pouce une clé de 44 caractères comme un sauvage.
Terminal générant une paire de clés Curve25519 WireGuard avec wg genkey, puis montant l'interface avec wg-quick up wg0 et la vérifiant avec wg show.
Générez la paire de clés, montez wg0, puis wg show confirme le handshake. Tout le service tient en une commande wg-quick. PNG

Étape 4 : firewall, NAT et DNS

Trois choses doivent s'accorder entre elles ici. Quand le tunnel « marche mais n'a pas d'Internet », c'est presque toujours l'une d'elles qui est déphasée : le forwarding IP du noyau, le NAT iptables / nftables, votre DNS. La config serveur plus haut gère déjà le NAT avec cette règle POSTROUTING -j MASQUERADE. Au-delà de ça, deux règles de plus valent votre temps :

  • Jetez les paquets forwardés qui ne viennent pas réellement de l'intérieur du tunnel : iptables -A FORWARD -i wg0 ! -s 10.8.0.0/24 -j DROP. C'est ce qui empêche un client mal configuré de revendiquer l'adresse d'un autre pair et de traverser votre serveur comme s'il était chez lui.
  • Resserrez l'exposition au niveau du firewall du fournisseur cloud lui-même, pas seulement sur la machine. Laissez entrer l'UDP 51820 depuis n'importe où, mais cloutez le SSH sur le TCP 22 (ou le port où vous l'avez déplacé) aux plages d'IP depuis lesquelles vous administrez réellement. Aucune raison d'agiter votre port SSH devant tout l'Internet.

Le DNS, c'est là que se produisent les fuites gênantes. Si vous êtes en full-tunnel, mettez DNS = 1.1.1.1 dans le bloc interface du client. Sinon l'OS continue gaiement à demander au résolveur du Wi-Fi du café ce que vous cherchez, ce qui, vous savez, ruine plutôt l'intérêt du tunnel. En split-tunnel vous voulez l'inverse : pointez le DNS vers votre résolveur maison (10.0.0.1 ou là où vit le vôtre) pour que vos noms d'hôtes internes continuent de résoudre.

Sous le capot : le handshake WireGuard

Vous n'avez besoin de rien savoir de tout ça pour faire tourner WireGuard. Mais c'est franchement élégant, et ça explique pas mal du comportement que vous allez observer. Tout le handshake tient en deux messages UDP, faits en un seul aller-retour. À partir de là, les deux côtés partagent une clé symétrique, et chaque paquet après ça est emballé dans une enveloppe ChaCha20-Poly1305 authentifiée de 16 octets.

Le handshake 1-RTT établit une clé symétrique fraîche avec le pattern Noise IK par-dessus Curve25519. Ensuite le plan de données fait tourner ChaCha20-Poly1305 avec un compteur par paquet, du coup personne ne peut rejouer votre trafic, et c'est la table de cryptokey-routing du noyau qui détermine à quel pair appartient un paquet donné. Les clés tournent toutes les 120 s ou tous les 2^30 messages, selon ce qui arrive en premier. Donc même une clé de session capturée a une durée de vie courte.

Quelques jolies choses tombent toutes seules de ce design, gratuitement. Un pair est sa clé publique, pas un nom DNS, pas une IP, donc l'identité ne dérive jamais. Le serveur reste aussi muet comme une tombe face aux inconnus. Scannez son port avec la mauvaise clé et vous n'obtenez rien en retour, ce qui veut dire qu'un scan de ports ne peut même pas confirmer qu'il y a un endpoint WireGuard posé là. C'est peut-être juste moi, mais je trouve celle-là vraiment rassurante sur un VPS public, plus que les chiffres de débit honnêtement. Et comme toute la crypto tourne dans le noyau, un seul cœur remplira sans problème un lien gigabit.

Durcissement et exploitation

  • Gardez l'écoute sur l'interface publique uniquement. Si votre VPS a une seconde carte réseau privée pour le trafic interne, ne laissez pas ListenPort répondre dessus. Clôturez-la avec des règles de firewall pour que le tunnel ne vive que là où vous l'attendez.
  • Surveillez les compteurs de handshake. wg show vous donne l'heure du dernier handshake, les totaux de transfert, les pairs configurés, tout d'un coup. Je le mets en cron toutes les minutes et j'alerte dès que le dernier handshake d'un pair dépasse les 300 secondes. C'est en général votre premier signe que quelque chose cloche, bien avant qu'un utilisateur pense à se plaindre.
  • Faites tourner les clés une fois par an. Curve25519 ne va pas s'user. Ce sont vos habitudes qui rouillent. Une réémission annuelle entretient la mémoire musculaire. Basculez tous les clients le même jour et faites en sorte que les vieilles clés échouent en mode fermé.
  • Durcissez la machine en dessous. Le tunnel n'est jamais plus sûr que la machine qui le fait tourner, alors déroulez notre checklist de durcissement du noyau Linux. Faites attention à la section réseau, et à glisser kernel.modules_disabled = 1 une fois le boot terminé.
  • Sauvegardez les clés. Le reste ne compte pas. /etc/wireguard/*.key et leurs fichiers .conf correspondants sont le VPN. Chiffrez cette poignée de fichiers et planquez-les hors site quelque part. Si le VPS s'évapore demain, tout le reste n'est qu'une réinstallation de cinq minutes.

Pièges courants

  • Le tunnel n'arrête pas de mourir au bout de 25 secondes environ. Neuf fois sur dix, il n'y a pas de PersistentKeepalive sur le client. La dixième fois ? Un routeur paranoïaque qui jette l'UDP inactif au bout de 15. Donc si le keepalive est déjà là, descendez-le simplement à 15 et passez à autre chose.
  • Le tunnel est debout mais il n'y a pas d'Internet. Le classique. Soit le serveur n'a jamais reçu net.ipv4.ip_forward = 1, soit la règle MASQUERADE n'a pas survécu à un reboot parce que iptables-persistent n'était pas réellement activé. Vérifiez-le tout de suite avec iptables -t nat -L POSTROUTING.
  • Fuite DNS en full-tunnel. Plein de distros continuent en douce de parler au stub systemd-resolved sur 127.0.0.53 quoi que vous leur ayez dit. Corrigez ça en mettant DNS = 1.1.1.1 dans la config client pour que wg-quick réécrive resolv.conf à votre place. Ou coupez carrément le stub.
  • L'IPv6 qui se faufile par la porte de derrière. Mettez AllowedIPs = 0.0.0.0/0, oubliez son partenaire ::/0, et votre trafic v6 sort tranquillement en clair pendant que vous restez là à vous croire en full-tunnel. Écrivez toujours la paire.
  • L'IP publique du VPS qui change sous vos pieds. WireGuard s'en fiche vraiment. L'Endpoint de votre client, lui, non, si vous avez codé l'IP en dur. Mettez plutôt un nom d'hôte DDNS dedans et le problème disparaît tout seul.
  • Réutiliser une même clé privée sur deux clients. Ne le faites pas. Le handshake retient le client qui a atteint le serveur en premier et laisse l'autre fixer des timeouts qu'il ne comprend pas. Une paire de clés par pair, pas de raccourci. C'est le piège dans lequel je vois les gens tomber plus que tout autre.

Puis-je utiliser un seul fichier de config pour le split et le full-tunnel ?

Non. Chaque profil correspond à un mode, et l'app ne vous laissera pas chevaucher les deux dans un seul fichier. La méthode propre, c'est de garder deux fichiers, wg-split.conf et wg-full.conf, plus un petit script qui échange celui qui est en service. Sur un téléphone c'est encore plus facile. Ajoutez les deux comme tunnels séparés dans l'app WireGuard et tapez simplement pour basculer de l'un à l'autre.

Questions fréquentes

En quoi WireGuard est-il différent de Tailscale ?

Même moteur, voiture différente. Tailscale fait tourner WireGuard en dessous et y boulonne ce que WireGuard laisse délibérément de côté : un service de coordination, une identité SSO, des ACL, de la traversée de NAT via les relais DERP, un panneau d'admin web. Vous avez une flotte de machines qui doivent se trouver entre elles avec quasiment zéro config ? C'est toute la raison d'être de Tailscale. Mais pour un seul serveur que vous possédez et une poignée de clients que vous montez à la main, je prendrais du WireGuard brut à chaque fois. C'est plus simple, et il n'y a pas de tiers dans la boucle qui puisse passer une mauvaise journée à votre place.

Puis-je faire tourner WireGuard sur un Raspberry Pi comme serveur ?

Oui, et honnêtement c'est une chouette petite machine pour ça. Un Pi 4 remplira sa carte gigabit de trafic WireGuard sans broncher. Ce qu'il faut surveiller, ce n'est pas la performance, c'est la porte d'entrée. Vous percez l'UDP 51820 depuis l'Internet ouvert droit dans votre réseau domestique. Alors forwardez seulement ce port-là, rien d'autre, et mettez en place les règles de firewall du guide pour qu'un pair mal configuré ne puisse pas se mettre à spoofer des adresses partout sur votre LAN.

WireGuard est-il sûr face aux ordinateurs quantiques ?

Pas tout seul, non. Curve25519 n'est pas post-quantique, donc la réponse honnête, c'est qu'un futur ordinateur quantique assez gros pour compter pourrait revenir en arrière et casser des sessions que quelqu'un a enregistrées aujourd'hui. Le problème du « harvest now, decrypt later », comme on l'appelle. Les mainteneurs ont publié une extension post-quantique, et des acteurs comme Mullvad et Cloudflare superposent déjà un échange de clés hybride PQ par-dessus WireGuard. Pour les menaces contre lesquelles la plupart d'entre nous se défendent vraiment en 2026, WireGuard tout nu fait l'affaire, je pense. Vous gardez des secrets qui doivent le rester pendant vingt ans ? C'est là que je regarderais de plus près les options hybrides.

Combien de pairs un seul serveur peut-il gérer ?

Plusieurs centaines sans que le serveur le remarque même. Ce qui vous manque en premier, ce ne sont pas les emplacements de pairs, c'est le CPU pour ChaCha20-Poly1305, et un cœur avalera environ 1 Gbps de trafic cumulé de pairs avant que ça devienne un souci. Poussez au-delà d'un millier de pairs actifs, par contre, et la douleur cesse d'être le débit. Ça devient gérer un fichier de config géant à la main. C'est le moment où je basculerais vers une couche de coordination comme Tailscale ou Netbird et où j'arrêterais de me battre.

WireGuard fonctionne-t-il derrière du carrier-grade NAT (CGNAT) ?

Côté client, oui. Le client ouvre la session UDP en sortant, donc le CGNAT ne lui met pas de bâton dans les roues. Le hic, c'est le serveur. Il doit être joignable, ce qui veut dire une vraie IP publique routable. Là où ça part en vrille, c'est quand les deux bouts sont derrière du CGNAT et qu'aucun ne peut être joint directement. Vous regardez alors un relais au milieu (DERP, ZeroTier, le projet FRP) ou un service de coordination comme Tailscale qui perce pour vous.