Serveur wireguard
VPN wireguard pour Debian Bullseye
par Petitchat
Introduction
Wireguard a été intégré dans le noyau Linux depuis mars 2020. C'est dire le succès de ce VPN. Fiable, rapide, bien sécurisé, facile à configurer...Cela devient évident de chiffrer ses données dans un tunnel pour rejoindre un réseau virtuel ou/et partager une adresse IP.
Prérequis et conventions pour le tuto
- Une machine Debian en guise de serveur Wireguard avec les droits administrateurs
- Pour les tests une machine connectée à Internet en dehors du réseau local, de n’importe quelle plate-forme, nécessaire comme client
- Savoir mettre en place un routage NAT sur sa box
- L'adresse IP publique de la box est 87.65.43.21
- le serveur vpn est dans un réseau physique de classe C, par exemple ici le réseau 192.168.15.0/24 et on fixe son adresse à 192.168.15.2
Installation
On met à jour les dépots apt :
sudo apt update
On installe simplement :
apt install wireguard
Puis nous créons un espace de travail: sur le Bureau le dossier "wireguard" et dans le dossier wireguard les dossiers "serveur" et "utilisateurs".
cd Bureau
mkdir wireguard ; cd wireguard ; mkdir serveur; mkdir utilisateurs
Génération des clés du serveur
On se place dans le dossier "serveur"
cd serveur
Nous allons créer une clé privée. Comme il s'agit d'un fichier secret, la commande wg nous force à utiliser la commande umask afin de restreindre les droits en lecture pour ce fichier.
umask 077
sudo wg genkey > wg-private.key
créer une clé publique avec la clé privée
sudo wg pubkey < wg-private.key > wg-public.key
Paramétrage de l'interface virtuelle
Wireguard fonctionne avec une interface réseau virtuelle qu'il faut paramétrer en créant, avec les droits administrateur, un fichier configuration. Wireguard utilise un format de nommage particulier pour ce fichier: <nom_de_l'interface>.conf. Nous nommons le fichier "wg0.conf" ainsi le nom de l'interface virtuelle sera "wg0".
sudo nano /etc/wireguard/wg0.conf
Nous y collons ce paramétrage:
# define the WireGuard services [Interface] Address = 10.0.15.1/24 # contents of file wg-private.key that was recently created PrivateKey = UKXwwKH+p2tNrZLzRI7TLyoAjoPUE2NC243lQVluBVU= # UDP service port; 51820 is a common choice for WireGuard ListenPort = 51820 PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o <interface> -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o <interface> -j MASQUERADE
Attention !!! il faut remplacer <interface> par le nom de l'interface physique. Pour connaître le nom de cette interface on peut utiliser la commande:
ip -o -4 route show to default | awk '{print $5}'
Dans mon cas l'interface s'appelle "ens33"
Explications des paramètres:
- <Address>, ici il faut choisir un réseaux de classe C, dans cet exemple le réseau 10.0.15.0/24. Il faut aussi choisir l'adresse du serveur wireguard dans le réseau, dans cet exemple de digit 1. Ce qui donne 10.0.15.1/24. Il faut choisir un sous réseau différent de son réseau local usuel, elle pourront quand même atteindre les machines du réseau local (dans mon cas 192.168.15.0/24).
- <PrivateKey>, précise la clef privée du serveur, c'est une donnée secrète.
- <ListenPort>, précise le port d'écoute du serveur, si on passe par une box il faut faire un routage NAT vers ce port.
- <PostUp>, ajoute une règle de routage lorsque l'interface virtuelle démarre. La règle de routage redirige le traffic de l'interface physique vers l'interface virtuelle du vpn.
- <PostDown>, supprime la règle de routage losque l'interface est éteinte.
Paramétrages réseau
A propos de règles de routage, on a besoin d'iptables, si ce n'est pas déjà fait il faut l'installer:
apt install iptables
et il faut l'activer iptables avec cette commande:
systemctl enable iptables
A ce stade on peut tester la configuration avec la commande
sudo wg-quick up wg0
Si la configuration de wg0.conf ne contient pas d'erreur on devrait obtenir ceci:
[#] ip link add wg0 type wireguard [#] wg setconf wg0 /dev/fd/63 [#] ip -4 address add 10.0.15.1/24 dev wg0 [#] ip link set mtu 1420 up dev wg0 [#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
on peut maintenant voir l'interface, un
sudo wg show wg0
donne ceci:
interface: wg0 public key: kjuD10RMEyU8eNYVnQNrBXx6StrokXg9fUKt4rDI4RU= private key: (hidden) listening port: 51820
On ferme l'interface proprement ainsi:
sudo wg-quick down wg0
L'activation du routage IPv4 se fait également dans le fichier /etc/sysctl.conf qu'il faut éditer et vérifier que cette directive est activée:
net.ipv4.ip_forward = 1
On peut vérifier que le changement est pris en compte avec la commande:
cat /proc/sys/net/ipv4/ip_forward
qui renvoie "1" si elle est activée.
désactiver networking.service sinon il rentre en conflit avec wg-quick qui le remplace:
sudo systemctl disable networking.service
Les utilisateurs du parefeu UFW pourront entrer cette règle:
sudo ufw allow 51820/udp
Retour à l'interface réseau
Debian reconnaît aussi un service qui permet de contrôler l'interface virtuelle. Il s'agit de wg-quick@<nom_interface>.service, donc pour nous wg-quick@wg0.service. Nour allons maintenant rendre les changements permanents au démarrage:
sudo systemctl enable wg-quick@wg0.service
On peut lancer le service ainsi:
sudo systemctl start wg-quick@wg.service
ce qui démarre l'interface virtuelle mais sans les messages.
On peut arrêter le service avec la commande:
sudo systemctl stop wg-quick@wg0.service
Et s'il y a lieu, le redémarrer:
sudo systemctl restart wg-quick@wg0.service
Pour surveiller l'état du service on pourra utiliser la commende « status » :
sudo systemctl status wg-quick@wg0.service
Il est également possible de voir l’historique de la création de l'interface en consultant le journal:
journalctl -u wg-quick@wg0.service
Malheureusement ces commandes ne donnent pas d'information sur les connexions des pairs. Pour cela il faut paramétrer un système de journalisation plus poussé.
La dernière étape du paramétrage réseau consiste à établir un routage NAT du port 51820 vers notre serveur wireguard d'adresse IP privée 192.168.15.1.
Coté client
Dans cette exemple nous allons créer manuellement une connexion pour l'utilisateur Sigmund. On lui créé un dossier dans le répertoire /wireguard/utilisateur et on se place dans ce dossier.
cd utilisateur
sudo mkdir sigmund
cd sigmund
Comme pour le serveur nous allons générer une paire de clés publique/privée.
D'abord la clé privée:
umask 077
sudo wg genkey > wg-sigmund-private.key
Puis une clée publique avec la clée privée:
sudo wg pubkey < wg-sigmund-private.key > wg-sigmund-public.key
Ceci fait nous allons créer le fichier configuration du client Sigmund. Editons le fichier "wgsigmund.conf":
sudo nano wgsigmund.conf
on y ajoute le paramétrage suivant:
[Interface] PrivateKey = <clef privée de sigmund> Address = 10.0.15.2/32 [Peer] PublicKey = <clef publique du serveur> AllowedIPs = 10.0.15.0/24, 192.168.15.0/24 Endpoint = 87.65.43.21:51820 PersistentKeepalive = 25
Explication des paramétres:
Le fichier contient deux sections:
La section [Interface]
- <PrivateKey>, ici il faut reporter la clé privée du client. Pour le faire il est pratique d'ouvrir une deuxième console, de se placer dans le dossier "sigmund" et de lancer la commande:
sudo cat wg-sigmund-private.key
- <Address>, l'adresse de l'interface client dans le sous réseau du vpn. 10.0.15.1 est prise par le serveur, on peut prendre l'adresse suivante qui est 10.0.15.2. "/32" est la notation cidr pouor une adresse IP.
La section [Peer]
- <PublicKey>, il faut reporter ici la clée publique du serveur (de la même façon qu'on a reporter plus haut la clé privée du client)
- <AllowedIPs>, ce paramètre corresponds aux réseaux que pourra atteindre le client. 10.0.15.0/24 est le sous réseau du vpn, le client pourra joindre les autres machines de ce sous réseau. 192.168.15.0/24 correspond au réseau local physique dans lequel se trouve le serveur wireguard, les clients pourront aussi joindre les machines de ce réseau. Enfin, dans ce champs, si l'on remplace ces réseaux par les réseaux 0.0.0.0/1 et 128.0.0.0/1 alors tout le trafic est redirigé vers le vpn, le client passe par le serveur vpn pour ses requêtes Internet. Bref, avec ce réglage, le client partage l'adresse IP publique du serveur.
- <Endpoint>, il s'agit de l'adresse IP publique du serveur ainsi que le port, soit dans notre exemple 87.65.43.21:51820
- <PersistentKeepalive>, ce paramètre indique, en seconde, le délai entre deux paquets keepalive. Ces paquets servent à maintenir la connexion active. On peut mettre cette valeur à 25.
Lorsque ceci est fait on enregistre le fichier et on quitte l'éditeur (Ctrl+X). Remarque: les fichiers configurations des clients contiennent leur clef privée qui est une donnée confidentielle, donc il faut gérer les droits des fichiers en conséquence.
Ajout du client coté serveur
Le serveur wireguard ne se connecte qu'aux machines dont il connaît à minima la clé publique. Il faut donc enregistrer celle-ci. Il existe une méthode rapide qui consiste en cette ligne de commande:
wg set wg0 peer CLIENT_PUBLIC_KEY allowed-ips 10.0.15.0/24, 192.168.15.0/24
Cette méthode rapide souffre de ne pas être persistante, de ne pas résister à un redémarrage. Heureusement il existe une autre méthode pour pérenniser les enregistrements des utilisateurs. Pour cela il faut d'abord éditer le fichier /etc/wireguard/wg0.conf avec les droits administrateurs:
sudo nano /etc/wireguard/wg0.conf
Nous allons enregistrer le client sigmund en ajoutant ces lignes en toute fin de fichier:
[Peer] #sigmund PublicKey = <clef publique de sigmund> AllowedIPs = 10.0.15.2/32 PersistentKeepalive = 25
Puis enregistrons les changements et quittons l'éditeur. Pour prendre en compte le nouveau client il faut redémarrer le service wg-quick:
sudo systemctl restart wg-quick@wg0.service
S'il n'y a pas d'erreur la commande:
sudo wg show wg0 (ou seulement sudo wg show)
affiche la configuration du serveur et les dernières lignes affichent les pairs.
Si l'on veut ajouter un autre pair, alors il faut rajouter les 5 lignes de paramètres en commençant pas [Peer].
Configurations sur la machine de test
Wireguard client existe pour la plupart des systèmes d'exploitation. On trouve le logiciel client sur cette page https://www.wireguard.com/install/ , dans l'appstore, l'applestore etc... On l'installe. Tout à l'heure nous avons créé un fichier de configuration pour l'utilisateur Sigmund qui s'appelle wgsigmund.conf, c'est le moment de le transférer sur notre machine cliente. Puis:
- connecter la machine cliente à Internet en la laissant déconnectée du réseau local
- lancer wiregard
- choisir "ajouter tunnel"
- choisir le fichier wgsigmund.conf; si tout se passe bien wiregard charge la configuration
Test du client
Le moment de vérité.
- pour le test désactiver le pare-feu du client s'il y a lieu. On réglera le pare-feu quand déjà ça marchera sans.
- dans wireguard, lancer la connexion
La connexion est établie lorsque wireguard indique un transfert d'octets entre le client et le serveur.
Pour être sûr, si l'on peut, on lance un
ping 10.0.15.1
qui devrait répondre, de même qu'un
ping 192.168.15.2
étant donné que le réseau 192.168.15.0/24 est normalement accessible via le vpn depuis Internet.
Le MTU
MTU est le sigle pour l'anglais "maximum transmission unit". C'est une valeur dont l'unité est l'octet. Du point de vu IP, couche réseau (couche 3) du modèle OSI, les interfaces serveur et cliente communiquent via des paquet IP qui contiennent entre autre les données à échanger entre les postes. Le MTU désigne la taille maximale des paquets IP qui circulent dans le VPN. En d'autres termes Wireguard fragmente l'information en paquets dont la taille est égale ou inférieure au MTU. Pour acheminer les données, les paquets IP sont aussi constitués, outre les données, d'une en-tête IP de 20 octet et d'une en-tête UDP de 8 octets qui sont autant d'information d'acheminement. Pour simplifier la problématique du MTU: plus il est élevé et plus le débit est rapide mais perd en fiabilité, ou, dit à contrario, plus le MTU est bas, plus le transfert est fiable mais lent. Dans Wireguard, le MTU du serveur et du client est fixée à 1420 octets ce qui est déjà un bon compromis. C'est pourquoi nous laissons cette valeur par défaut. Il est toutefois possible de la modifier aussi bien pour le serveur que pour le client. Il faut pour cela éditer le fichier de configuration et ajouter dans la section [Interface] la ligne:
MTU = <valeur>
Jouer en LAN avec Wireguard
Nous avons essayer divers jeux windows via un serveur Debian 11 et Wireguard. Certains jeux fonctionnent en LAN facilement et d'autre non; en particulier certains jeux ne permettent pas de se connecter nominativement à une adresse IP précise et utilisent impérativement le broadcast qui justement ne passe pas dans le VPN. Certains jeux, alors que les joueurs sont dans le même réseau local virtuel, nécessitent la configuration "0.0.0.0/0" ou "0.0.0.0/1, 128.0.0.0/1" dans les AllowedIPS du client pour fonctionner, c'est le cas d'Age of Mythology par exemple.
Script de création de compte pour Wireguard
Générer les clefs du client, son fichier configuration, enregistrer le client dans le fichier configuration du serveur, relancer le service, tout cela multiplier par le nombre d'utilisateur : la tâche peut s'avérer fastidieuse et répétitive à la longue. C'est pourquoi je vous fais don d'un script de création de compte que j'ai écrit.
Installation du script
- Il faut placer ce script dans le dossier « […]/Bureau/wireguard » qu'on a créer précédemment, dossier qui contient les sous dossier « serveur » et « utilisateurs »
- Dans le dossier « utilisateur » il faut créer le fichier « nextip ». Ce fichier ne contient qu'un nombre entier qui correspond au prochain digit qu'on utilisera pour créer un utilisateur. Si pour l'instant on n'a créé uniquement l'utilisateur Sigmund, alors : « 10.0.15.1 » et prise par le serveur, « 10.0.15.2 » est prise par Sigmund mais « 10.0.15.3 » est libre. On peut alors fixer « nextip » à 3 de cette façon, en se plaçant dans le dossier « utilisateurs » :
echo 3 > nextip
Cette commande créer le fichier « nextip » s'il n'existe pas et lui attribue la valeur « 3 ».
Puis nous créons le fichier du script à proprement parlé :
sudo nano wgadduser
On y colle se code abondamment commenté :
#!/bin/bash # wgadduser "utilisateur" ajoute un utilisateur à wireguard declare -i digit ; clear ; #teste si le nom de l'utilisateur a été précisé if [[ -z "$1" ]]; then echo "syntaxe: ./wgadduser <utilisateur> " ; exit 0 ; fi #récupération de la clé publique du serveur pbkeysrv=$(head ./serveur/wg-public.key) ; #changement de dossier courant cd utilisateurs ; #récupération de nextIP digit=$(head nextip) ; #création du dossier utilisateur #faire commencer le nom du dossier par $digit permet de lister #les dossiers dans l ordre de création et d adresse ip mkdir $digit.$1 ; cd $digit.$1 ; #génération et récupération de la clé privée nmprkey=wg-"$1"-private.key ; umask 077 ; wg genkey > $nmprkey ; prkey=$(head $nmprkey) ; #génération et récupération de la clé publique nmpbkey=wg-"$1"-public.key ; wg pubkey < $nmprkey > $nmpbkey ; pbkey=$(head $nmpbkey) ; #génération du fichier wg-utlisateur.conf confile=wg"$1".conf ; echo "[Interface]" > $confile ; echo "PrivateKey = "$prkey >> $confile ; echo "Address = 10.0.15."$digit"/32">> $confile ; echo "MTU = 1384" >> $confile ; echo "" >> $confile ; echo "[Peer]" >> $confile ; echo "PublicKey = "$pbkeysrv >> $confile ; echo "AllowedIPs = 10.0.15.0/24, 192.168.15.0/24" >> $confile ; echo "Endpoint = 82.65.96.172:51820" >> $confile ; echo "PersistentKeepalive = 25" >> $confile ; #affichage du fichier cat $confile; #choix de validation ou d'annulation while true ; do read -p "Valider l'enregistrement ? y/n" choix case $choix in [YyOo]* ) break ;; [Nn]* ) cd ..; rm -R $1; exit 0 ;; * ) echo "Répondre oui (o) ou non (n)" ;; esac done clear ; #ajout de l'utilisateur à /etc/wireguard/wg0.conf config="/etc/wireguard/wg0.conf" ; echo "" >> $config ; echo "[Peer]" >> $config ; echo "#"$1 >> $config ; echo "PublicKey = "$pbkey >> $config ; echo "AllowedIPs = 10.0.15."$digit"/32" >> $config ; echo "PersistentKeepalive = 25" >> $config ; #incrémentation de nextip digit=$((digit+1)) ; cd .. ; echo $digit > nextip ; #proposition de redémarrage du service echo "L\'utilistaeur "$1" a bien été enregistré" ; while true ; do read -p "Faut-il redémarrer l'interface pour prendre en compte les changements ? (O)ui ou (N)on" choix1 ; case $choix1 in [YyOo]* ) break;; [Nn]* ) exit 0 ;; * ) echo "Répondre oui (o) ou non (n)" ;; esac done systemctl restart wg-quick@wg0 ; echo "service relancé, fin du script, merci !" ; exit 0 ;
Enfin on rend le script executable avec la commande:
sudo chmod +x wgadduser
Fonctionnement du script
la syntaxe du script est
./wgadduser <utilistateur>
par exemple
./wgadduser donald
va créer l'utilisateur donald automatiquement. Le script est commenté de façon à comprendre ce qu'il fait au fur et à mesure. Une fois la commande lancée le script affiche les informations avec lesquelles il va procéder à l'enregistrement, il est possible d'annuler la création à ce moment. Si on valide le choix de création, alors :
- Dans le dossier « utilisateurs» est créé un nouveau dossier. Son nom respecte la syntaxe <dernier_digit>.<utilisateur>. Ainsi, avec un simple
ls -al
On aura une correspondance entre utilisateurs et adresses IP dans le VPN ce qui s’avérera fort pratique à l'usage pour identifier les connections.
- Dans ce dossier le script génère la paire de clés nécessaire au chiffrement.
- Toujours dans ce dossier le script génère un fichier de configuration pour l'utilisateur client. Le fichier s'appelle wg<utilisateur>.conf.
- Le script ajoute au fichier de configuration wg0.conf une nouvelle section [Peer] en fin de fichier correspondant à l'enregistrement du nouvel utilisateur.
- Pour finir le script propose de redémarrer le service Wireguard, ce qui permet de ne redémarrer qu'une fois tous les enregistrements faits.
Conclusion
Il est encore possible d'aller plus loin dans la configuration, par exemple ajouter un serveur DNS ou installer le paquet qrencode, ce paquet génère un Qrcode de configuration pour les smartphones. Pour l'heure avec ce tuto on a un serveur wireguard fonctionnel, un script de création des comptes, c'est une bonne mise à l'étrier.
Remerciements
Ont contribué à tester mes vpn Wireguard et à ce tutoriel : Nour, Rico, Watts, Anonimix ; je les remercie particulièrement pour leur patience.
Copyleft Petitchat MMXXII-MMXXIV