WireGuard, serveur VPN

WireGuard, serveur VPN

Le futur du VPN ?

Présentation de WireGuard VPN

Serveur WireGuard VPN

wireguard.png

WireGuard est un serveur VPN dont l'avantage principal est qu'il est léger, simple à prendre en main et surtout très rapide comparé à d'autres solutions comme OpenVPN. Il ne fonctionne uniquement que par UDP, ce qui explique en partie sa rapidité, mais qui peut aussi être problématique avec certains firewall. L'une des spécificités de WireGuard c'est qu'il fonctionne en mode "peer to peer" au contraire du traditionnel modèle "serveur-client", ce qui fait qu'en réalité, il n'y a pas véritablement de serveur WireGuard étant donné que chaque pair de la connexion peut dans l'absolu être le serveur de l'autre et vice-versa.

Cela est évidemment un avantage non négligeable qui apporte beaucoup de flexibilité à cette solution.

L'authentification se base sur un principe d'échange de clé, sur le même principe que SSH avec les clés privées/publiques.

Et niveau algorithme, il n'y a pas de soucis à ce faire, car WireGuard utilise les chiffrements les plus robustes possibles et qui sont audités régulièrement par des chercheurs en sécurité.

Il est bien sûr multiplateforme : Windows, Linux, BSD, macOS, Android, iOS, OpenWrt...

Par défaut, WireGuard fonctionne sur le port 51820.

Installation du serveur

Informations essentielles

HôteAdresse IPInfos
Serveur WireGuard192.168.1.40Serveur Debian 11
Client WindowsDHCPWindows 10
Smartphone DHCPAndroid

Je testerai principalement la connexion Peer to Peer entre le serveur WireGuard et le client Windows 10.

Pour pouvoir accéder au serveur VPN depuis n'importe où via internet, vous devrez effectuer une redirection sur le port 51820 sur votre box ou routeur.

Installation et configuration du serveur WireGuard

WireGuard fait partie des dépôts officiels de Debian, donc une simple commande apt-get suffit.

sudo apt-get update
sudo apt-get install wireguard

install_wireguard.jpg

La partie serveur de Wireguard est installé, il faut maintenant le configurer.

Configuration du serveur

Création de l'interface WireGuard

Comme dit précédemment, WireGuard repose sur un système de clé privée/clé publique pour l'authentification serveur/client. Nous allons donc devoir générer la clé privée et publique à l'aide de cette commande :

wg genkey | sudo tee /etc/wireguard/wg-private.key | wg pubkey | sudo tee /etc/wireguard/wg-public.key

clé_privé_publique.jpg

La valeur qui nous est retournée est la clé publique. Nous allons devoir ajouter la valeur de notre clé privée dans le fichier de configuration de WireGuard. Récupérer là et copiez-la.

sudo cat /etc/wireguard/wg-private.key

J'ai censuré la clé, c'est juste pour montrer le résultat de la commande

clé_privé_wireguard.png

Maintenant, il faut créer le fichier de configuration dans /etc/wireguard/. Je l'ai nommé wg0.conf comme l'interface Wireguard wg0 que je compte créer.

sudo nano /etc/wireguard/wg0.conf

On doit y ajouter ce contenu :

[Interface]
Address = 192.168.110.100/24
SaveConfig = true
ListenPort = 51820
PrivateKey = <clé privée du serveur>

La section [Interface] sert à déclarer la partie serveur. Voici quelques informations :

  • Address : l'adresse IP de l'interface WireGuard au sein du tunnel VPN (sous-réseau différent du LAN distant)
  • SaveConfig : la configuration est mise en mémoire (et protégée) tout le temps que l'interface est active
  • ListenPort : le port d'écoute de WireGuard, ici, c'est 51820 qui est le port par défaut, mais vous pouvez le personnaliser
  • PrivateKey : la valeur de la clé privée de notre serveur (wg-private.key)

Après avoir enregistré le fichier, nous allons démarrer l'interface de WireGuard en précisant son nom (wg0, comme le nom du fichier de conf wg0.conf) :

