Dans le cadre de ma recherche d'une solution de redirection de port pour accéder à mes machines de mon réseau interne depuis l’extérieur, avec une box 4G comme seul accès internet, j'avais écrit un article mettant en oeuvre le VPN Zerotier.

C'est parfaitement fonctionnel mais dans les différents channels Telegram que je suis, le VPN Wireguard  revient souvent dans les discussions.
Par curiosité j'ai donc voulu reproduire le même fonctionnement qu'avec Zerotier, mais avec WirGuard.
Le principe reste similaire:

  • un VPN installé sur un VPS externe,
  • un docker client sur une machine interne qui va faire passerelle

La différence est qu'il n'y a pas de serveur VPN tierce, le serveur VPN est directement installé sur le VPS.

Installation du VPS

J’ai pris l’abonnement le moins cher chez firstheberg.com , le GP1 à 2,49 € HT/mois. Entre-temps j'ai voulu testé celui de ionos.fr , le VPS S à 1 € HT/mois mais malgré le paiement, je suis toujours en attente de création. L'offre semble victime de son succès ou bien...

J’ai choisi l’installation Debian 10 que j’ai configuré comme suit en me connectant en ssh avec Putty  à l'aide des informations de connexion reçues par mail.

J'ai utilisé cette vidéo de Superboki (merci @Sylvain pour le lien) qui décrit plus en détail le processus suivant:

Verification du kernel Debian

Wireguard a besoin d'un kernel > 5.6 pour fonctionner.
J'ai vérifié à l'aide de la commande :

uname -r

et évidement la version était inférieure. Il a fallu faire un upgrade du kernel:
On édite le fichier des listes de sources

nano /etc/apt/sources.list

puis on ajoute les listes suivantes en fin de fichier:

deb http://deb.debian.org/debian buster-backports main contrib non-free
deb-src http://deb.debian.org/debian buster-backports main contrib non-free

on met à jour avec :

apt update

puis

apt install -t buster-backports linux-image-5.9.0-0.bpo.5-amd64 linux-headers-5.9.0-0.bpo.5-amd64

et enfin on reboot le vps

 reboot

Installation de Wireguard Serveur

J'ai ensuite utilisé le script d'installation d'Angristan comme indiqué dans la vidéo :

Si curl n'est pas installé :

apt install curl

puis

curl -O https://raw.githubusercontent.com/angristan/wireguard-install/master/wireguard-install.sh

puis on rends le script exécutable:

chmod +x wireguard-install.sh

et enfin on execute le script  et on répond aux questions posées:

./wireguard-install.sh

On peut tout laisser par défaut sauf le port que j'ai changé en 56604


A la fin il est demandé le "client name", c'est le nom du premier client du serveur VPN.
Comme je vais mettre le client sur un docker, je l'ai simplement appelé "docker", ce qui va généré un fichier wg0-client-docker.conf contenant la configuration du client utile un peu plus tard.

Configuration du serveur VPN

Le fichier de configiration se trouve dans /etc/wireguard

Pour que le le vps puisse atteindre le reseau interne, il faut également ajouter la plage d'ip interne dans la partie client: AllowedIPs = 10.66.66.3/24,192.168.1.0/24

Le fichier wg0.conf dans /etc/wireguard devrait ressembler à ce qui suit :

[Interface]
Address = 10.66.66.1/24
ListenPort = 56604
PrivateKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PostUp = iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i eth0 -o wg0 -j ACCEPT; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

### Client docker
[Peer]
PublicKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PresharedKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
AllowedIPs = 10.66.66.3/24,192.168.1.0/24

Pour éditer le fichier et le modifier afin qu'il soit comme suit :

nano /etc/wireguard/wg0.conf

Pour prendre en compte la modification, on  arrête et on relance l'interface :

wg-quick down wg0
wg-quick up wg0

Pour que l'interface soit montée au démarrage, il faut executer :

systemctl enable [email protected]

Configuration du client VPN

J'ai commencé par vérifier la version du kernel de la Debian où est installé Docker.
Bien sur, ce n'était pas la bonne version, j'ai donc appliqué la même procédure que pour le VPS, décrite un peu plus haut.
Ensuite, j'ai créé le repertoire et effectué la configuration du client:

