Tutoriel : Comment implémenter un service VPN personnel avec WireGuard ?

Publié le

Un service VPN est utile pour protéger son anonymat quand on utilise un réseau non sécurisé, par exemple, dans des lieux publics tels que des hôtels ou aéroports. Il existe de nombreux fournisseurs de VPN et c’est un marché fortement concurrentiel. Pour un prix comparable à ce que proposent ces fournisseurs, il est possible de mettre en place soi-même ce service. La contrepartie est qu'il n'est pas possible de changer le pays de destination du VPN à la volée : l'emplacement géographique est à définir au moment de la mise en place du serveur chez un Cloud provider.

Nous allons voir ici comment implémenter un VPN avec WireGuard, qui est un logiciel libre et open source.
Il présente de nombreux avantages :

  • Il est très rapide et peu consommateur en resources.
  • Le code source de son implémentation sous Linux ne fait que quelques milliers de lignes, ce qui réduit sa surface d’attaque et le rend facilement auditable.
  • Il utilise des algorithmes cryptographiques rapides et efficaces.
  • Son client est utilisable sur de nombreuses plateformes : Linux, les BSD, macOS, Windows, Android, iOS, etc.
  • Son installation est très simple.

Choix du Cloud provider

Nous mettrons en place le service chez le Cloud provider de votre choix (il n'y a pas de prérequis à ce niveau, ça dépend surtout du pays dans lequel vous voulez que l'adresse IP du VPN soit localisée). Attention toutefois à l’utilisation que vous ferez de ce service, certains Cloud providers facturent le trafic (avec éventuellement un Free Tier), d’autres non.

Préparation du serveur VPN

Règles de pare-feu

Si votre Cloud provider supporte les security groups, l'idéal est d'en mettre une en place pour le trafic entrant :

  • ssh (port 22/TCP), pour l'administration
  • un port de votre choix, en UDP pour WireGuard (dans ce tutoriel: port 123/UDP)

Souvent c'est le port 51820 qui est utilisé pour WireGuard. Ici, je choisis de prendre le port normalement réservé au protocole NTP. Ce choix est volontaire, car ce port est moins susceptible d'être bloqué. On aurait pu choisir le port 53 (port du service DNS), mais celui-ci est parfois détourné, en particulier sur les réseaux mobiles.

Pour le trafic sortant, on autorise tous les ports, ce qui permettra d'utiliser le VPN pour tous les services, et non pas uniquement les serveurs de mails et la consultation de sites web.

Serveur

Vous pouvez prendre une machine virtuelle de très petite taille, son rôle sera uniquement de déchiffrer les paquets du service VPN et de router le résultat vers l'internet public. Pour un usage « normal », ça ne nécessite pas beaucoup de puissance, et WireGuard utilise des algorithmes cryptographiques très rapides à calculer. J'utilise une machine virtuelle avec 512MB de RAM et 1 cœur de CPU.

Le seul prérequis dans ce tutoriel est que la machine soit sous Ubuntu 20.04. Les commandes peuvent assez facilement être adaptées pour d'autres distributions Linux récentes.

Une fois la machine virtuelle réservée, il est nécessaire de s'y connecter en SSH.

Installation du service

Dans la plupart des distributions Linux récentes, dont Ubuntu 20.04 fait partie, WireGuard est présent dans le noyau de base. Il sera par contre nécessaire d'installer les outils pour générer des clés de chiffrement :

# Passage en root pour faciliter la suite
sudo su -

apt install wireguard

Nous enchaînons rapidement avec la création d'une paire de clé publique/privée qui identifie le serveur VPN :

# Crée un répertoire pour stocker les clés
mkdir -p /etc/wireguard/keys

# Crée les clés avec les droits 0600
umask 077

# Crée un clé privée
wg genkey > /etc/wireguard/keys/server-private-key

# Dérive la clé publique à partir de la clé privée
wg pubkey < /etc/wireguard/keys/server-private-key > /etc/wireguard/keys/server-public-key