sudo wg-quick up wg0

wg_0_up.jpg

On peut vérifier l'existence de notre interface avec ip a

ip_a.jpg

Ensuite, il faut activer le démarrage automatique de notre interface wg0 wireguard.

sudo systemctl enable wg-quick@wg0.service

IP Forwarding

On doit faire en sorte que notre serveur Debian puisse router les paquets entre les différents réseaux, tel un routeur, c'est-à-dire entre le réseau du VPN et le réseau local. Et pour cela, nous avons besoin d'activer l'IP Forwarding car elle est désactivée par défaut.

Ouvrez ce fichier de configuration

sudo nano /etc/sysctl.conf

Et ajoutez-y la ligne suivante ou décommentez là

net.ipv4.ip_forward=1

net.ipv4.jpg

On active le changement au niveau du forwarding et on fait en sorte qu'il reste persistant même après un redémarrage du serveur :

sudo sysctl -p

On peut vérifier que le forwarding est bien activé, la commande doit nous retourner "1" :

sudo cat /proc/sys/net/ipv4/ip_forward

Vérifier bien que l'IP Forwarding est activé si plus tard, lorsque vous vous connectez à wireguard, vous pouvez ping votre serveur Wireguard mais ne pouvez pas accéder au reste de votre LAN, c'est sûrement que l'IP Forwarding est désactivé.

IP Masquerade

Afin que le serveur puisse router correctement les paquets et que le LAN distant soit accessible à la machine cliente, il faut activer l'IP Masquerade sur notre serveur Debian. C'est plus ou moins l'activation du NAT.
Pour cela, je vais devoir configurer le pare-feu du serveur Linux à travers d'UFW.

UFW est un pare-feu Linux dont la gestion est simplifiée comparée à d'autres, mais pouvez très bien utiliser Iptables ou Nftables si ça vous chante.

Pour installer UFW :

sudo apt install ufw

Il faut ensuite autoriser l'accès SSH pour ne pas perdre le contrôle à distance (car UFW, comme bien d'autres pare-feux, désactivera la majorité des ports par défaut pour raison de sécurité) :

sudo ufw allow 22/tcp

Il faut aussi bien évidement autorisé la connexion au port utilisé par WireGuard :

sudo ufw allow 51820/udp

ufw_rules.jpg

On poursuit la configuration de l'IP masquerade et pour cela on a besoin de récupérer le nom de l'interface connecté au réseau local. On peut la connaitre avec ip a

ip_a_carte_local.jpg

Avec cette information en poche, on va éditer le fichier suivant :

sudo nano /etc/ufw/before.rules

On va venir ajouter ces lignes à la fin du fichier afin d'activer l'IP masquerade sur l'interface connecté au réseau local (ens33 dans mon cas), au sein de la chaîne POSTROUTING de la table NAT de notre pare-feu local :

# NAT - IP masquerade
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o ens33 -j MASQUERADE

# End each table with the 'COMMIT' line or these rules won't be processed
COMMIT

ufw_ip_masquerade.jpg

Configuration du pare-feu Linux pour WireGuard

Toujours dans le même fichier de conf, on va déclarer le réseau auquel on veut avoir accès quand on est connecté au VPN. Donc dans mon cas, ça sera le "192.168.1.0/24" qui correspond à mon LAN où j'ai accès à mon Raspberry Pi (NAS) et mes autres périphériques locaux. On doit de ce fait déclarer le réseau du VPN + celui du réseau auquel on veut avoir accès.

On n'est pas obligé de déclarer notre LAN, on peut très bien faire en sorte que les gens connectés au VPN, les "Peer" n'est seulement qu'accès au sous réseau du VPN si l'on veut, on reste flexible.

# autoriser le forwarding pour le réseau distant de confiance (+ le réseau du VPN)
-A ufw-before-forward -s 192.168.1.0/24 -j ACCEPT
-A ufw-before-forward -d 192.168.1.0/24 -j ACCEPT
-A ufw-before-forward -s 192.168.110.0/24 -j ACCEPT
-A ufw-before-forward -d 192.168.110.0/24 -j ACCEPT

