Journal WireGuard : Au-delà de la configuration de base

Posté par  . Licence CC By‑SA.
Étiquettes :
30
3
sept.
2024

Sommaire

(Écrit par moi en anglais, traduit en français par ChatGPT)

La semaine dernière, j'ai voulu remplacer ma configuration OpenVPN par WireGuard. Les bases étaient bien documentées, mais aller au-delà des bases était un peu plus compliqué. Laissez-moi vous enseigner ce que j'ai appris.

Les bases

Mais d'abord, résumons les bases. J'ai un serveur chez un fournisseur d'hébergement que je veux utiliser comme serveur VPN. Je ne vais pas entrer dans les détails ici, car il existe déjà de nombreuses excellentes explications sur le web (ici, ici, ici ou ici), faisons juste un rapide résumé d'une configuration simple, comme base pour discuter des usages (légèrement) plus avancés que j'ai dû configurer moi-même :

  1. Générer une paire de clés (clé privée/clé publique) pour le serveur.

  2. Générer une paire de clés (clé privée/clé publique) pour chaque client.

  3. Choisir un réseau pour le VPN (pour moi : 10.100.0.0/16), une IP pour le serveur (10.100.0.1) et les clients (10.100.0.2, 10.100.0.3, etc.)

  4. Créer la configuration pour le serveur

[Interface]
Address = 10.100.0.1/24
PrivateKey = (censuré)
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens0 -j MASQUERADE

[Peer]
PublicKey = (censuré)
AllowedIPs = 10.100.0.2/32

[Peer]
PublicKey = (censuré)
AllowedIPs = 10.100.0.3/32
  1. Démarrer le serveur, wg up /etc/wireguard/wg0.conf

  2. Créer la configuration pour le client

[Interface]
PrivateKey = (censuré)

[Peer]
PublicKey = (censuré)
Endpoint = mon-serveur.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
  1. Démarrer le client : wg up /etc/wireguard/wg0.conf

(optionnellement, non illustré ici : créer un namespace réseau pour votre VPN, afin que votre connexion principale ait toujours un accès direct à Internet, mais que vous puissiez placer les applications qui veulent utiliser le VPN dans le namespace réseau du VPN).

NAT

Certaines applications (je pense à toi, client BitTorrent) ne fonctionnent pas bien derrière un NAT. Malheureusement, votre VPN (qu'il s'agisse de WireGuard ou non) agit comme un NAT. Une méthode largement utilisée pour contourner ces problèmes est l'UPnP.

