Wireguard
Wireguard est un VPN très pratique à mettre en place tout en restant sécurisé puisqu'il n'accepte que les dernières méthodes de chiffrement existantes. De plus, il fonctionne même si l'IP de votre appareil change (passage d'une connexion filaire à un réseau sans-fil par exemple). Il permet un accès tant en IPv4 qu'IPv6, ce qui peut permettre d'obtenir une IP fixe en IPv6 si votre FAI n'en donne pas. Il est supporté de base à partir d'OpenBSD 6.8. Avec les version précédentes, il faudra installer un port ("# pkg_add wireguard-go").
Il existe des clients wireguard sur de multiples plateformes (android, MacOS...) ce qui facilite son utilisation.
C'est certainement le choix le plus simple et utile si on veut mettre en place un VPN sur un serveur auto-hébergé.
Principe de fonctionnement
On retrouve les mêmes idées qui ont déjà fait leurs preuves pour chiffrer des mails ou encore publier les signatures DKIM : la paire de clés.
- Chaque appareil du VPN dispose d'une paire de clés (publique et privée) ainsi qu'une adresse IP interne. Les clés vont notamment permettre de d'identifier les appareils entre eux et sécuriser la première poignée de mains. (Méthode des clés pré-partagées : seul l'administrateur est censé en avoir eu connaissance).
- Régulièrement, les appareils se font des "poignées de main" afin de s'assurer que tout le monde va bien. Par la même occasion, ils s'échangent le nécessaire pour chiffrer les communications (clés symétriques). Ces dernières clés changent de façon périodique.
- Le flux entrant sur un appareil est déchiffré avec la clé échangée lors de la "poignée de mains" précédente.
Pour faire simple, chaque morceau de données envoyé au travers du VPN est mis dans un coffre et fermé avec un cadenas qui ne peut s'ouvrir qu'avec la clé échangée pendant la poignée de mains. La poignée de main est quant à elle chiffrée avec les clés publiques la première fois.
Mise en place d'un point de sortie ("roadwarrior")
Je vous propose l'organisation suivante :
- Le serveur servira de point de sortie pour les clients. C'est par son biais qu'ils accèderont à internet, et apparaîtront avec l'IP du serveur.
- Le traffic des clients passera par défaut via la route 0 pour rejoindre le serveur (rdomain 0).
- Les clients auront toujours leur accès à internet direct habituel que l'on basculera sur une route différente de celle par défaut : rdomain 1. Ainsi, on ne supprime pas cet accès, mais ce n'est pas celui privilégié.
Dans cet exemple, nous utiliserons dans le VPN des IP situées dans le sous réseau 10.0.0.0/24 :
- 10.0.0.1 sera l'IP du serveur;
- 10.0.0.2, 10.0.0.3, ... seront les IP des clients.
En savoir plus sur les adresses sous-réseau
Voici à quoi cela va ressembler :
+-------------+ | serveur | wg0: 10.0.0.1 port 4545 | |---------------+ +-------------+ | | IP Publique | | 192.0.2.2 | | | | | /\/\/\/\/\/\/\ |WireGuard | internet | |VPN \/\/\/\/\/\/\/ | | | | | |rdomain 1 | +-------------+ | | client |---------------+ +-------------+ wg0: 10.0.0.2 rdomain 0 (defaut)
Par défaut, le traffic passera par 10.0.0.2 à moins que vous demandiez précisément à passer par une autre route. (ex : "route -T1 exec ping openbsd.org")
Le VPN se met en place par la création d'interfaces wgN, où "N" peut être un chiffre de 0 à 9 par exemple. Sous OpenBSD, une telle interface peut être obtenue en remplissant un fichier "/etc/hostname.wgN".
Le serveur écoutera sur le port 4545 en UDP. N'importe quel autre port peut-être utilisé. Vérifiez tout de même que celui choisi ne soit pas déjà réservé en consultant "/etc/services".
Création de clés
Pour créer une clé privée robuste, utilisez la commande suivante :
openssl rand -base64 32
Cela retourne par exemple : "uA1ggvRv66QslZ0ygorWvcLVTxzFauffqMigXTrmLVY="
Ce n'est qu'une fois une clé privée attribuée à une interface que vous pourrez récupérer la clé publique correspondante avec la commande
# ifconfig wgN
Sur le serveur
On crée une clé privée :
# openssl rand -base64 32 r8uSGD6vyycE5n5/atU9/NX9JQPo4SJryNGpjbQG+rA=
On crée l'interface en précisant la clé précédente
# ifconfig wg0 create wgkey r8uSGD6vyycE5n5/atU9/NX9JQPo4SJryNGpjbQG+rA= wgport 4545
Maintenant, vous pouvez récupérer la clé publique correspondant à cette nouvelle interface :
# ifconfig wg0 wg0: flags=8082<BROADCAST,NOARP,MULTICAST> mtu 1420 index 5 priority 0 llprio 3 wgport 4545 wgpubkey x9VXlh4AMa2YRjTMRVE39pQRsFHRJHUYrATL6vkqFmU= groups: wg
La ligne commençant par "wgpubkey" vous renseigne sur la clé publique utilisée par le serveur. Il faudra la préciser pour les clients, prenez-en note.
Prenez-bien note aussi de la clé privée du serveur : on l'utilisera tout à l'heure dans un fichier pour automatiser toute la procédure en cours.
Sur un client
On fait la même chose que sur le serveur, c'est à dire créer une clé privée puis une interface wg0 associée (nul besoin de préciser le port):
# openssl rand -base64 32 q/7uIx6wBIRUIdxOi5D6OWEQRVUt2AXhMj7j29W/s3s= # ifconfig wg0 create wgkey q/7uIx6wBIRUIdxOi5D6OWEQRVUt2AXhMj7j29W/s3s= # ifconfig wg0 |grep wgpubkey wgpubkey V3pCAhxnRl0QEL8luB9D4EvTVxGT7QGDDCZ3O26kY3A=
Redirection du traffic à travers le serveur
Ici, on souhaite que le serveur se constitue comme une sorte de relai entre le client et le reste du réseau.
On doit pour cela activer la redirection d'IP sur les paquets passant par le serveur :
# sysctl net.inet.ip.forwarding=1
Pour que ça soit automatique, ajoutez cette ligne dans "/etc/sysctl.conf" :
net.inet.ip.forwarding=1
Si vous voulez faire de même en IPv6, utilisez plutôt:
net.inet6.ip6.forwarding=1
De plus, il faudra ajouter une règle pour faire du nat avec le parefeu :
# Ouverture du port 4545 en UDP pass in proto udp from any to any port 4545 keep state # Ce qui vient du VPN (wg0) est NATté vers l'interface "publique" du # serveur match out on egress from (wg0:network) to any nat-to (egress) # la règle match doit être avant un "pass out on egress..." final pass on egress from (wg0:network) to any pass in on wg0
Creusons le tunnel
Maintenant qu'on dispose de tout le nécessaire pour identifier client et serveur, on peut creuser le tunnel. Pour ça, on va notamment ajouter les clés publiques des clients sur le serveur, et inversement. On va aussi indiquer les IP autorisées à utiliser le tunnel.
Afin de gagner du temps pour la suite et rendre les choses plus simples, nous allons désormais directement éditer les fichiers "/etc/hostname.wg0". Ainsi, lors d'un futur redémarrage, la configuration sera intacte.
Prêtez bien attention aux clés utilisées, ce sont les mêmes que celles obtenues juste avant pour vous aider à vous repérer. 😉
Sur le serveur :
Le fichier "/etc/hostname.wg0" contient maintenant:
inet 10.0.0.1/24 wgkey r8uSGD6vyycE5n5/atU9/NX9JQPo4SJryNGpjbQG+rA= wgport 4545 wgpeer V3pCAhxnRl0QEL8luB9D4EvTVxGT7QGDDCZ3O26kY3A= wgaip 10.0.0.2/32 up
Quelques explications :
- wgkey : c'est la clé privée du serveur qui lui permettra de déchiffrer le traffic. Cette clé doit rester secrète. C'est celle qu'on a créé précédemment.
- wgport : le port d'écoute, on avait choisi le 4545.
- wgpeer : c'est la clé publique du client. Ça permettra au serveur de chiffrer le traffic à destination du client.
- wgaip : Adresse IP pour le client autorisée à établie le VPN. Remarquez ici le "/32" pour pouvoir plus tard ajouter d'autres clients sans confusions.
- inet: C'est l'adresse IP de l'interface dans le VPN.
- up : l'interface est activée au démarrage.
Vous pouvez ajouter autant de lignes "wgpeer" que vous voulez. C'est bon à savoir si vous souhaitez proposer un accès à plusieurs machines 😉. Cependant, chaque client disposera de sa propre IP. Par exemple :
wgpeer V3pCAhxnRl0QEL8luB9D4EvTVxGT7QGDDCZ3O26kY3A= wgaip 10.0.0.2/32 wgpeer m7K/gfmMPYRJx1IOP01zYrNbEuMnnZ29xN4OBgRoRXo= wgaip 10.0.0.3/32 wgpeer qnuq5MgezCDHXsYYGmrcegPCNcJvz9EOIG3XyHp1DBk= wgaip 10.0.0.4/32
Sur le client :
Le fichier "/etc/hostname.wg0" du client fonctionne comme pour le serveur, à ceci près qu'on doit notamment préciser où trouver le serveur ("wgendpoint") et modifier les routes par défaut pour que le traffic passe par le tunnel.
wgkey q/7uIx6wBIRUIdxOi5D6OWEQRVUt2AXhMj7j29W/s3s= wgpeer x9VXlh4AMa2YRjTMRVE39pQRsFHRJHUYrATL6vkqFmU= wgendpoint chezmoi.tld 4545 wgaip 0.0.0.0/0 inet 10.0.0.2/24 wgrtable 1 !route add -net default 10.0.0.1 up
- wgkey : clé privée du client.
- wgpeer : clé publique du serveur.
- wgendpoint : IP publique ou nom de domaine du serveur, suivi du port pour y accéder. Si vous choisissez comme dans l'exemple d'indiquer le nom de domaine, comprenez que votre machine doit être capable de résoudre les noms de domaine pour que le tunnel fonctionne. Dans le doute, préférez l'IP.
- wgaip : En indiquant la valeur "0.0.0.0/0", on permet l'envoi des paquets vers n'importe quelle IP. Ça tombe bien, le tunnel doit pouvoir fonctionner peu importe l'IP du serveur.
- inet : adresse IP du client dans le VPN
- wgrtable : les échanges avec le serveur se font sur la table de routage 1. On s'en servira juste après
- !route add -net default 10.0.0.1 : on modifie la route par défaut vers le bout du tunnel, c'est à dire l'IP du serveur.
Ouvrez le tunnel avec la commande suivante sur le serveur et le client :
# sh /etc/netstart wg0
Modifiez la configuration correspondant à l'interface du client pour lui préciser de passer par la table de routage 1. Par exemple, dans "/etc/hostname.em0" :
dhcp rdomain 1 up
Vous pouvez désormais vérifier que lorsque vous naviguez sur internet, votre nouvelle IP est celle du serveur.
Configuration de clients utilisant d'autres systèmes d'exploitation
Comme je le disais plus haut, Wireguard est bien supporté par la plupart des systèmes. Cherchez "Client wireguard -nom-de-votre-plateforme-" pour trouver votre bonheur. Par exemple, pour Android, on peut trouver un client dans les dépôts F-droid.
Système supportés par Wiregard
Voici le minimum à préciser :
Interface :
- Générer clé privée et clé publique. Copier la clé publique dans "/etc/hostname.wg0" sur le serveur de sortie.
- Adresses : 10.0.0.5/24 par exemple, selon l'ip choisie dans "/etc/hostname.wg0" sur le serveur
- Choisir "Toutes les application"
Pair :
- Clé publique du serveur de sortie
- Adresses IP autorisées : 0.0.0.0/0
- Point de terminaison : 192.0.2.2:4545 (ip.du.serveur.sortie:port)
Pour aller plus vite
On a précisé ici comment déployer le VPN avec les outils de base dans OpenBSD. Sachez que vous pouvez installer le port "wireguard-tools" qui pourra vous faire gagner du temps sur la gestion des clés.
Ressources
Ce tutoriel est très largement inspiré des liens suivants :
- https://xosc.org/wireguard.html
- https://lipidity.com/openbsd/wireguard/
- https://man.openbsd.org/wg
- https://codimd.laas.fr/s/NMc3qt5PQ