Ubuntu Linux · Épisode 12

🔐 VPN WireGuard — Ton Propre Tunnel Sécurisé

Déploie ton propre serveur VPN WireGuard sur Ubuntu : génére des clés, configure le serveur et connecte smartphones, PC et tablettes à ton rôleau privé depuis n'importe où dans le monde.

📅 Avril 2026
👤 Par OWL
~35 min de lecture
Avancé
Illustration VPN WireGuard Ubuntu

Ton propre VPN WireGuard

é
WireGuard — Le plus rapide
4x plus rapide qu'OpenVPN, 10x moins de code que IPSec. WireGuard est le protocole VPN moderne de référence, intégré au noyau Linux depuis 5.6.
💰
Chiffrement moderne
ChaCha20, Poly1305, Curve25519, BLAKE2 — WireGuard utilise une cryptographie d'état de l'art, simple et auditée. Zero-trust par défaut.
💰
Multi-appareils
Connecte tous tes appareils : smartphone Android/iOS, PC Windows/Mac/Linux. L'appli officielle WireGuard est disponible partout.
💰
Accès au homelab
Accède — Nextcloud, Jellyfin, Portainer et tous tes services locaux depuis l'extérieur, sans les exposer directement sur Internet.

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

Terminal — Installation
# Installer WireGuard
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.).

Terminal — Génération des clés
# === SERVEUR === Générer clé privée + publique
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

Terminal — Récupérer les clés pour la config
# Récupérer les valeurs — copier dans la config
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 :

/etc/wireguard/wg0.conf — Serveur
sudo nano /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
Terminal — Activer le routage IP + démarrer WireGuard
# Activer le routage IP (forwarding)
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)

phone.conf — à importer dans l'appli WireGuard
[Interface]
# 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

Terminal — QR Code pour import mobile
# Installer qrencode
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

Terminal — Commandes WireGuard essentielles
## STATUT ##
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.

/opt/wg-easy/compose.yml
services:
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.

Terminal — DDNS avec DuckDNS (gratuit)
# Inscription gratuite sur https://www.duckdns.org
# 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 show affiche l'interface wg0 avec le port 51820 en é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 show affiche "latest handshake: X minutes ago" pour le peer du téléphone
  • En full tunnel : curl ifconfig.me depuis 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é.

💬 Commentaires & Discussion