WireGuard vit dans le noyau Linux depuis la version 5.6. Il n'a ni négociation complexe, ni certificats, ni démon volumineux : une paire de clés par machine, un fichier de configuration d'une vingtaine de lignes, et un tunnel qui sature un lien gigabit sans mobiliser un cœur entier.
L'usage le plus courant sur un VPS : sortir sur Internet depuis une adresse IP stable, atteindre un réseau privé, ou relier plusieurs machines sans les exposer. Le montage ci-dessous couvre le premier cas, dont les deux autres sont des variantes.
1. Installer WireGuard
sudo apt update
sudo apt install -y wireguard qrencode
qrencode servira à enrôler les téléphones sans recopier une clé à
la main.
2. Générer les clés
Chaque participant du tunnel possède sa paire. La clé privée reste sur sa
machine, la clé publique est distribuée. Le umask 077 évite qu'un
autre compte du serveur puisse lire la clé privée.
umask 077
wg genkey | sudo tee /etc/wireguard/serveur.key | wg pubkey | sudo tee /etc/wireguard/serveur.pub
# et une paire par client
wg genkey | tee client-laptop.key | wg pubkey > client-laptop.pub
3. Activer le routage
Un serveur Linux ne transfère pas de paquets par défaut. Activez-le pour les deux familles d'adresses, de façon persistante.
sudo tee /etc/sysctl.d/99-wireguard.conf <<'EOF'
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
EOF
sudo sysctl --system
4. Configurer l'interface serveur
On choisit un préfixe privé pour le tunnel : 10.8.0.0/24 en IPv4 et
un ULA fd42:42:42::/64 en IPv6. Repérez d'abord le nom de votre
interface publique.
ip -brief addr # souvent ens3, eth0 ou enp1s0
sudo tee /etc/wireguard/wg0.conf <<'EOF'
[Interface]
Address = 10.8.0.1/24, fd42:42:42::1/64
ListenPort = 51820
PrivateKey = <contenu de /etc/wireguard/serveur.key>
PostUp = nft add table inet wg; \
nft add chain inet wg postrouting { type nat hook postrouting priority 100 \; }; \
nft add rule inet wg postrouting oifname "ens3" masquerade
PostDown = nft delete table inet wg
[Peer]
# laptop
PublicKey = <contenu de client-laptop.pub>
AllowedIPs = 10.8.0.2/32, fd42:42:42::2/128
EOF
sudo chmod 600 /etc/wireguard/wg0.conf
Une table nftables dédiée plutôt que des règles
iptables éparpillées : PostDown supprime alors tout
le bloc d'un coup, sans laisser de règle orpheline après un redémarrage du
tunnel. Adaptez oifname au nom réel de votre interface.
5. Ouvrir le port et démarrer
sudo ufw allow 51820/udp
sudo ufw route allow in on wg0 out on ens3
sudo systemctl enable --now wg-quick@wg0
sudo wg show
wg show doit lister l'interface, son port d'écoute et le pair
déclaré. Un pair sans latest handshake est simplement un client qui
ne s'est pas encore connecté.
6. Configurer un client
Sur le poste, un fichier symétrique. AllowedIPs = 0.0.0.0/0, ::/0
fait passer tout le trafic par le tunnel ; pour n'y router qu'un réseau précis,
remplacez cette ligne par le préfixe concerné.
[Interface]
Address = 10.8.0.2/32, fd42:42:42::2/128
PrivateKey = <contenu de client-laptop.key>
DNS = 9.9.9.9, 2620:fe::fe
[Peer]
PublicKey = <contenu de /etc/wireguard/serveur.pub>
Endpoint = 198.51.100.42:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
PersistentKeepalive maintient l'association ouverte à travers les
NAT domestiques et mobiles. Sans lui, le tunnel fonctionne du client vers le
serveur mais pas dans l'autre sens après quelques minutes d'inactivité.
7. Enrôler un téléphone
L'application WireGuard lit un QR code contenant la configuration complète. Rien à taper, aucune clé à transmettre par messagerie.
qrencode -t ansiutf8 < client-telephone.conf
Chaque nouveau client se déclare côté serveur par un bloc [Peer]
supplémentaire, avec sa propre adresse dans AllowedIPs :
sudo wg set wg0 peer <clé publique du client> allowed-ips 10.8.0.3/32,fd42:42:42::3/128
sudo wg-quick save wg0
8. Dépannage
-
Aucune poignée de main : le port 51820/UDP n'est pas joignable.
Testez avec
nc -zvu 198.51.100.42 51820et vérifiez UFW. -
Poignée de main mais pas d'Internet : le masquage NAT ou le
transfert IP manque. Contrôlez
sysctl net.ipv4.ip_forwardetsudo nft list table inet wg. -
Le nom de domaine ne résout pas : la directive
DNSdu client est absente ou pointe vers un résolveur inaccessible depuis le tunnel. -
Fuite IPv6 : si le client dispose d'IPv6 native et que
AllowedIPsne contient pas::/0, une partie du trafic sort hors du tunnel.
Un dernier réflexe : sudo wg show wg0 latest-handshakes donne
l'horodatage de la dernière poignée de main par pair. C'est l'indicateur le plus
rapide pour distinguer un problème de réseau d'un problème de configuration.