L'UPnP résout deux problèmes :

  • Votre ordinateur ne connaît pas son adresse publique sur Internet (du point de vue d'un système externe) ; derrière un VPN, votre adresse publique est l'adresse du serveur VPN, pas celle assignée par votre FAI (votre logiciel VPN connaît cette adresse — mais le reste du système n'en a généralement aucune connaissance). Et si cette adresse n'est pas connue de votre logiciel peer-to-peer, il ne peut pas la communiquer à d'autres pairs.

  • Même si cette adresse est connue et correctement communiquée à un pair, si vous écoutez un port (par exemple, TCP 8043), le pair essaiera de vous atteindre sur ce port, mais sur l'IP de votre serveur VPN. Pour que cette connexion atteigne réellement votre ordinateur, votre logiciel VPN devra configurer une règle de redirection de port (du port 8043 du serveur VPN à l'adresse IP assignée par votre FAI, port 8043 — dans une configuration réelle, les deux ports peuvent en fait différer, mais gardons les choses simples pour cette explication). L'UPnP fournit un moyen de faire cela.

Montrons qu'évidemment, notre simple configuration VPN basée sur WireGuard ne fournit pas l'UPnP (external-ip est un outil fourni par miniupnpc, un client UPnP) :

$ external-ip
No IGD UPnP Device found on the network !

C'était attendu. WireGuard, étant un module kernel très simple, n'est pas livré avec un serveur UPnP intégré. Nous devrons le faire manuellement. Heureusement, c'est assez simple :

  1. Installer miniupnpd (sur le serveur, évidemment).

  2. Configurer miniupnpd.

  3. Ajouter PostUp = systemctl start miniupnpd et PostDown = systemctl stop miniupnpd dans votre fichier de configuration WireGuard.

La seule étape non triviale ici est la configuration de miniupnpd. Toute l'action se passe dans /etc/miniupnpd/miniupnpd.conf. Voici ce que vous devez configurer :

  • ext_ifname=ens0 : c'est l'interface orientée vers Internet de votre serveur (elle peut être différente de ens0).

  • listening_ip=wg0 : c'est l'interface réseau WireGuard sur votre serveur.

  • uuid=06df7440-dbac-404c-9c07-0b0dbfca609e : utilisez uuidgen pour en générer un. Ou vous pouvez voler le mien, cela n'a pas d'importance, puisque tout se passe dans un réseau privé non routable.

  • allow 1024-65535 10.100.0.0/16 1024-65535 : c'est ici que vous spécifiez votre réseau WireGuard (dans ma configuration de base 10.100.0.0/16).

Vérifions que cela fonctionne :

$ external-ip
(censuré, mais cela a correctement retourné l'IP de mon serveur)
$ upnpc -n 10.100.0.2 8043 8043 tcp 300
external (censuré : IP du serveur) :8043 TCP est redirigé vers l'interne 10.100.0.2:8043 (durée=300)
$ socat TCP-LISTEN:8043 STDIO

Et sur une autre machine :

$ socat TCP:(censuré : IP du serveur) :8043 STDIO

Vous pouvez voir que les deux instances socat peuvent communiquer entre elles, en passant par votre VPN.

IPv6

Vous savez ce qui est encore mieux que de prendre en charge l'UPnP pour contourner les problèmes introduits par le NAT ? Ne pas avoir de NAT. Et la bonne nouvelle est qu'avec l'IPv6, vous pouvez réellement éviter le NAT.

Les quelques tutoriels qui expliquent comment configurer l'IPv6 pour un VPN basé sur WireGuard reproduisent généralement la configuration IPv4 : assigner un réseau privé non routable à l'IPv6 (10.100.0.0/16 pour IPv4 est traduit par quelque chose comme fd00:dead:beef::/48 pour IPv6), assigner des adresses IP dans ce réseau au serveur et aux clients, et ajouter une action de masquage ip6tables.

Nous n'allons pas faire cela. Nous pouvons faire mieux, et nous allons faire mieux.

La première chose à remarquer est que mon fournisseur d'hébergement m'a attribué tout un réseau /48 pour mon compte (2001:aaaa:bbbb::/48), et un /56 (2001:aaaa:bbbb:1000::1/56) pour mon serveur. Nous pouvons en profiter pour assigner des adresses IPv6 publiquement routables à nos clients, au lieu d'assigner des adresses privées non routables.

Commençons par la configuration du serveur. Ajoutons l'IPv6. Nous attribuons le sous-réseau /80 2001:aaaa:bbbb:1000:cafe::/80 au réseau VPN. Je vais seulement lister les lignes de configuration ajoutées, sans répéter celles existantes :

[Interface]
Address = 2001:aaaa:bbbb:1000:cafe::1/80

[Peer]
AllowedIPs = 2001:aaaa:bbbb:1000:cafe::2/128

[Peer]
AllowedIPs = 2001:aaaa:bbbb:1000:cafe::3/128

Côté client, ce n'est pas beaucoup plus compliqué :

[Interface]
Address = 2001:aaaa:bbbb:1000:cafe::2/128

Juste une vérification de bon sens : sur votre serveur, ip -6 route get 2001:aaaa:bbbb:1000:cafe::2 doit renvoyer l'interface WireGuard (wg0). Sinon, vous devrez attribuer une métrique inférieure à wg0 dans vos routes. Mais vous pouvez maintenant, sur votre client, écouter directement sur un port :

$ socat TCP6-LISTEN:8043

et il sera accessible depuis Internet sans aucune configuration UPnP :

$ socat TCP6:[2001:aaaa:bbbb:1000:cafe::2]:8043

De plus, l'adresse IP sur le périphérique de votre route par défaut sera 2001:aaaa:bbbb:1000:cafe::2, ce qui signifie qu'il n'est pas nécessaire de configurer l'UPnP pour détecter votre IPv6 publique et routable : votre IP d'interface VPN (qui est privée dans le cas de l'IPv4, mais maintenant publique pour l'IPv6) est également votre IP publique.

  • # merci

    Posté par  . Évalué à 2. Dernière modification le 04 septembre 2024 à 19:21.

    Merci en particulier pour la partie ipv6, j'avais déjà vu des tutoriels mais c'était pas aussi clair sur ces histoires d'adresses.

    J'avais prévu de convertir ma configuration en ipv6 ready et en systemd-networkd (networkd intégre le paramètrage wireguard dans ses propre fichiers de configuration), ça va m'étre utile.

  • # UPnP

    Posté par  (site web personnel) . Évalué à 2.

    Merci beaucoup pour le tuto!
    Ne prévoyant pas d'utiliser IPv6 dans l'immédiat, c'est surtout la partie UPnP qui m'a interessée : ne la connaissant qu'en utilisateur côté desktop, une install serveur me permettrait de faire des ajustements pour plein de cas.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.