Nous allons ensuite paramétrer le réseau privé du VPN. Pour commencer, nous devons définir un sous-réseau pour l'adressage du serveur et des clients. La RFC 1918 définit ces plages d'adresses privées pour IPv4 :

  • 10.0.0.0/8 (adresses 10.0.0.0 à 10.255.255.255)
  • 172.16.0.0/12 (adresses 172.16.0.0 à 172.31.255.255)
  • 192.168.0.0/16 (192.168.0.0 à 192.168.255.255)

Nous choisissons ici de définir un sous-réseau du réseau 192.168.0.0/16, ça sera 192.168.254.0/24. Le serveur prendra l'adresse IP 192.168.254.1, et les clients les adresses qui la suivent. Nous avons donc la possibilité de connecter 252 clients sur ce serveur (255 hôtes sont possibles sur ce réseau, auxquels on soustrait les adresses de broadcast 192.168.254.255, du réseau 192.168.254.0, et du serveur 192.168.254.1 qui ne sont pas utilisables).

Nous passons ensuite à la configuration de l'interface wg0, dans /etc/wireguard/wg0.conf :

[Interface]
PrivateKey = [Contenu de /etc/wireguard/keys/server-private-key]
Address = 192.168.250.1/24, fd00::1/128
ListenPort = 123
PostUp = sysctl -w net.ipv4.ip_forward=1; sysctl -w net.ipv6.conf.all.forwarding=1; iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # Add forwarding when VPN is started
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE # Remove forwarding when VPN is shutdown

Les commandes définies dans les variables PostUp et PostDown servent à permettre le routage du trafic des clients à partir du serveur.

Nous sécurisons l'accès à ce fichier en modifiant ses droits :

chmod 0600 /etc/wireguard/wg0.conf

Installation d'un client

Sur un client Linux, tout comme sur le serveur, il sera nécessaire d'installer WireGuard avec le gestionnaire de paquet pour avoir l'utilitaire en ligne de commande wg.

Sous macOS, l'installation de cet utilitaire se fait facilement avec Homebrew : brew install wireguard-tools. Pour les autres plateformes dont Windows, l'utilitaire est disponible à partir du site officiel.

Configuration sous Linux

Nous avons besoin d'une paire de clés publique/privée pour identifier le client :

# en root
sudo su -

# Crée un répertoire pour stocker les clés
mkdir -p /etc/wireguard/keys

# Crée les clés avec les droits 0600
umask 077

# Crée un clé privée
wg genkey > /etc/wireguard/keys/client-private-key

# Dérive la clé publique à partir de la clé privée
wg pubkey < /etc/wireguard/keys/client-private-key > /etc/wireguard/keys/client-public-key

La configuration du client se fait dans /etc/wireguard/wg0.conf :

[Interface]
PrivateKey = [Contenu de /etc/wireguard/keys/client-private-key]
Address = 192.168.250.2/24, fd00::2/128
DNS = 1.1.1.1

[Peer]
PublicKey = [Contenu de /etc/wireguard/keys/server-public-key du serveur VPN]
Endpoint = [Adresse IP publique du serveur VPN]:123
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

Nous sécurisons l'accès à ce fichier :

chmod 0600 /etc/wireguard/wg0.conf

La section Interface définit les paramètres suivants :

  • Le client aura l'adresse IP 192.168.254.2.
  • Le DNS 1.1.1.1 est géré par Cloudflare et l'APNIC. Ces entreprises mettent en avant la protection de la vie privée de l'utilisateur. À vous de les croires ou non, et de déterminer si un autre service DNS correspond mieux à vos besoins, ou encore s'il faudra en implémenter un vous-même.

La section Peer définit comment se connecter au serveur VPN :

  • PublicKey permet de valider l'authentification du serveur VPN.
  • Endpoint définit l'adresse IP publique et le port auquel se connecter.
  • L'option PersistentKeepalive fait en sorte que WireGuard envoie un paquet toutes les 25 secondes, ce qui est utile quand il est utilisé derrière un NAT. Sans cette option, on peut se retrouver avec des erreurs de connexion.

Configuration sous macOS

Sous macOS, vous aurez besoin de télécharger l'application WireGuard (en plus de l'utilitaire en ligne de commande).

