WireGuard : Configuration d'un VPN / NAT simple

Ça y est, cette fois-ci on va parler d'un premier cas concret. On va voir dans cet article comment configurer un « VPN / NAT ». Bien que je vais vous montrer comment faire ça avec WireGuard, les configurations réseau que je vais vous présenter ici sont applicables à d'autres situations et peuvent être utilisées avec n'importe quels autres protocoles de VPN (du moment qu'une interface réseau est créée pour le tunnel).

Mais avant de mettre les mains dans le cambouis, peut-être qu'il faudrait que je vous explique ce que j'appelle un « VPN / NAT »... Déjà, sachez que ce n'est pas une dénomination « officielle », c'est juste le meilleur nom que j'ai trouvé pour ce cas de figure. Ce que j'appelle un « VPN / NAT », c'est un VPN dont le seul but est de faire sortir le trafic de votre machine (PC, téléphone,...) à un autre endroit sur Internet.

C'est très utile pour sécuriser sa connexion lorsque l'on se connecte depuis un lieu public, ça sert également à masquer son adresse IP réelle, à contourner des restrictions géographiques (continuer à accéder au Netflix français lorsque l'on est en voyage à l'étranger par exemple), etc. C'est en fait exactement ce que vous vendent les fournisseurs de VPN grand public comme NordVPN dont tous les youtubeurs nous rebattent les oreilles depuis des mois.

Prérequis

Si vous souhaitez mettre en œuvre les configurations présentées dans cet article, vous devrez disposer d'au moins :

  • une machine sous Linux pour monter le serveur VPN (un serveur dédié, un VPS ou un simple Raspberry PI à la maison feront parfaitement l'affaire 😉️),
  • d'une ou plusieurs machines clientes (PC, smartphones,... peu importe leurs systèmes d'exploitation).

Pour pouvoir suivre dans de bonnes conditions, je vous recommande vivement de lire d'abord les deux premiers articles de cette série. Le premier donne notamment quelques explications sur le fonctionnement général de WireGuard, explique comment l'installer sous Linux et fournit les instructions nécessaires à la génération des clefs. Le second parle quant à lui des fichiers de configuration et de comment les utiliser sur chaque système d'exploitation. Je ne détaillerais donc pas ces notions-là dans le présent article.

C'est quoi un NAT ?

Je ne vais pas expliquer ici comment fonctionne un NAT, il y aurait de quoi faire un article complet à ce sujet. On va donc s'en tenir au fait que c'est typiquement le comportement de votre MachinBox à la maison (Freebox, Livebox, MiséricâbleBox,...) : la machine dispose d'une adresse IP dite « publique » sur un réseau (généralement Internet), et permet à d'autres machines dont les adresses ne sont pas routable sur ce réseau à quand même pouvoir échanger des données avec.

Pour donner un exemple, votre ordinateur connecté chez vous à votre BiduleBox™ dispose d'une adresse IP privée, routable uniquement sur votre réseau local. Lorsque vous vous connectez à un site web depuis cet ordinateur, le serveur du site ne voit pas l'adresse IP de votre machine (celle utilisée sur votre réseau local) ; il voit uniquement l'adresse publique de votre BiduleBox™. C'est votre BiduleBox™ qui se débrouille pour que les données que le serveur lui renvoie en réponse arrivent bien sur votre ordinateur (et pas sur votre téléphone, lui aussi connecté à votre réseau).

Le NAT à donc pour effet secondaire de masquer l'adresse IP de votre machine, ce qui peut justement être ce que l'on recherche lorsque l'on utilise un VPN.

Quoi qu'il en soit soit, si vous souhaitez en savoir plus sur le NAT, je vous envoie vers cet article d'OpenClassrooms qui vous donnera bien plus d'informations à ce sujet.

Configuration du serveur

Partons pour l'instant du principe que la machine sur laquelle on va monter notre serveur VPN est un serveur accessible sur Internet (un serveur dédié ou un VPS loué chez un hébergeur quelconque).

Cette machine dispose d'une adresse IP publique que l'on définira comme étant vpn.example.org dans nos configurations. L'interface réseau connectant cette machine à Internet s'appelle eth0, et on se débrouillera pour que l'interface réseau de notre VPN s'appelle wg0.

Configuration de WireGuard