Bien évidemment, vous pouvez autoriser l'accès au nombre de réseaux que vous désirez ou même seulement à certaines hôtes en particulier.

déclaration_réseaux_ufw.jpg

Après avoir enregistré les modifications, on active UFW et on redémarre son service pour que tous les changements soient bien pris en compte.

sudo ufw enable
sudo systemctl restart ufw

Configuration du client Windows

Installation du client et création d'un profil WireGuard

Bon ici, rien de spécial, vous télécharger le programme d'installation depuis le site officiel et lancer l'installation qui est très rapide.

Après avoir lancé le logiciel, on va créer un nouveau tunnel qui nous permettra de se connecter au serveur VPN. Cliquez sur la flèche à droite du bouton "Ajouter le tunnel" et cliques sur le bouton "Ajouter un tunnel vide".

interface_vide.png

Une fenêtre de configuration va s'ouvrir. À chaque fois que l'on crée une nouvelle configuration de tunnel, WireGuard génère un couple de clés privé/public propre à cette configuration. Dans cette configuration, nous devons déclarer le "peer", c'est-à-dire le serveur distant. Pour le moment, nous avons seulement ceci :

[Interface]
PrivateKey = <la clé privée du PC>

On doit compléter cette configuration, avec notamment l'adresse IP pour cette interface, mais aussi déclarer le serveur WireGuard distant via un bloc [Peer].

Commençons par le bloc [Interface] en déclarant l'adresse IP du client Windows. Dans mon cas, j'ai choisi "192.168.110.150". N'oublions pas que le serveur dispose de l'adresse IP "192.168.110.100" sur ce segment réseau.

[Interface]
PrivateKey = <la clé privée du PC>
Address = 192.168.110.150/24

Après cela, nous devons déclarer le bloc "Peer" avec trois propriétés, ce qui nous donne cette configuration :

[Peer]
PublicKey = UupurkaXGBwS+YaP5QNwPBRWn5flxkbk+YqK3toVgjw=
AllowedIPs = 192.168.110.0/24, 192.168.1.0/24
Endpoint = <ip-serveur-debian>:51820

Dans mon cas, j'ai fait en sorte que mon serveur WireGuard soit accessible depuis Internet, il faudra donc ici indiquer à la place de l'adresse IP du serveur Debian, l'adresse IP publique de votre box afin que vous puissiez accéder au VPN depuis n'importe où.

Mais si vous utiliser Wireguard en local, vous n'avez pas besoin de faire tout cela et vous avez juste à indiquer l'addresse IP local du serveur.

Tunnel_wireguard.jpg

Précisions sur le bloc [Peer]

  • PublicKey : il s'agit de la clé publique du serveur WireGuard Debian 11 (vous pouvez obtenir sa valeur via la commande "sudo wg")
  • AllowedIPs : il s'agit des adresses IP / des sous-réseaux accessibles via ce réseau VPN WireGuard, ici il s'agit du sous-réseau propre à mon VPN WireGuard (192.168.110.0/24) et de mon LAN distant (192.168.1.0/24)
  • Endpoint : il s'agit de l'adresse IP du serveur Debian 11 puisque c'est notre point de liaison WireGuard (il s'agit l'adresse IP publique dans mon cas comme expliqué précédemment)

Si jamais vous voulez tunnelez tout le réseau en mettant AllowedIPs en : "0.0.0.0/0, ::/0".
Il faudra ajouter une ligne DNS dans le bloc Interface afin d'avoir accès à internet.
Vous pouvez utilisez 1.1.1.1 pour celui de Cloudflare ou 8.8.8.8 pour celui de Google si vous n'avez pas de DNS par exemple.
tunnel_dns.jpg

Finalement, choisissez un nom pour le tunnel (sans espaces) et copiez coller la clé publique du client quelque part, car nous allons devoir la déclarer sur le serveur.

Cliquez sur Enregistrer.

Déclaration du client sur le serveur WireGuard

