Installer un VPN Wireguard sur un serveur Linux Debian (ainsi qu'un Raspberry Pi)
Le but de cet article est de vous permettre de créer un VPN Wireguard sur votre propre serveur et d'être capable de l'administrer, c'est à dire ajouter facilement de nouveaux profils pour se connecter à ce VPN. Vous pourrez ainsi :
- Bénéficier de l'adresse IP V4 et V6 ainsi que de la localisation de votre serveur.
- Communiquer avec les autres appareils connectés à ce serveur VPN.
- N'autoriser certains services du serveur qu'aux appareils connectés au VPN.
Et d'autres cas d'usage plus ou moins avancés que je partagerai dans de futurs articles.
À noter que j'utilise un certain nombre d'automatisations et de variables pour accélerer et simplifier la création de certains fichiers, libre à vous de réaliser cela à la main.
00 | Pré-requis
- Avoir un serveur Linux Debian ou bien un Raspberry Pi à jour.
- Un nom de domaine ou un sous-domaine associé à une adresse IP V4 et/ou V6 fixe(s) qui pointe vers le serveur.
- Avoir les droits
sudo
avec l'utilisateur qui va réaliser l'installation. - Définir un numéro de port UDP qui sera attribué à Wireguard.
01 | Ouvrir le port UDP dédié à Wireguard
J'ai choisi pour cet article le port par défaut
51820
mais je vous conseille d'en choisir un autre par sécurité.
Action à réaliser avec votre logiciel de pare-feu, avec iptables
par exemple :
sudo iptables -A INPUT -p udp –dport 51820 -j ACCEPT
Attention à rendre la règle persistente, avec une solution comme iptables-persistent
, pour ne pas perdre cette configuration au redémarrage de votre serveur.
Personnellement j'utilise ufw
qui est plus simple à prendre en main pour une configuration de pare-feu simple et mémorise par défaut les règles au redémarrage du serveur. Voici ce que donne la commande avec ufw
:
sudo ufw allow 51820/udp
02 | Activer la redirection IPv4/IPv6 au niveau système
Les instructions ci-dessous permettre d'activer les redirections IPv4 et IPv6 au niveau du système :
sudo sed -r -i "s/^\#net\.ipv4\.ip\_forward\=1$/net.ipv4.ip_forward=1/" /etc/sysctl.conf && \
sudo sed -r -i "s/^\#net\.ipv6\.conf\.all\.forwarding\=1$/net.ipv6.conf.all.forwarding=1/" /etc/sysctl.conf && \
sudo sysctl -p
Nous avons simplement éditer le fichier de configuration /etc/sysctl.conf
avec la commande sed
puis nous avons rechargé le service du système de configuration globale pour prendre en compte ces nouveaux paramètres.
Sans cela, la communication Internet ne serait pas effective une fois connecté au VPN.
03 | Installer le paquet Wireguard
sudo apt install wireguard
Celui-ci est disponible par défaut avec les sources officielles de Debian.
04 | Créer les clés de sécurité du VPN Wireguard
privateKey=$(wg genkey | sudo tee /etc/wireguard/private.key) && \
sudo chmod go= /etc/wireguard/private.key && \
publicKey=$(sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key)
Nous avons ici créé la clé privée private.key
ainsi que la clé publique public.key
qui se trouvent chacune dans le dossier /etc/wireguard
, avec une sécurité accrûe sur la clé privée qui n'est lisible uniquement que par le système.
Nous mémorisons dans la session actuelle les valeurs de chacune de ces clés dans les variables privateKey
et publicKey
qui nous serons utiles pour la suite de l'installation.
05 | Créer le fichier de configuration du VPN Wireguard
Nous allons dans un premier temps définir les valeurs des variables suivantes :
- Le numéro de port
portNumber
(dédié à Wireguard)- Attention à bien utiliser la même valeur que précedemment ou laisser vide ce champ pour laisser la valeur par défaut à
51820
.
- Attention à bien utiliser la même valeur que précedemment ou laisser vide ce champ pour laisser la valeur par défaut à
- L'interface réseau externe
interfaceName
(utilisée pour communiquer avec Internet)- Le nom de l'interface sera récupérée automatiquement.
- Le sous-réseau IPv4
ipv4Subnet
(dédié à Wireguard)- Attention à bien utiliser un format d'un réseau IPv4 privé, en omettant le dernier chiffre, si vous ne renseignez rien, la valeur par défaut sera
10.0.1.
.
- Attention à bien utiliser un format d'un réseau IPv4 privé, en omettant le dernier chiffre, si vous ne renseignez rien, la valeur par défaut sera
- Le sous-réseau IPv6
ipv6Subnet
(dédié à Wireguard)- Le sous réseau IPv6 sera généré automatiquement.
nous allons utiliser ces variables juste après pour créer le fichier de configuration.
while ! (echo "$domainNameOrIpAddress" | grep -qP "^((.+\.\w{2,63})|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))$"); do \
read -p "Domain name (or public IP Address): " domainNameOrIpAddress \
; done && \
while ! (echo "$portNumber" | grep -qP "^\d{1,5}$"); do \
read -p "Port number (default: 51820): " portNumber && \
portNumber=${portNumber:-51820} \
; done && \
interfaceName=$(ip route | head -1 | cut -d " " -f5) && \
while ! (echo "$ipv4Subnet" | grep -qP "^\d{1,3}\.\d{1,3}\.\d{1,3}\.$"); do \
read -p "IPv4 subnet (default: 10.0.1.): " ipv4Subnet && \
ipv4Subnet=${ipv4Subnet:-10.0.1.} \
; done && \
ipv6Subnet=$(echo -e 'fd'$(echo -e $(date +%s%N)$(cat /var/lib/dbus/machine-id) | sha1sum | awk '{print $1}' | cut -c 31-)':' | sed 's/.\{4\}/&:/g')
Nous allons maintenant créer le fichier de configuration principal du VPN Wireguard en s'appuyant sur les variables générées précedemment.
Par convention, le fichier de configuration principal du serveur s'appelle
wg0.conf
. Vous êtes libres de choisir un autre nom si vous préférez. Pour cela, modifier simplement les valeurs au niveau des commandessudo tee
etsudo chmod
sur la dernière ligne ci-dessous.
echo -e "[Interface] \n\
Address = ${ipv4Subnet}1/24 \n\
Address = ${ipv6Subnet}1/64 \n\
SaveConfig = true \n\
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -I FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o $interfaceName -j MASQUERADE \n\
PostUp = ip6tables -I FORWARD -i %i -j ACCEPT; ip6tables -I FORWARD -o %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o $interfaceName -j MASQUERADE \n\
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o $interfaceName -j MASQUERADE \n\
PostDown = ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -D FORWARD -o %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o $interfaceName -j MASQUERADE \n\
ListenPort = $portNumber \n\
PrivateKey = $privateKey" | sudo tee /etc/wireguard/wg0.conf > /dev/null && sudo chmod go= /etc/wireguard/wg0.conf
Nous avons donc renseigné dans le fichier /etc/wireguard/wg0.conf
les valeurs du sous-réseau IPv4 & IPv6, créer les règles iptables
indispensables au lancement ou l'arrêt du VPN pour permettre la bonne communication entre les clients et le VPN Wireguard, nous avons indiqué le numéro du port, renseigné la clé privée du VPN Wireguard et nous avons enfin sécuriser ce fichier.
Vous devriez pouvoir afficher ce fichier grâce à la commande suivante :
sudo cat /etc/wireguard/wg0.conf
Et vérifier que le contenu ressemble à cet exemple :
[Interface]
Address = 10.0.1.1/24
Address = fdc8:1911:07cd::1/64
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -I FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostUp = ip6tables -I FORWARD -i %i -j ACCEPT; ip6tables -I FORWARD -o %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PostDown = ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -D FORWARD -o %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
PrivateKey = <contenu-du-fichier-/etc/wireguard/private.key>
Si vous constatez une erreur ou une absence, vous pouvez bien entendu éditer le fichier à la main en utilisant la commande sudo vi
ou sudo nano
sur le fichier /etc/wireguard/wg0.conf
.
05 | Activer le VPN Wireguard au démarrage du serveur et lancer le VPN immédiatement
sudo systemctl enable wg-quick@wg0 && \
sudo systemctl start wg-quick@wg0
Vérifiez le bon fonctionnement grâce à la commande suivante :
sudo systemctl status wg-quick@wg0
Vous devriez voir le statut "active" en vert.
Vérifiez également que l'interface virtuelle de Wireguard a bien été créée :
sudo ifconfig wg0
Si tout est bon, passons maintenant à la suite, à savoir la configuration d'un client qui pourra se connecter à ce VPN.
06 | Créer les clés de sécurité du client
sudo mkdir -p /etc/wireguard/.clients && \
clientNumber=$((2 + $(sudo ls /etc/wireguard/.clients | grep --count \.conf || true))) && \
clientId=$(printf "%02d" $clientNumber) && \
clientPrivateKey=$(wg genkey | sudo tee /etc/wireguard/.clients/client-${clientId}-private.key) && \
sudo chmod go= /etc/wireguard/.clients/client-${clientId}-private.key && \
clientPublicKey=$(sudo cat /etc/wireguard/.clients/client-${clientId}-private.key | wg pubkey | sudo tee /etc/wireguard/.clients/client-${clientId}-public.key)
Nous avons ici créé ou vérifié l'existance du dossier /etc/wireguard/.clients
, nous avons également vérifier si un ou plusieurs clients existaient déjà, dans ce cas nous incrémentons l'ID du client en en comptant l'ensemble des clients déjà créés. Sinon, on partira de 02. (01 étant si l'on veut déjà attribué au VPN, on y reviendra plus tard, notamment sur la désignation des adresses IP).
Par exemple si j'ai déjà deux clients de créés, le nouveau client aura l'ID "04", sa clé privée sera /etc/wireguard/.clients/client-04-private.key
.
07 | Créer le fichier de configuration du client
echo -e "[Interface] \n\
PrivateKey = $clientPrivateKey \n\
Address = ${ipv4Subnet}${clientNumber}/24, ${ipv6Subnet}${clientNumber}/64 # IPv4 & IPv6 that will be defined for the Wireguard's client \n\
DNS = ${ipv4Subnet}1/24, ${ipv6Subnet}1/64 \n\
# DNS = 1.1.1.1, 2606:4700:4700::1111 \n\
\n\
[Peer] \n\
PublicKey = $publicKey \n\
AllowedIPs = 0.0.0.0/0, ::0 # To be used to tunnel all the traffic through the VPN between the client & the server \n\
# AllowedIPs = ${ipv4Subnet}.0/24, ${ipv6Subnet}/64 # To be used to be only connected remotely to the server, but not sending through all the traffic \n\
Endpoint = ${domainName}:{portNumber} # Endpoint to be configure as domain name or IP plus the port that is listened by Wireguard's server \n\
# PersistentKeepalive = 60 # To keep the connection alive in case of connectivity issues" | sudo tee /etc/wireguard/.clients/client-${clientId}.conf > /dev/null && sudo chmod go= /etc/wireguard/.clients/client-${clientId}.conf
Plusieurs remarques ici, la partie DNS part du principe que vous avez déjà un service DNS fonctionnel hébergé sur votre serveur, ce que je vous recommande chaudement.
Si ce n'est pas le cas, vous pouvez remplacer la ligne par DNS = 1.1.1.1, 2606:4700:4700::1111
si vous souhaitez utiliser le DNS public de Cloudflare par exemple. Libre à vous d'indiquer le DNS public de votre choix.
Pour la partie AllowedIPs
, je pars du principe que l'on souhaite en général que tout le trafic Internet passe par le serveur une fois connecté au VPN Wireguard. Si vous avez un besoin différent, à savoir simplement être connecté au serveur en mode "local" mais sans vouloir passer tout le trafic par le serveur, vous pouvez décommenter la seconde ligne AllowedIPs
et commenter la première.
Enfin, si vous rencontrez des problèmes d'instabilité, vous pouvez tenter de décommenter la dernière ligne PersistentKeepalive
, et ajouter à nouveau cette configuration sur votre appareil.
Votre fichier devrait ressembler à cela en faisant sudo cat /etc/wireguard/.clients/client-${clientId}.conf
:
[Interface]
PrivateKey = <contenu-du-fichier-/etc/wireguard/.clients/client-${clientId}-private.key>
Address = 10.0.1.2/24, fdc8:1911:07cd::2/64 # IPv4 & IPv6 that will be defined for the Wireguard's client
DNS = 10.0.1.1, fdc8:1911:07cd::1
[Peer]
PublicKey = <contenu-du-fichier-/etc/wireguard/public.key>
AllowedIPs = 0.0.0.0/0, ::0 # To be used to tunnel all the traffic through the VPN between the client & the server
# AllowedIPs = 10.0.1.0/24, fdc8:1911:07cd::/64 # To be used to be only connected remotely to the server, but not sending through all the traffic
Endpoint = wg.domain.tld:51820 # Endpoint to be configure as domain name or IP plus the port that is listened by Wireguard's server
# PersistentKeepalive = 60 # To keep the connection alive in case of connectivity issues
08 | Autoriser le nouveau client à se connecter sur le VPN Wireguard
Grâce à cette commande, le client sera autorisé à se connecter au VPN Wireguard :
sudo wg set wg0 peer $clientPublicKey allowed-ips ${ipv4Subnet}${clientNumber},${ipv6Subnet}${clientNumber}
Pour vérifier que l'autorisation a bien été prise en compte, utilisez cette commande :
sudo wg
Il ne reste maintenant qu'à ajouter la configuration de ce client sur votre appareil, que ce soit un ordinateur ou un mobile.
09 | Installer Wireguard sur votre appareil
Avant de pouvoir vous connecter au VPN Wireguard, vous devez installer sur votre ordinateur ou téléphone mobile le logiciel Wireguard qui vous permettra d'ajouter la configuration client que nous avons créé précédemment.
09.01 | Se connecter à Wireguard sur ordinateur
Une fois le logiciel installé, il ne vous reste plus qu'à copier le fichier /etc/wireguard/.clients/client-${clientId}.conf
ou bien copier le contenu de ce fichier au moment d'ajouter une connexion via le logiciel nouvellement Wireguard installé sur l'ordinateur.
Pensez bien à supprimer le fichier qui aurait été copié sur votre ordinateur, une fois la configuration effectuée, par mesure de sécurité.
09.02 | Se connecter à Wireguard sur mobile
Une fois l'application mobile installée, vous pouvez facilement ajouter une nouvelle connexion au VPN en scannant un QR Code.
Pour cela, nous pouvons générer un QR code directement via la ligne de commande du serveur en installant déjà l'utilitaire qrencode
:
sudo apt install qrencode
Puis pour générer et afficher le QR code à l'écran :
sudo cat /etc/wireguard/.clients/client-${clientId}.conf | qrencode -t ansiutf8
10 | Vérifier votre connexion au VPN Wireguard
Vous devriez maintenant être capable de vous connecter au VPN Wireguard installé sur votre serveur depuis votre appareil.
Pour vérifier votre adresse IP, je vous invite à vous connecter sur le célèbre site whatismyip.com.
Pour toute question, clarification ou remarque, n'hésitez pas à me contacter sur Mastodon.