La configuration de WireGuard sur notre serveur est identique à ce que nous avions pu voir dans le précédent article (c'est pourquoi je ne la détaillerais pas ici)  :

[Interface]
Address = 10.8.8.254/24
PrivateKey = aE5ovKfa3vE9ujI9BI1UnQR744oH+0fDaQDxEnHRL00=
ListenPort = 51820

[Peer]
PublicKey = wGDWnA+bj15JxOUUlA0SCUP9CcCqUMJKyidhu+ufLHk=
AllowedIPs = 10.8.8.1/32

# [Peer]
# Configuration pour un éventuel second client...

On sauvegarde tout ça dans le fichier /etc/wireguard/wg0.conf (pour rappel le nom du fichier est important), et on active cette configuration pour qu'elle soit lancée au démarrage de la machine :

systemctl enable wg-quick@wg0

Configuration de la partie NAT

Maintenant que la configuration de base de WireGuard est faite, on va passer à la configuration du NAT.

Pour commencer il faut activer la fonctionnalité d'IP forwarding de Linux :

sysctl -w net.ipv4.ip_forward=1
sysctl -p

Une fois ceci fait, il nous suffit d'ajouter les règles suivantes au firewall pour qu'il effectue la traduction d'adresses :

# On accepte les paquets en provenance du VPN
iptables -A FORWARD -i wg0 -j ACCEPT

# On autorise également les paquets à destination du VPN
iptables -A FORWARD -o wg0 -j ACCEPT

# On effectue la traduction d'adresse entre l'IP publique du serveur et les clients
iptables -t nat -A POSTROUTING -s 10.8.8.0/24 -o eth0 -j MASQUERADE

Bien sûr, si on se contente d'exécuter les commandes ci-dessus, les règles de firewall ne seront pas réappliquées au prochain redémarrage de la machine. C'est pourquoi on va les rajouter au fichier de configuration de WireGuard, dans la section [Interface] :

[Interface]
# ...

# On exécute les commandes d'ajout des règles lorsque le VPN démarre
PostUp = sysctl -w net.ipv4.ip_forward=1 ; sysctl -p ; iptables -A FORWARD -i %i -j ACCEPT ; iptables -A FORWARD -o %i -j ACCEPT ; iptables -t nat -A POSTROUTING -s 10.8.8.0/24 -o eth0 -j MASQUERADE

# Et on rajoute des commandes pour les supprimer lorsque le VPN est éteint
PostDown = iptables -D FORWARD -i %i -j ACCEPT ; iptables -D FORWARD -o %i -j ACCEPT ; iptables -t nat -D POSTROUTING -s 10.8.8.0/24 -o eth0 -j MASQUERADE

Note

NOTE : Dans le fichier ci-dessus, les références à l'interface wg0 ont été remplacées par %i. Il s'agit d'une facilité de configuration qui nous permettra de toujours avoir le bon nom pour l'interface du VPN, même si on l'a nommée différament.

Pour appliquer les changements de notre configuration, il nous suffit à présent de redémarrer notre VPN :

systemctl restart wg-quick@wg0

Le serveur est maintenant configuré.

BONUS : Serveur VPN à la maison

Dans la section précédente, je vous ai expliqué comment configurer le serveur VPN s'il était installé sur une machine directement accessible depuis Internet (serveur dédié ou VPS). Eh bien sachez que si vous souhaitez faire tourner le serveur chez vous (donc derrière un autre routeur NAT), sur un Raspberry PI par exemple, la configuration reste exactement la même. Il vous faudra seulement configurer le port forwarding du firewall de votre MachinBox.

Note

NOTE : ce genre de configuration fera probablement râler les admins réseau à cause de l'utilisation de deux NAT successifs (celui de notre serveur VPN et celui de la MachinBox). Ce n'est certes pas la solution idéale, je vous montrerais d'ailleurs une meilleure solution dans le prochain article, mais il s'agit parfois de la seule solution possible (notamment lorsque la MachinBox est trop limitée et ne permet pas de configurer des routes statiques).

Étant donné que les interfaces diffèrent pour chaque Box, je vais vous donner tous les paramètres ci-dessous. Il est probable que l'interface dans votre MachinBox soit simplifiée et ne vous demande pas autant de choses... à vous d'adapter à votre situation :

  • Protocole : UDP
  • IP source : toutes
  • Port source : tous
  • Port destination : 51820
  • IP NAT (machine à laquelle on transfère) : IP de la machine faisant tourner le VPN (Raspberry PI ou autre)
  • Port NAT : 51820

Voici ce que ça donne par exemple sur ma Livebox :

Capture d'écran de la configuration du port forwarding sur une LiveBox d'Orange

Et sur ma Freebox v6 :

Capture d'écran de la configuration du port forwarding sur une Freebox v6 de Free

Configuration du client

La configuration du client reste assez similaire à celle vue dans l'article précédent, à ceci près que l'on souhaite cette fois router tout le trafic à travers le VPN :

[Interface]
Address = 10.8.8.1/24
PrivateKey = cLc9zpU1WD7CkYyPBjajlsTijqMCEAiXux7g8Nc29Fg=

[Peer]
PublicKey = 0Pi1sWdM58zh4tWu15RKN8/RNePatcTwz/xntVAM/1k=
Endpoint = vpn.example.org:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Note

NOTE : ici vpn.example.org correspond soit à l'IP de votre serveur s'il est accessible publiquement sur Internet, soit à l'IP publique de votre MachinBox si votre serveur est hébergé chez vous.

Comme vous pouvez le voir, construire un VPN / NAT avec WireGuard est assez simple. Une fois que l'on a compris comment fonctionne WireGuard, il n'y a plus qu'à utiliser les outils fournis par Linux pour arriver à nos fins.

C'est tout pour aujourd'hui, je vous retrouve bientôt pour une autre configuration concrète, toujours à base de WireGuard et de Linux. 😁️


EDIT 2022-09-30 : Ajout de sysctl -p pour recharger les paramètres sysctl depuis le fichier /etc/sysctl.conf après modification (voir commentaire de Xavier B ci-dessous).