On retourne sur le serveur Debian pour y déclarer le "Peer", c'est-à-dire notre client Windows dans la configuration de WireGuard. Il faut d'abord stopper l'interface "wg0" pour pouvoir modifier sa configuration.

sudo wg-quick down wg0

Ensuite on modifie le fichier de conf précédemment crée :

sudo nano /etc/wireguard/wg0.conf

À la suite du bloc [Interface], il faut que l'on déclare un bloc [Peer] :

[Peer]
PublicKey = jg/CoZ2EAN4fkpfkneVqIOvHsaDAY5F3xO9ZaCihM3E=
AllowedIPs = 192.168.110.150/32

Ce bloc [Peer] contient la clé publique du client Windows (PublicKey) ainsi que l'adresse IP de l'interface de ce PC (AllowedIPs) : le serveur communiquera dans ce tunnel WireGuard uniquement pour contacter le client Windows, d'où la valeur "192.168.110.150/32".

Le masque de sous réseau /32 est pour indiquer à WireGuard qu'il s'agit que d'une seul adresse IP.

On sauvegarde le fichier et on redémarre l'interface "wg0".

sudo wg-quick up wg0

On peut vérifier que la déclaration du "peer" fonctionne bien avec cette commande :

sudo wg show

wg_show_peer.jpg

À partir du moment où l'hôte distant aura monté sa connexion WireGuard, son adresse IP va remonter au sein de la valeur "endpoint".

Et enfin, on peut sécuriser l'accès aux fichiers de configuration en limitant l'accès à "root" :

sudo chmod 600 /etc/wireguard/ -R

Première connexion avec WireGuard

Maintenant que nous avons effectué toutes les configurations, il est maintenant temps d'effectuer le premier test de connexion !

Sur le client Windows, cliquez sur le bouton "Activer" : la connexion va passer de "Eteinte" à "Activée". Mais cela ne veut pas pour autant dire que la connexion fonctionne, il faudra faire des tests et observer le journal d'audit et si nécessaire modifier les ficheirs de configurations.

Lorsque la connexion est établie, nos deux machines communiquent via l'interface WireGuard configurée de chaque côté !

En cas de problème, ce sera visible au sein de l'onglet "Journal". Les deux hôtes vont s'échanger des paquets régulièrement pour vérifier l'état de la connexion, d'où les messages "Receiving keepalive packet from peer 1".

wireguard_journal.png

Si l'onglet "Journal" de WireGuard affiche un message tel que celui ci-dessous, vous devez vérifier que les clés publiques déclarées des deux côtés sont correctes.

Handshake for peer 1 (&lt;ip&gt;:51820) did not complete after 5 seconds, retrying (try 2)

Il fallait le savoir ^^

Dans mon cas, c'était plus un souci d'inattention.

En fait, j'avais indiqué la mauvaise adresse IP dans alloweds ips sur le serveur Debian, comme vous pouvez le voir ici :

wg_show_peer_bad_ip.png

J'avais mis 192.168.110.0 au lieu de 192.168.110.150 :)

Donc vérifier bien vos configurations si jamais quelque chose ne fonctionne pas comme prévu.

Connexion client vers serveur : Peer to Peer

Dans cette section, on va faire en sorte d'établir une connexion VPN entre le client distant et le serveur WireGuard. C'est ce qu'on appelle une connexion "Peer to Peer".

Étant donné qu'on a déjà configuré en grande partie le serveur et le client, il n'y a pas grand-chose à modifier.

Environnement de test

Toujours avec mon serveur Debian faisant office de serveur WireGuard, j'utiliserai un client Windows 10 connecté à la 4G de mon portable pour être sûr que le VPN est bien accessible depuis l'extérieur de mon réseau local.

Configuration

Serveur

Comme toujours, lorsque je veux effectuer des modifications sur le fichier de configuration de WireGuard sur le serveur, je désactive d'abord l'interface avec la commande :

sudo wg-quick down wg0

J'ouvre le fichier de conf de wireguard :

sudo nano /etc/wireguard/wg0.conf

peers_good_ip.jpg