La préparation de la configuration de WireGuard sous macOS est presque identique à Linux. Nous pouvons reprendre la configuration présentée dans la section précédente pour l'installation d'un client, mais la procédure est faite avec l'utilisateur courant plutôt qu'avec root. Nous écrivons la configuration dans le dossier de démarrage de l'utilisateur, ici, j'ai choisis de créer un dossier ~/.wg :

# Crée un répertoire pour stocker les clés
mkdir -p $HOME/.wg/keys

# Crée les clés avec les droits 0600
umask 077

# Crée un clé privée
wg genkey > $HOME/.wg/keys/client-private-key

# Dérive la clé publique à partir de la clé privée
wg pubkey < $HOME/.wg/keys/client-private-key > $HOME/.wg/keys/client-public-key

La configuration du client est écrite dans ~/.wg/wg0.conf :

[Interface]
PrivateKey = [Contenu de $HOME/.wg/keys/client-private-key]
Address = 192.168.250.3/24, fd00::3/128
DNS = 1.1.1.1

[Peer]
PublicKey = [Contenu de /etc/wireguard/keys/server-public-key du serveur VPN]
Endpoint = [Adresse IP publique du serveur VPN]:123
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

Nous ouvrons le client WireGuard pour macOS :

2021-02-19-wg-macOS.png

Nous cliquons sur le petit engrenage en bas à gauche, puis sur Ajouter un tunnel vide, enfin nous insérons la configuration :

2021-02-19-wg-macOS-configuration.png

Nous enregistrons la configuration. Nous pouvons maintenant supprimer le dossier ~/.wg :

rm -rf $HOME/.wg

Mise à jour de la configuration sur le serveur, et démarrage du service

Nous ajoutons la configuration pour le client Linux, sur le serveur dans /etc/wireguard/wg0.conf :

[Peer]
PublicKey = [Clé publique du client Linux]
AllowedIPs = 192.168.250.2/24, fd00::2/128

De même pour le client macOS :

[Peer]
PublicKey = [Clé publique du client macOS]
AllowedIPs = 192.168.250.3/24, fd00::3/128

Le démarrage du serveur VPN est faisable manuellement ou de façon simplifiée avec l'utilitaire wg-quick. Sur le serveur VPN puis sur le client Linux, la commande pour activer le service est la même :

sudo wg-quick up wg0

Nous pouvons lancer automatiquement le service au démarrage de la machine, avec la commande :

sudo systemctl enable wg-quick@wg0

Sous macOS, le processus se fait par l'interface graphique de l'application WireGuard :

2021-02-19-wg-macOS-inactif.png

Nous cliquons sur activer. Le service se met en route presque instantanément.

Test du VPN

Nous pouvons tester maintenant le fonctionnement de notre VPN avec un service de renseignements sur notre adresse IP. J'ai choisi le service de localisation de Maxmind :

2021-02-19-maxmind-natif.png
(Sans le VPN, nous sommes connecté depuis Luxembourg)

2021-02-19-maxmind-vpn.png
(Avec le VPN, nous constatons que nous sommes localisé en Suisse, alors que la requête a été initié depuis mon domicile au Luxembourg)

La bande passante est excellente :

2021-02-19-speedtest-natif.png
Sans le VPN

2021-02-19-speedtest-vpn.png
Avec le VPN, la latence (ping) est un peu plus élevée, mais le débit reste excellent

Pour aller plus loin

Une option de configuration qui n'a pas été abordée ici, est l'utilisation de secrets pré-partagés (PSK, pre-shared keys) entre le serveur et chacun des clients. Ce mécanisme ajoute cependant une couche de sécurité supplémentaire. Une PSK est unique pour chaque couple (client, serveur), et peut être générée avec la commande wg genpsk.

Conclusion

WireGuard est très rapide à mettre en place, en quelques commandes seulement. Il est plus simple à déployer par rapport à OpenVPN, tout en utilisant des algorithmes cryptographiques dans l'air du temps. De plus, il offre des performances tout à fait intéressantes face à ses concurrents.

Autres références

Mention légale : "WireGuard" and the "WireGuard" logo are registered trademarks of Jason A. Donenfeld.

PHILIPPE CHEPY

Administrateur Système et Développeur