mkdir wireguard
cd wireguard
nano wg0.conf

J'ai récupéré la configuration du client générée sur le VPS (wg0-client-docker.conf) que j'ai modifié et collé dans le fichier wg0.conf:

[Interface]
PrivateKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Address = 10.66.66.3/24
DNS = 94.140.14.14,94.140.15.15

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PresharedKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Endpoint = 188.150.20.240:56604
AllowedIPs = 10.66.66.0/24
PersistentKeepalive = 25

Installation du container Docker

J'ai ensuite utilisé le container disponible ici : https://hub.docker.com/r/linuxserver/wireguard  en procédant comme suit:

L'installation nécessite Docker Compose. Si ce n'est pas déjà installé, vous pouvez  utiliser la méthode décrite à l'étape 1 de cet article : https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-debian-10-fr

J'ai créé un fichier docker-compose.yaml directement dans le répertoire au dessus du répertoire wireguard créé précédemment.

nano docker-compose.yaml

Le contenu est le suivant :

version: '3.7'

services:
  wireguard:
    image: linuxserver/wireguard
    container_name: wireguard
    restart: unless-stopped
    networks:
      - backbone
    volumes:
      - './wireguard:/config'
      - '/lib/modules:/lib/modules:ro'
    environment:
      - PUID=1000
      - PGID=1000
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv6.conf.all.disable_ipv6=0

networks:
  backbone:
    driver: bridge

Pour finir, on peut lancer le container :

sudo docker-compose up -d

Redirection de port sur le VPS

Il faut maintenant rediriger les requètes de l’ip publique du vps vers le réseau interne pour un port donné.

Dans mon cas d’usage, il s’agit du port  8123  qui doit être dirigé vers l’adresse ip 192.168.1.63 en passant par l’IP de l’interface VPN  10.66.66.1  :

Prerouting sur l'interface publique, dans mon cas eth0

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8123 -j DNAT --to-destination 192.168.1.63:8123

Postrouting sur l'interface Wireguard, dans mon cas wg0 (verifiez avec la commande ip a )

iptables -t nat -A POSTROUTING -o wg0 -p tcp --dport 8123 -d 192.168.1.63 -j SNAT --to-source 10.66.66.1

Ces deux lignes sont à répéter pour chaque port qu’on souhaite ouvrir.

On test maintenant qu’on accède bien à l’interface d’Home Assistant depuis l’IP publique du VPS:  https://188.150.20.240:8123

On rend ensuite les règles persistantes sinon elles seront perdues au prochain démarrage du VPS :

apt-get install iptables-persistent
systemctl enable netfilter-persistent
iptables-save > /etc/iptables/rules.v4

@Fabien m'a fait remarqué qu'il était plus judicieux d'inclure les règles de redirection de port directement dans la configuration du serveur VPN en Postup et PostDown. Ainsi les règles seront  appliquées au démarrage du VPN et supprimées lors de l'arret, l'utilisation d'iptables-persistent n'étant alors plus nécessaire.

La configuration du serveur devient alors :

[Interface]
Address = 10.66.66.1/24
ListenPort = 56604
PrivateKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PostUp = iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8123 -j DNAT --to-destination 192.168.1.63:8123;iptables -t nat -A POSTROUTING -o wg0 -p tcp --dport 8123 -d 192.168.1.63 -j SNAT --to-source 10.66.66.1
PostDown = iptables -D FORWARD -i eth0 -o wg0 -j ACCEPT; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE;iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 8123 -j DNAT --to-destination 192.168.1.63:8123;iptables -t nat -D POSTROUTING -o wg0 -p tcp --dport 8123 -d 192.168.1.63 -j SNAT --to-source 10.66.66.1

### Client docker
[Peer]
PublicKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PresharedKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
AllowedIPs = 10.66.66.3/24,192.168.1.0/24

@Fabien m'a également fait remarqué qu'une bonne sécurisation du VPS était nécessaire puisque qu'il est directement exposé sur Intenet.

J'espère bien lui soutirer des informations pour rédiger un petit article sur le sujet...à suivre.

C'est terminé, on peut  accéder à des services hébergés sur le réseau interne  avec une box 4G en redirigeant les ports depuis le VPS...fini la box ADSL !