URL: https://linuxfr.org/news/wireguard-protocole-de-communication-chiffre-sur-udp-et-logiciel-libre Title: WireGuard, protocole de communication chiffré sur UDP et logiciel libre Authors: carb0n Cyrille Pontvieux, Anonyme, benja, Benoît Sibaud, volts, yPhil, SaintGermain, tisaac, Yves Bourguignon, palm123, GG, Pierre Tramo, gregober, Voisin et azerttyu Date: 2021-07-09T23:28:19+02:00 License: CC By-SA Tags: wireguard et sécurité Score: 3 [[WireGuard]] est à la fois un protocole de communication chiffré sur [UDP](https://fr.wikipedia.org/wiki/User_Datagram_Protocol) et un logiciel libre l’implémentant, le tout créé par Jason A. Donenfeld, qui vise à remplacer les protocoles ou logiciels comme [IPSec](https://fr.wikipedia.org/wiki/IPsec) ou [OpenVPN](https://fr.wikipedia.org/wiki/OpenVPN). Bien que WireGuard ait été principalement pensé pour Linux et que son implémentation de référence soit celle du noyau Linux, il existe des implémentations sous licence libre pour la majorité des plateformes (Linux, BSD, Windows, Mac, Android, iOS), sous GPLv2 pour le noyau Linux, sous MIT, BSD, APLv2 ou GPL suivant les autres cas. ---- ---- Introduction ============ WireGuard se veut plus simple qu’IPSec à la fois pour les développeurs et pour les utilisateurs. Il ne propose notamment qu’une seule suite d’algorithmes cryptographiques (considérés comme les plus sûrs et les plus performants à l’heure actuelle) et ne laisse aucun choix de configuration. Bien que le protocole ne soit pas normalisé sous forme d’une RFC comme peuvent l’être d’autres protocoles d’internet (IPSec par exemple), il est décrit dans [un « papier blanc » écrit par son créateur](https://www.wireguard.com/papers/wireguard.pdf). Disponibilité ============= Linux ----- WireGuard est disponible nativement dans le noyau Linux depuis la version 5.6 et est disponible comme un module externe pour les noyaux 3.10 et ultérieur (en utilisant le support dynamique de chargements de modules [DKMS](https://en.wikipedia.org/wiki/DKMS)). `NetworkManager` gère WireGuard par défaut [depuis la version 1.16](https://www.phoronix.com/scan.php?page=news_item&px=NetworkManager-1.16-Released), cependant il n’existe pas d’interface graphique pour gérer ce type de connexions. Pour ajouter une interface graphique de configuration, il existe le greffon [network-manager-wireguard](https://github.com/max-moser/network-manager-wireguard) (semblable aux greffons pour `OpenVPN` ou `OpenConnect`). ### Debian Avec Debian 11 (Bullseye), WireGuard est intégré au noyau 5.10 et vous n’avez rien à faire si ce n’est installer les outils en ligne de commande fournis par le paquet [wireguard](https://packages.debian.org/bullseye/wireguard) et ses dépendances. Sur Debian 10 (Buster), WireGuard s’installe depuis les backports (aussi avec le paquet [`wireguard`](https://packages.debian.org/buster-backports/wireguard)), mais l’installation utilise DKMS et peut nécessiter des actions manuelles si vous avez SecureBoot activé : * soit [signer le module avec une clef que vous aurez préalablement ajoutée au trousseau UEFI](https://wiki.debian.org/SecureBoot#MOK_-_Machine_Owner_Key) ; * soit [désactiver Secure Boot](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=931440) (en dernier recours). Ensuite il faudra peut-être remplacer `resolvconf` par `openresolv` à cause [du bogue 939904](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=939904). ### Android Une application est disponible soit sur [Play Store](https://play.google.com/store/apps/details?id=com.wireguard.android), soit sur [F-droid](https://f-droid.org/en/packages/com.wireguard.android/). Petite astuce, il est possible de générer un QR code depuis le serveur : `qrencode -t ansiutf8 < fichier_de.conf` FreeBSD, NetBSD et OpenBSD -------------------------- WireGuard est intégré au noyau d’OpenBSD depuis la [version 6.8](https://www.openbsd.org/68.html). NetBSD propose WireGuard dans le noyau de sa [branche de développement](https://mail-index.netbsd.org/current-users/2020/08/20/msg039393.html), la future version 10. Quant à FreeBSD, le support de WireGuard [fut retiré](https://lwn.net/Articles/850098/) de son noyau juste avant la sortie de la version 13. Pour pallier ce manque, le mécanisme des ports propose une nouvelle [implémentation en espace noyau](https://www.freshports.org/net/wireguard-kmod/), ainsi que l’implémentation de référence qui fonctionne [en mode utilisateur](https://www.freshports.org/net/wireguard-go/). Windows ------- Wireguard est disponible pour Windows soit sous la forme [d’un module en espace utilisateur](https://git.zx2c4.com/wireguard-windows/about/) (recommandée), soit sous la forme d’un module noyau expérimental : [`WireguardNT`](https://git.zx2c4.com/wireguard-nt/about/). MacOS et iOS ------------ Des applications sont disponibles sur l'App Store pour [macOS](https://itunes.apple.com/us/app/wireguard/id1451685025?ls=1&mt=12) et [iOS](https://itunes.apple.com/us/app/wireguard/id1441195209?ls=1&mt=8). Tutoriel : Installer Wireguard côté serveur sur Debian/Ubuntu ====================================================================== Tutoriel assez complet pour installer WireGuard sur Debian et Ubuntu 20.04 avec : - tunnel/NAT - IPv6 - serveur DNS (pour éviter les fuites DNS) Une très bonne base : https://static.cinay.eu/2020/10/22/Wireguard-+-DNS-Unbound-+-Wireguard-Web-(go).html Si vous installez le [résolveur DNS validateur, cache, récursif unbound](https://fr.wikipedia.org/wiki/Unbound), il faut penser à désinstaller `bind9` avant sinon vous aurez un conflit sur le port `53`. ### Installation de WireGuard Le serveur utilisé est un VPS avec une installation Ubuntu server 20.04 toute fraîche. ```sh apt install wireguard ``` Activation de l'ip_forward pour les deux piles IP ```shell sed -i 's/^#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf sed -i 's/^#net.ipv6.conf.all.forwarding=1/net.ipv6.conf.all.forwarding=1/' /etc/sysctl.conf ``` Prise en compte immédiate ```shell sysctl -p ``` La configuration se fait dans `/etc/wireguard/`. Le serveur a besoin d’un fichier de configuration nommé par exemple `wg0.conf`. Ici `wg0` sera le nom de l’interface réseau de WireGuard. Pour l’exemple, nous utiliserons ici les plages d’adresses privées suivantes : `10.26.174.0/24, fd42:42:42::/64`. Le serveur écoutera sur le port `51955`. Nous allons également devoir générer des paires de clefs (privées et publiques) pour le serveur (A) et pour l’exemple les deux premiers clients (B et C). Pour cela, Wirguard fournit tous les outils nécessaires. ```shell umask 077; wg genkey | tee peer_A.key | wg pubkey > peer_A.pub umask 077; wg genkey | tee peer_B.key | wg pubkey > peer_B.pub umask 077; wg genkey | tee peer_C.key | wg pubkey > peer_C.pub ``` Dans la foulée, on va également générer des clefs pré-partagées histoire d’ajouter un petit niveau de sécurité. ```shell umask 077; wg genpsk > peer_A-peer_B.psk umask 077; wg genpsk > peer_A-peer_C.psk ``` WireGuard a la capacité de lancer des commandes à son lancement (PostUp) et à sa fermeture (PostDown). Nous allons nous en servir pour lancer les commandes Iptables nécessaires à son fonctionnement. Dans cet exemple, l’interface réseau du VPS sur lequel ont été menés les tests est `ens3`. Le fichier de configuration `/etc/wireguard/wg0.conf` ```ini [Interface] Address = 10.26.174.1/24, fd42:42:42::1/64 ListenPort = 51955 PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE; ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ens3 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE; ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ens3 -j MASQUERADE PrivateKey = C...contenu_de_peer_A.key...= DNS = 10.26.174.1, fd42:42:42::1 [Peer] PublicKey = K...contenu_de_peer_B.pub...= PresharedKey = k...contenu_de_peer_A-peer_B.psk...= AllowedIPs = 10.26.174.2/32, fd42:42:42::2/128 [Peer] PublicKey = r...contenu_de_peer_C.pub...= PresharedKey = j...contenu_de_peer_A-peer_C.psk...= AllowedIPs = 10.26.174.3/32, fd42:42:42::3/128 ``` ### Installation du serveur DNS [Unbound](https://nlnetlabs.nl/projects/unbound/about/) > Si vous ne comptez pas utiliser `unbound`, et donc sauter cette étape, vous allez avoir une erreur au lancement de WireGuard. `openresolv` est la solution. Installez ce paquet et passez à l’étape suivante. ```shell apt install unbound unbound-host resolvconf ``` Téléchargement de la liste des serveurs DNS racines ```shell curl -o /var/lib/unbound/root.hints https://www.internic.net/domain/named.cache chown unbound:unbound /var/lib/unbound/root.hints ``` Le fichier de configuration qui va bien : `/etc/unbound/unbound.conf.d/dns-cx11.conf`. ```awk server: num-threads: 4 # enable logs verbosity: 0 # no verbosity, only errors # liste des serveurs DNS racine root-hints: "/var/lib/unbound/root.hints" # Répondre aux requêtes DNS sur toutes les interfaces interface: 0.0.0.0 # 0.0.0.0 unbound sur plusieurs interfaces interface: ::0 max-udp-size: 3072 # IPs authorised to access the DNS Server access-control: 0.0.0.0/0 refuse access-control: 127.0.0.0/8 allow access-control: 10.26.174.0/16 allow access-control: ::0/0 refuse access-control: ::1 allow access-control: fe80::/10 allow access-control: fd42:42:42::/48 allow #hide DNS Server info hide-identity: yes hide-version: yes # limit DNS fraud and use DNSSEC harden-glue: yes harden-dnssec-stripped: yes harden-referral-path: yes # add an unwanted reply threshold to clean the cache and avoid, when possible, DNS poisoning unwanted-reply-threshold: 10000000 # have the validator print validation failures to the log val-log-level: 1 # minimum lifetime of cache entries in seconds cache-min-ttl: 1800 # maximum lifetime of cached entries in seconds cache-max-ttl: 14400 prefetch: yes qname-minimisation: yes prefetch-key: yes #include: /etc/unbound/unbound.conf.d/adslist.txt ``` Droits : ```shell chown -R unbound:unbound /var/lib/unbound ``` Pour vérifier si le fichier de configuration est valide ```shell unbound-checkconf /etc/unbound/unbound.conf.d/dns-cx11.conf ``` La réponse attendue : > unbound-checkconf: no errors in /etc/unbound/unbound.conf.d/dns-cx11.conf Désactiver `systemd-resolved` (si utilisé) ```shell systemctl stop systemd-resolved systemctl disable systemd-resolved ``` Activation d’unbound` ```shell systemctl enable unbound-resolvconf systemctl enable unbound ``` Il est conseillé de redémarrer le serveur On peut utiliser ce script pour mettre à jours les serveurs DNS racines et le lancer par crontab : ```shell curl -o /etc/unbound/dnsunbound-update-root-dns.sh https://static.cinay.eu/files/dnsunbound-update-root-dns.sh chmod +x /etc/unbound/dnsunbound-update-root-dns.sh crontab -e ``` ### Protection du serveur avec UFW ```shell apt install ufw ``` On va modifier une stratégie par défaut d’UFW dans `/etc/default/ufw` pour permettre un bon fonctionnement de WireGuard : `DEFAULT_FORWARD_POLICY="DROP"` devient `DEFAULT_FORWARD_POLICY="ACCEPT"` On va également ouvrir le port d'écoute du serveur VPN (51955). ```shell ufw allow 51955/udp ufw allow in on wg0 to any ``` Histoire de conserver l’accès SSH : ```shell ufw allow ssh ``` S’il vous arrive d’avoir deux mains gauches et dix pouces, relirez vos règles avant d’activer UFW. ```shell ufw enable ``` Pour voir les règles prises en compte : ```shell ufw status ``` ### Test de WireGuard Lancement du serveur VPN : ```shell wg-quick up wg0 ``` Si tout se passe bien on peut admirer le résultat : ```shell wg show ``` (`wg` donne le même résultat) Pour l’arrêter : ```shell wg-quick down wg0 ``` Mise en service et activation du service au démarrage du serveur : ```shell systemctl enable wg-quick@wg0 ``` Redémarrage et tadaaa !