Si vous avez suivi les précédentes étapes, il n'y a rien modifier ici, sinon, remplacez les clés privées/publiques et adresses IP avec celles correspondantes aux vôtres.

Après avoir enregistré vos modifications, n'oubliez pas de réactiver l'interface de WireGuard pour que les changements soient pris en compte :

sudo wg-quick up wg0

Client

C'est ici qu'il y aura le plus grand changement.

Lancez WireGuard, vous devriez voir votre tunnel précédemment créé avec un résumé des informations essentielles comme son adresse IP dans le réseau VPN, l'adresse IP ou nom de domaine du serveur WireGuard, etc.

interface_client.jpg

Cliquez sur Modifier.

Ce qui va particulièrement nous intéresser ici est la partie AllowedIPs qui indique quelles adresses IP ou sous-réseaux on aura accès lors de la connexion VPN.

Dans notre cas à nous, vu que l'on veut une connexion peer to peer entre notre serveur et notre client, on va y déclarer seulement l'adresse IP de notre serveur, qui pour rappel est 192.168.100.100. Pour bien préciser que l'on désire uniquement avoir accès a une seule adresse IP, on utilisera un masque de sous réseau /32.

Ainsi, dans la section AllowedIPs, déclarez l'adresse du peer auquel vous voulez avoir accès, dans mon cas celle de mon serveur, suivi d'un /32, ce qui nous donne dans mon cas : 192.168.100.100/32

tunnel_peer.jpg

Après avoir vérifié que toutes les informations sont correctes, cliquez sur Enregistrer.

On revient sur la page d'accueil de WireGuard et on peut remarquer que les modifications ont bien été pris en compte.

interface_peer.jpg

Test

Il est temps de tester la connexion VPN en appuyant sur le bouton Activer. Après quelques secondes, la connexion devrait être active et le statut de l'état passé à Activée.

interface_peer_activé.jpg

Certes, la connexion est active, mais comme précisé auparavant, ça ne veut pas pour autant dire qu'elle fonctionne. On va donc vérifier cela grâce au Ping. En toute logique, je devrais avoir accès à Internet et pouvoir contacter mon serveur Debian.

ping_peer.jpg

Eh bien cela fonctionne bien ! J'ai bien accès à internet et je peux contacter mon serveur sur le sous-réseau du VPN.

Maintenant, on peut faire une vérification supplémentaire qui est d'être sûr qu'on n'a pas accès à mon LAN (192.168.1.0/24). Je vais de ce fait essayer de contacter mon serveur Debian sur le LAN qui a pour adresse IP 192.168.1.40.

ping_peer_verify.jpg

Parfait, je n'y ai pas accès :)

Sur votre serveur, vous pouvez voir l'état des connexions les plus récentes avec cette commande :

sudo wg show

Nous avons ainsi vu comment il a été possible d'établir une connexion Peer to Peer via WireGuard.

Connexion to host : Peer to LAN

Cette fois-ci, on va établir une connexion VPN vers le LAN, cela nous permettra d'avoir une connexion sécurisée vers nos périphériques locaux, et dans mon cas, à mon Raspberry Pi.

Encore une fois, vu qu'on a déjà effectué la configuration initiale, il n'y a pas forcément de choses à changer au niveau du serveur.

Environnement de test

Toujours avec mon serveur Debian faisant office de serveur WireGuard, j'utiliserai un client Windows 10 connecté à la 4G de mon portable pour être sûr que le VPN est bien accessible depuis l'extérieur de mon réseau local.

Configuration

Serveur

Comme toujours, lorsque je veux effectuer des modifications sur le fichier de configuration de WireGuard sur le serveur, je désactive d'abord l'interface avec la commande :

sudo wg-quick down wg0

J'ouvre le fichier de conf de WireGuard :

sudo nano /etc/wireguard/wg0.conf

peers_good_ip.jpg

Si vous avez suivi les précédentes étapes, il n'y a rien modifier ici, sinon, remplacez les clés privées/publiques et adresses IP avec celles correspondantes aux vôtres.

