🎯 Compétences acquises
Ton propre VPN WireGuard
🛠️ Le Tutoriel Complet
Serveur VPN WireGuard sur Ubuntu
La métaphore d'OWL : Le Tunnel Privé
Un VPN, c'est un tunnel privé et chiffré au milieu d'Internet public. Imagine que tes données voyagent dans une valise diplomatique scellée — personne ne peut l'ouvrir même si elle passe entre mille mains. WireGuard, c'est la version moderne de cette valise : ultra-légére, ultra-rapide, et mathématiquement inviolable avec les outils actuels.
Le principe de WireGuard repose sur des paires de clés (comme SSH) : le serveur connaît ta clé publique, toi tu gardes ta clé privée. Quand tu te connectes, les deux parties prouvent mutuellement qu'elles détiennent les bonnes clés sans jamais s'échanger les clés privées. élégant et imparable.
Pour le homelab d'OWL : le serveur WireGuard tourne sur le NAS/PC Ubuntu à la maison. Depuis l'extérieur (café, hôtel, bureau), le téléphone se connecte au VPN, et hop — il est virtuellement à la maison, avec accès — tous les services internes.
Architecture WireGuard — Homelab
🌐 Internet
é
— Port UDP 51820
?
+--------------------------------------------+
é Serveur Ubuntu (chez toi) é
é IP publique: 88.123.45.67 é
é WireGuard Server — wg0 : 10.0.0.1/24 é
é é
é +-- Jellyfin 192.168.1.10:8096 é
é +-- Nextcloud 192.168.1.10:8080 é
é +-- Portainer 192.168.1.10:9000 é
+--------------------------------------------+
— — ?
— tunnel VPN — é
📱 Pixel 9 💻 PC Travail 💻 Laptop
10.0.0.2 10.0.0.3 10.0.0.4
⚠️ Prérequis avant de commencer
- 1.IP publique à ton serveur doit étre joignable depuis Internet (IP fixe ou DDNS si IP dynamique)
- 2.Port UDP 51820 ouvert — sur ton routeur (règle NAT/redirection de port), ET dans UFW
- 3.Ubuntu 26.04+ — WireGuard est dans le noyau depuis Linux 5.6, aucun module tiers requis
1. Installer WireGuard sur Ubuntu
sudo apt update && sudo apt install -y wireguard
# Vérifier la version
wg --version
wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/
# Créer le dossier de configuration (avec permissions restreintes)
sudo mkdir -p /etc/wireguard
sudo chmod 700 /etc/wireguard
2. Générer les Paires de Clés
Chaque appareil (serveur + chaque client) a sa propre paire de clés. Tu dois générer une paire pour le serveur, et une paire pour chaque client (téléphone, PC, etc.).
cd /etc/wireguard
wg genkey | sudo tee server_private.key | wg pubkey | sudo tee server_public.key
# Afficher les clés (é noter précieusement)
sudo cat server_private.key
YHtK5Z3mVq2BuNnwpDLFrC4mJx8RoGiPeKlSqWvA3kI= — garder SECRÈTE
sudo cat server_public.key
k/v3P8+aP4Y2bNxLmQwRs5tUgFjHdOeXcViBlZnMoKw= — à distribuer aux clients
# === CLIENT 1 : Téléphone === Même procédure
wg genkey | sudo tee phone_private.key | wg pubkey | sudo tee phone_public.key
# === CLIENT 2 : PC Bureau ===
wg genkey | sudo tee pc_private.key | wg pubkey | sudo tee pc_public.key
# Sécuriser les fichiers (clés privées lisibles uniquement par root)
sudo chmod 600 /etc/wireguard/*.key
ls -la /etc/wireguard/
Ne partage JAMAIS les fichiers *_private.key. La clé privée ne quitte jamais l'appareil qui l'a générée. Seules les clés publiques (*_public.key) peuvent étre échangées.
3. Configurer le Serveur WireGuard
SERVER_PRIVATE=$(sudo cat /etc/wireguard/server_private.key)
PHONE_PUBLIC=$(sudo cat /etc/wireguard/phone_public.key)
PC_PUBLIC=$(sudo cat /etc/wireguard/pc_public.key)
# Identifier l'interface rôleau principale
ip route | grep default | awk '{print $5}'
enp3s0 — noter ce nom (peut étre eth0, ens3, etc.)
Créer /etc/wireguard/wg0.conf :
[Interface]
# Adresse IP du serveur dans le tunnel VPN
Address = 10.0.0.1/24
# Port d'écoute WireGuard
ListenPort = 51820
# Clé privée du serveur
PrivateKey = YHtK5Z3mVq2BuNnwpDLFrC4mJx8RoGiPeKlSqWvA3kI=
# Activer le routage IP (pour que les clients accèdent au LAN)
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o enp3s0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o enp3s0 -j MASQUERADE
# -------------------------------------
# Client 1 : Téléphone
[Peer]
PublicKey = (clé publique du téléphone)
AllowedIPs = 10.0.0.2/32
# Client 2 : PC Bureau
[Peer]
PublicKey = (clé publique du PC bureau)
AllowedIPs = 10.0.0.3/32
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
net.ipv4.ip_forward = 1
# Démarrer WireGuard
sudo systemctl enable --now wg-quick@wg0
# Vérifier le statut
sudo wg show
interface: wg0
public key: k/v3P8+aP4Y2bNxLmQwRs5tUgFjHdOeXcViBlZnMoKw=
private key: (hidden)
listening port: 51820
# Ouvrir le port dans UFW
sudo ufw allow 51820/udp
sudo ufw reload
4. Configurer les Clients
Chaque client a un fichier de configuration .conf → importer dans l'application WireGuard.
Config pour le Téléphone (phone.conf)
# Adresse IP du téléphone dans le tunnel
Address = 10.0.0.2/24
# DNS — utiliser via le VPN (ex: resolver local ou Cloudflare)
DNS = 1.1.1.1
# Clé privée du téléphone
PrivateKey = (phone_private.key)
[Peer]
# Clé publique du SERVEUR
PublicKey = k/v3P8+aP4Y2bNxLmQwRs5tUgFjHdOeXcViBlZnMoKw=
# IP publique du serveur + port WireGuard
Endpoint = 88.123.45.67:51820
# Tout le trafic passe par le VPN (0.0.0.0/0 = tout)
# Pour accès homelab uniquement, utilise 10.0.0.0/24, 192.168.1.0/24
AllowedIPs = 0.0.0.0/0
# Maintenir la connexion active (utile derrière un NAT)
PersistentKeepalive = 25
Split Tunnel vs Full Tunnel — Quel AllowedIPs choisir
0.0.0.0/0 — Full Tunnel
TOUT le trafic passe par le VPN. Protège ta navigation sur Wi-Fi public. Peut ralentir la connexion.
10.0.0.0/24, 192.168.1.0/24
Split tunnel : seul le trafic vers ton homelab passe par le VPN. Navigation normale en direct.
Générer un QR Code pour l'appli mobile
sudo apt install -y qrencode
# Générer le QR code depuis la config client
qrencode -t ansiutf8 < /etc/wireguard/phone.conf
ééééééééééééééééééééééééééééééééé
ééééééééééééééééééééééééééééééééé
éééé _____ é_é__ éé_ _____ éééé
éééé — — à é_ééé — à — éééé
éééé é___é ééé_ééé_ é___é éééé
...
# Sur l'appli WireGuard mobile :
# — "+" — "Scanner depuis QR code" — scanner l'écran
5. Gérer les Connexions — Commandes wg
sudo wg show # voir l'état complet : peers connectés, trafic
sudo wg show wg0 peers # lister les clients
sudo systemctl status wg-quick@wg0
interface: wg0
public key: k/v3P8+...
listening port: 51820
peer: abcXyz... (téléphone)
endpoint: 82.45.123.10:54321
allowed ips: 10.0.0.2/32
latest handshake: 2 minutes ago — connecté !
transfer: 42 MiB received, 8 MiB sent
## SERVICE ##
sudo systemctl start wg-quick@wg0
sudo systemctl stop wg-quick@wg0
sudo systemctl restart wg-quick@wg0
## AJOUTER UN PEER — CHAUD (sans redémarrer) ##
sudo wg set wg0 peer <PUBLIC_KEY_CLIENT> allowed-ips 10.0.0.4/32
## RETIRER UN PEER ##
sudo wg set wg0 peer <PUBLIC_KEY_CLIENT> remove
## VOIR LES STATS DE TRAFIC PAR PEER ##
sudo watch -n 1 wg show # actualisation toutes les secondes
6. Alternative Facile — wg-easy (Interface Web)
Si la configuration manuelle te semble complexe, wg-easy est un conteneur Docker qui offre une interface web pour gérer WireGuard : ajouter des clients, télécharger les configs, voir les connexions actives.
wg-easy:
image: ghcr.io/wg-easy/wg-easy:latest
container_name: wg-easy
restart: unless-stopped
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1
ports:
- "51820:51820/udp" # WireGuard
- "51821:51821/tcp" # Interface web
volumes:
- wg_data:/etc/wireguard
environment:
- WG_HOST=88.123.45.67 # ton IP publique ou DDNS
- PASSWORD_HASH=$$2y$$10$$... # hash bcrypt du mot de passe
- WG_DEFAULT_ADDRESS=10.0.0.x
- WG_DEFAULT_DNS=1.1.1.1
- WG_ALLOWED_IPS=0.0.0.0/0
volumes:
wg_data:
# Générer le hash du mot de passe
docker run --rm ghcr.io/wg-easy/wg-easy wgpw 'TON_MOT_DE_PASSE'
PASSWORD_HASH='$$2y$$10$$hBCoykrB95WSzuV4fafBzOHWKu9RdzqPpg98.BEAC0w7.xGbnXyhmS'
# Accès — http://IP:51821
wg-easy est parfait pour un homelab : tu ajoutes un client en 1 clic, télécharges sa config ou scannes le QR code directement depuis l'interface web. Aucune ligne de commande nécessaire pour gérer les clients.
7. IP Dynamique — Utilise un DDNS
Si ton FAI te fournit une IP qui change régulièrement, ton Endpoint dans les configs clients deviendra invalide. La solution : un service DDNS (Dynamic DNS) qui mappe un nom de domaine fixe vers ton IP changeante.
# Tu obtiens : monhomelab.duckdns.org + un token
# Script de mise à jour automatique de l'IP
cat <<'EOF' > ~/duckdns_update.sh
#!/bin/bash
TOKEN="ton-token-duckdns"
DOMAIN="monhomelab"
curl -s "https://www.duckdns.org/updateédomains=$DOMAIN&token=$TOKEN&ip=" > /dev/null
EOF
chmod +x ~/duckdns_update.sh
# Planifier la mise à jour toutes les 5 minutes
( crontab -l 2>/dev/null; echo "*/5 * * * * ~/duckdns_update.sh" ) | crontab -
# Dans la config client WireGuard, utilise le nom DDNS
Endpoint = monhomelab.duckdns.org:51820
# Alternatives gratuites : No-IP, FreeDNS, Cloudflare DDNS
✅ Comment savoir si ton VPN WireGuard fonctionne
- ✅
sudo wg showaffiche l'interfacewg0avec le port51820en écoute - ✅Depuis ton téléphone en 4G (Wi-Fi coupé), tu peux pinger
10.0.0.1:ping 10.0.0.1 - ✅Depuis le téléphone connecté au VPN, tu accèdes →
http://192.168.1.10:8096(Jellyfin local) - ✅
sudo wg showaffiche "latest handshake: X minutes ago" pour le peer du téléphone - ✅En full tunnel :
curl ifconfig.medepuis le téléphone retourne l'IP de ton serveur, pas l'IP 4G
⚠️ Problèmes Courants & Solutions
Le client se connecte mais ne peut pas atteindre Internet ou le LAN
💡 Le routage IP n'est pas activé sur le serveur. Vérifie : cat /proc/sys/net/ipv4/ip_forward → doit retourner 1. Si 0 : sudo sysctl net.ipv4.ip_forward=1. Vérifie aussi les règles iptables dans le PostUp et que le nom d'interface rôleau (enp3s0) est correct.
"latest handshake" ne change jamais à la connexion ne s'établit pas
💡 Le paquet UDP n'arrive pas au serveur. Vérifie : 1) la redirection de port 51820/UDP sur ton routeur, 2) la règle UFW sudo ufw status | grep 51820, 3) que l'Endpoint dans la config client est bien l'IP publique du serveur, pas son IP locale.
La connexion se coupe régulièrement derrière un NAT (4G / box)
💡 Ajoute PersistentKeepalive = 25 dans la section [Peer] de la config client (pas serveur). Cela envoie un paquet keep-alive toutes les 25 secondes pour maintenir la session NAT ouverte.
é Fuite DNS — mes requêtes DNS ne passent pas par le VPN
💡 Vérifie que tu as bien défini DNS = 1.1.1.1 dans la config client, et que AllowedIPs = 0.0.0.0/0 inclut le trafic DNS (port 53 sur 0.0.0.0/0). Teste avec dnsleaktest.com depuis le téléphone connecté.