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 !