Wireguard, le VPN revisité (Linux)
Wireguard est une nouvelle technologie de VPN qui se veut plus sécurisé et plus perfomant que ses concurrents. Il est différent de l'IPSEC et de l'OPENVPN par sa facilité de mise en place et sa volonté de rester simple.
Wireguard est une nouvelle technologie de VPN qui se veut plus sécurisé et plus performant que ses concurrents.
Il est différent de l'IPSEC et de l'OPENVPN par sa facilité de mise en place et sa volonté de rester simple.
Wireguard se veut aussi simple à configurer et à déployer que le protocole SSH, une session VPN se fait simplement en échangeant les clés publiques - exactement comme l'échange de clés SSH - tout le reste est géré de manière transparente par WireGuard.
L'échange de la clé publique à l'hôte voisin permet à Wireguard d'établir et d'échanger une Preshared-Key. Un chiffrement assymétrique est donc appliqué pour échanger cette clé entre les deux hôtes, cette PSK est ensuite renouvelée régulièrement.
Wireguard a l'avantage de proposer une interface virtuelle wg0
qui peut être configurée en utilisant les outils déjà présents sous Linux tels que ip(8)
et ifconfig(8)
.
Nous verrons dans la suite de la présentation comment mettre en place des tunnels VPNs avec Wireguard.
Lexique :
- private-key : clé privée associée à l'interface wireguard.
- public-key : clé publique dérivée de la clé privée.
- endpoint : adresses IPs des peers sur laquelle la session VPN est établie, un port UDP est aussi nécessaire.
- allowed-ips : réseaux autorisés au sein du VPN.
Installation de wireguard (debian)
echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' > /etc/apt/preferences.d/limit-unstable apt update apt install wireguard
Postulat de base
Chacun des 3 sites ci-dessus se trouvent dans des pays différents et sont séparés par des réseaux dits "publiques", ils ont chacun une IP publique attribuée (ici représenté par le réseau 192.168.1.0/24).
Nous établirons des sessions VPNs entre ces trois sites grâce au protocole Wireguard, pour ensuite annoncer les réseaux clients (172.16.1.0/24, 10.0.2.0/24, 77.66.55.0/24) et enfin nous configurerons la sortie Internet via l'un des sites (Moly).
Dans cet exemple, chacun des sites va établir 2 sessions VPN vers les 2 autres voisins car ceux ci sont directement joignables. Dans certains cas ce n'est pas possible (réseau naté, réseau mobile etc.) il faut alors choisir un site accessible publiquement qui aura le rôle de Hub.
Les différentes étapes à réaliser :
- Mise en place de tous les peers VPN; giant <-> raspi, giant <-> moly etc.
- Routage des réseaux clients des 3 sites.
- Mise en place de la sortie internet.
Nous aurons ainsi l'occasion de jouer avec le routage et l'iptable sous Linux (Debian dans notre cas).
Mise en place des sessions VPN entre les trois sites
Tout d'abord nous devons générer une clé privée et sa clé publique associée sur l'ensemble des endpoints (peers):
wg genkey | tee private.key | wg pubkey > public.key
Nous devons ensuite créer sur chacune des machines une interface virtuelle wg0 qui sera capable d'établir autant de peer que l'on souhaite.
Nous associons ensuite la clé privée à l'interface virtuelle wg0.
Cela peut-être fait de deux façons, la première est de rentrer chacune des commandes manuellement, la seconde est d'utiliser le script wg-quick en se basant sur un fichier de configuration. Nous verrons les deux cas.
Sur Moly et Giant (wg-quick) :
Le script wg-quick de Wireguard s'appuie sur un fichier de configuration dans lequel nous devons définir les paramètres de l'interface wg0 et les informations des peers (public-keys, endpoint, allowed-ips). Il améliore grandement le déploiement et permet dans un seul fichier de définir l'ensemble des paramètres.
Respectivement ces deux machines auront une interface virtuelle wg0 avec une clé privée, et deux peers avec leurs clés publiques associées :
#Giant [Interface] Address = 172.16.1.1/24 SaveConfig = true ListenPort = 5555 PrivateKey = UCQhBHQF08IKvMdUXl7IPL8+iPSx41tO4J3q0e1bwGE= #Moly [Peer] PublicKey = p65NVxgVdoeIHQfi/Tmp2MgYDJLjGo0TUBz7iatVXBw= AllowedIPs = 172.16.1.2/32 Endpoint = 192.168.1.162:5555 #Raspi [Peer] PublicKey = KY0qEDi4bOKDxqKj9yt6kczUuZpYetOyQNKkXRfc+Uw= AllowedIPs = 172.16.1.3/32 Endpoint = 192.168.1.200:5555
On lance ensuite le script qui aura pour rôle de créer l'interface wg0, d'associer l'adresse IP et la clé privée, puis enfin de configurer les peers et d'ajouter les routes.
wg-quick up wg0
On vérifie que la session entre Moly et Giant fonctionne :
La commande wg permet d'afficher les statistiques des peers.
Création de l'interface et association des peers manuellement :
Sur raspi nous n'utiliserons pas la commande wg-quick, nous ferons la configuration manuellement :
Création de l'interface virtuelle :
ip link add dev wg0 type wireguard
Association de l'ip sur l'interface virtuelle :
ip address add dev wg0 172.16.1.3/24
Configuration du peer vers Moly :
wg set wg0 listen-port 5555 private-key private.key peer p65NV.. allowed-ips 172.16.1.2/32 endpoint 192.168.1.162:5555
Il est aussi possible d'utiliser le fichier /etc/network/interfaces afin d'établir la session VPN au démarrage du poste.
Exemple pour moly dans /etc/network/interfaces :
auto wg0 iface wg0 inet static address 172.16.1.2 netmask 255.255.255.0 pre-up ip link add $IFACE type wireguard pre-up wg setconf $IFACE /etc/wireguard/$IFACE.conf post-down ip link del $IFACE post-up ip route add 77.66.55.0/24 dev wg0
Le fichier wg0.conf doit être rempli avec les informations du peer (endpoint, allowed-ips, public_key etc.) comme vu plus haut.
Si l'on admet que le script wg-quick ait été utilisé sur tous les peers, voici le contenu du fichier wg0.conf et les clés privées/publiques des 3 sites :
Le routage entre les différents sites
Pour imiter le réseau client de chacun des sites nous créeons des interfaces loopbacks dans /etc/network/interfaces
.
auto lo:10 iface lo:10 inet static address 10.0.2.1 netmask 255.255.255.0
Par défaut, et lorsque l'on utilise le script wg-quick
, les routes des réseaux allowed-ips sont automatiquement ajoutées.
Si l'on ajoute un peer manuellement il faudra alors penser à ajouter manuellement les routes associées.
Route par défaut
Nous allons maintenant considérer Raspi et Giant comme des clients, l'ensemble des flux seront routés vers Molly pour accéder à internet.
Sur le client :
[Peer] PublicKey = p65NVxgVdoeIHQfi/Tmp2MgYDJLjGo0TUBz7iatVXBw= AllowedIPs = 0.0.0.0/0 Endpoint = 192.168.1.162:5555
On relance ensuite wg-quick qui aura pour rôle de remplacer la route par défaut par une nouvelle à destination du tunnel wg0.
Sur le serveur, on NAT les flux provenants des réseaux clients :
On active le routage : echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s 77.66.55.0/24 -j MASQUERADE
L'ensemble des flux sont maintenant routés et chiffrés depuis les clients vers le serveur Moly.
Capture de paquet
Ci-dessous une capture de paquet entre Giant et Raspi, on observe l'encapsulation UDP sur le port 5555.