Après avoir enregistré vos modifications, n'oubliez pas de réactiver l'interface de WireGuard pour que les changements soient pris en compte :

sudo wg-quick up wg0

Client

C'est ici qu'il y aura le plus grand changement.

Lancez WireGuard, vous devriez voir votre tunnel précédemment créé avec un résumé des informations essentielles comme son adresse IP dans le réseau VPN, l'adresse IP ou nom de domaine du serveur WireGuard, etc.

interface_client - peer.jpg

Cliquez sur Modifier.

Ce qui va particulièrement nous intéresser ici est la partie AllowedIPs qui indique quelles adresses IP ou sous-réseaux on aura accès lors de la connexion VPN.

Cette fois-ci, on va définir les plages de sous-réseaux auxquels on veut avoir accès, ce qui va nous donner 192.168.110.0/24 pour le réseau du VPN et 192.168.1.0/24 pour mon LAN ou il y a le reste de mes périphériques dont mon Raspberry Pi.

Tunnel_wireguard.jpg

Après avoir vérifié que toutes les informations sont correctes, cliquez sur Enregistrer.

Test

Il est temps de tester la connexion VPN en appuyant sur le bouton Activer. Après quelques secondes, la connexion devrait être active et le statut de l'état passé à Activée.

interface_lan.jpg

Certes, la connexion est active, mais comme précisé auparavant, ça ne veut pas pour autant dire qu'elle fonctionne. On va donc contrôler cela grâce au Ping. En toute logique, je devrais avoir accès à Internet et à mon serveur Debian (192.168.1.40).

ping_lan.jpg

Je teste l'accès à mon Raspberry Pi qui a pour adresse 192.168.1.82 :

ping_pi.jpg

J'y ai bien accès, c'est bon.

Notre serveur WireGuard est bien configuré et je peux autant m'y connecté en mode peer to peer, peer to LAN ou Full tunnel.

Performance au niveau de la vitesse

Maintenant que nous avons mis en place note serveur WireGuard, on va observer comment il se débrouille niveau performances comparées à d'autres solutions VPN. Pour le coup, on va le comparer à mon serveur VPN OpenVPN.

Méthodologie

Pour pouvoir comparer les performances, je vais télécharger un fichier de 1 Go hébergé sur mon serveur Debian vers un client Windows 10, via WinSCP.

Pour créer un fichier vide de la taille que vous voulez sur Linux, on peut utiliser l'utilitaire dd. L'exemple que je vais montrer est pour créer un fichier de 1 Go, mais vous pouvez mettre la taille que vous souhaitez :

dd if=/dev/zero of=1G.bin bs=1024 count=0 seek=$[1024*1024]

Tests

Je vais donc me connecter d'abord en WireGuard puis en OpenVPN à mon réseau pour pouvoir télécharger le fichier et observer la vitesse de téléchargement. J'ai effectué les tests depuis les locaux de mon école, de ce fait depuis le WAN. Et les tests ont été réalisés plusieurs fois afin d'éviter des imprévus dans les résultats des tests.

WireGuard

transfer_fichier.jpg

transfert_wireguard.jpg

Sous WireGuard, le téléchargement du fichier de 1 Go aura pris ~ 34 secondes, avec une moyenne de ~ 22 Mo/s et une vitesse maximum de 30 Mo/s.

OpenVPN

transfert fichier_openvpn.jpg

Sous OpenVPN, le téléchargement du fichier de 1 Go aura pris ~ 3 minutes 38 secondes, avec une moyenne de ~ 4 Mo/s et une vitesse maximum de 5 Mo/s.

Conclusion

On peut déduire clairement de ce test via scp de la différence de performances entre les deux solutions. WireGuard est clairement gagnant sur ce coup-là, il est globalement entre 5 et 10 fois plus rapide !

Wireguard VPN fait clairement parti du futur du VPN, que ce soit au niveau de la sécurité, de la simplicité de configuration (on peut générer des QR codes pour les clients mobiles) ou des performances. Je vous encourage donc dès maintenant à adopter cette solution.