Monter son serveur VPS Wireguard et l'utiliser avec un client Docker + kill switch + proxy

proxy 8 nov. 2021

J’utilise depuis un petit bout de temps un VPS IONOS en guise de serveur VPN basé sur Wireguard. Ce protocole VPN bride moins le débit qu’OpenVPN et c’est bien pratique dans le cadre d’une utilisation “dédiée au trafic” (voici une idée des performances avec/sans VPN, celles-ci sont très aléatoires et données à titre indicatif). IONOS est le moins cher que j’avais trouvé mais ça fonctionne tout aussi bien avec des VPS OVH (trafic illimité), Vultr (Cloud Compute, trafic selon l’offre) ou encore Hetzner (Cloud, 20Tb de trafic mensuel).

IONOS permet de louer un VPS dès 1.20€ TTC/mois (sans engagement contrairement à mes souvenirs) avec un trafic illimité et une bande passante de 400Mbps (malgré ma ligne fibre de 1Gbps c’est déjà pas mal). 512Mo de RAM suffisant amplement pour un serveur VPN (OpenVPN comme Wireguard). J’installe mon serveur avec le script d’Angristan et côté client je passe par 2 Dockers (dont 1 que je viens de changer car plus récent) : un client Wireguard avec kill switch/proxy/DNS over TLS etc d’intégrés de Quentin McGaw.

Au menu :

Il est compliqué de trouver un VPS qui allie petit prix et bande passante + trafic. Je privilégie IONOS pour son prix, 1.20€ TTC et son trafic illimité. La bande passante est limitée à 400Mbps, en deçà de mon débit fibre (1000/600Mbps) mais ce sera amplement suffisant pour mon utilisation : torrenting (rarement), bouncer IRC, streaming et surf.

Une fois le compte validé par IONOS (pas la peine de penser Tor/BTC avec eux), je prends possession de mon VPS. J’y installe Debian 10 (besoin d’1GB de RAM pour Debian 11) et y adjoins une clé SSH (un mot de passe fonctionne aussi).

On peut suivre l’état d’avancement sur l’interface. IONOS oblige ensuite à définir une stratégie de pare-feu.

Pour pouvoir s’y connecter en SSH il est impératif d’ouvrir le port TCP 22 puis on peut définir un port UDP pour notre serveur Wireguard (ce que vous voulez). Ce sont évidemment de sports d’entrée, par défaut leur firewall ne ferme aucun port de sortie.

Wireguard n’est pas par défaut dans les dépôts de Debian 10 et son noyau de base ne le supporte pas (5.6 minimum)

root@localhost:~# uname -sr
Linux 4.19.0-18-amd64

On doit donc installer les backports, rafraichir les sources et mettre à jour vers un nouveau noyau (5.10 ici)

root@localhost:~# sh -c "echo 'deb http://deb.debian.org/debian buster-backports main contrib non-free' > /etc/apt/sources.list.d/buster-backports.list"

root@localhost:~# apt-get update

root@localhost:~# apt-get install -y linux-image-5.10.0-0.bpo.9-amd64 linux-image-amd64

Après un reboot, le noyau est bien à jour

root@localhost:~# uname -r
5.10.0-0.bpo.9-amd64

Je peux ensuite y installer mon serveur Wireguard via le script d’Angristan. On vérifie/intègre quelques paramètres : le port Wireguard est évidemment celui qu’on a ouvert dans le pare-feu IONOS. Et j’utilise les DNS de dns.watch et quad9.

root@localhost:~# curl -O https://raw.githubusercontent.com/angristan/wireguard-install/master/wireguard-install.sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 15088  100 15088    0     0  94300      0 --:--:-- --:--:-- --:--:-- 94300

root@localhost:~# chmod +x wireguard-install.sh

root@localhost:~# ./wireguard-install.sh
Welcome to the WireGuard installer!
The git repository is available at: https://github.com/angristan/wireguard-install

I need to ask you a few questions before starting the setup.
You can leave the default options and just press enter if you are ok with them.

IPv4 or IPv6 public address: 123.456.789.10
Public interface: ens192
WireGuard interface name: wg0
Server's WireGuard IPv4: 10.66.66.1
Server's WireGuard IPv6: fd42:42:42::1
Server's WireGuard port [1-65535]: 60177
First DNS resolver to use for the clients: 84.200.69.80
Second DNS resolver to use for the clients (optional): 9.9.9.9

Okay, that was all I needed. We are ready to setup your WireGuard server now.
You will be able to generate a client at the end of the installation.
Press any key to continue...

Je lance l’installation dans la foulée. Il faut entrer un nom de client, pour moi ce sera NUC2 car il sera utilisé sur mon… NUC n°2 (je suis un grand créatif !)

Tell me a name for the client.
The name must consist of alphanumeric character. It may also include an underscore or a dash and can't exceed 15 chars.
Client name: NUC2
Client's WireGuard IPv4: 10.66.66.2
Client's WireGuard IPv6: fd42:42:42::2

Here is your client config file as a QR Code:

[QRcode]

It is also available in /root/wg0-client-NUC2.conf
If you want to add more clients, you simply need to run this script another time!

Et voilà. Serveur installé. Je peux déjà afficher le contenu de la configuration (cat /root/wg0-client-NUC2.conf) en vue de son utilisation dans le client Docker.

[Interface]
PrivateKey = abc
Address = 10.66.66.2/32,fd42:42:42::2/128
DNS = 84.200.69.80,9.9.9.9

[Peer]
PublicKey = def
PresharedKey = ghi
Endpoint = 123.456.789.10:60177
AllowedIPs = 0.0.0.0/0,::/0

En guise de client je passe par le Docker gluetun de qdm12. Il est très complet !
Outre qu’il soit prévu pour un bon nombre de fournisseurs VPN, ilest compatible OpenVPN comme Wireguard, intère un kill switch (qui empêche une connexion hors VPN si le serveur distant est HS), un proxy shadowsock(SOCKS5)/HTTP/HTTPS, compatible ARM etc. En gros, il manque juste le café ^^


J’installe ça sur le NUC2, dans sa version Custom Provider

docker run -d \
--name wireguard \
--restart always \
--cap-add=NET_ADMIN \
-e TZ=Europe/Paris \
-e VPNSP=custom \
-e VPN_TYPE=wireguard \
-e WIREGUARD_ENDPOINT_IP=123.456.789.10 \
-e WIREGUARD_ENDPOINT_PORT=60177 \
-e WIREGUARD_PUBLIC_KEY=def \
-e WIREGUARD_PRIVATE_KEY=abc \
-e WIREGUARD_PRESHARED_KEY=ghi \
-e WIREGUARD_ADDRESS="10.66.66.2/32" \
--label=com.centurylinklabs.watchtower.enable=true \
qmcgaw/gluetun

Il suffit de remplir d’après de le fichier de configuration client Wireguard juste au-dessus :
PUBLIC_KEY = PublicKey
PRIVATE_KEY = PrivateKey
PRESHARED_KEY = PresharedKey
Et comme souvent j’ajoute Watchtower.

On peut vérifier que tout fonctionne dans les logs du Docker

root@NUC2:/home/aerya/# docker logs wireguard
========================================
========================================
=============== gluetun ================
========================================
=========== Made with ❤️ by ============
======= https://github.com/qdm12 =======
========================================
========================================

Running version latest built on 2021-11-07T21:29:28.361Z (commit 6ffb94f)

[...]

2021/11/08 14:40:40 INFO vpn: You are running on the bleeding edge of latest!
2021/11/08 14:40:41 INFO ip getter: Public IP address is 123.4456.789.10 (xxx xxx xxx)

[...]

Ou en suivant le Wiki. Pensez à changer le nom du Docker client “gluetun” pour le nom de votre Docker

root@NUC2:/home/aerya/docker/wireguard# docker run --rm --network=container:wireguard alpine:3.14 sh -c "apk add wget && wget -qO- https://ipinfo.io"
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz
(1/3) Installing libunistring (0.9.10-r1)
(2/3) Installing libidn2 (2.3.1-r0)
(3/3) Installing wget (1.21.1-r1)
Executing busybox-1.33.1-r3.trigger
OK: 8 MiB in 17 packages
{
  "ip": "123.456.789.10",
  "city": "xxx",
  "region": "xxx",
  "country": "xxx",
  "loc": "xxx",
  "org": "AS8560 IONOS SE",
  "postal": "60306",
  "timezone": "Europe/Berlin",
  "readme": "https://ipinfo.io/missingauth"

Son utilisation est simple. Par exemple pour faire en sorte que mon Docker ruTorrent passe par le VPN, il suffit de le forcer à utiliser le réseau de ce dernier via l’option –network=container:wireguard (ou tout autre nom que vous auriez donné à votre Docker client).
Le fait de faire passer un container par le réseau d’un autre empêche de publier un port. En effet, la publication de port (-p 927/80 \) n’est utile que lorsqu’on peut y accéder directement. Et vu que ça passe par le réseau VPN, ce n’est pas le cas.

Le principe est le même pour tous les containers Dockers (sauf rares exceptions) : bouncer IRC (ZNC), blog, Nextcloud… A vous de voir l’intérêt de faire transiter telle ou telle application par un VPN.

docker run -d \
--name=rutorrentwireguard \
--restart always \
-v /home/aerya/docker/rutorrentwireguard/config:/config \
-v /mnt:/downloads \
-e PGID=0 -e PUID=0 \
-e TZ=Europe/Paris \
--net=container:wireguard \
romancin/rutorrent:0.9.8

Pour vérifier que le container ruTorrent accède bien au Web via le VPN je contrôle son IP publique (qui est donc celle de mon VPS IONOS)

root@NUC2:/home/aerya# docker exec -it rutorrentwireguard curl icanhazip.com
123.456.789.10

Et donc pour accéder à mon Docker ruTorrent, c’est dans le Docker VPN que je dois publier le port de l’interface Web : c’est le port mapping.
Concrètement, si je veux accéder à mon interface port 80 depuis mon réseau local, alors qu’il accède à Internet via le VPN, je dois ouvrir le port 80 dans le Docker VPN.

Avec -p 927/80 \ j’accéderai à ruTorrent via le port 927.

/!\ pour lancer cette version du Docker wireguard, supprimez l’existant (docker stop wireguard puis docker rm wireguard)

docker run -d \
--name wireguard \
--restart always \
--cap-add=NET_ADMIN \
-e TZ=Europe/Paris \
-e VPNSP=custom \
-e VPN_TYPE=wireguard \
-e WIREGUARD_ENDPOINT_IP=123.456.789.10 \
-e WIREGUARD_ENDPOINT_PORT=60177 \
-e WIREGUARD_PUBLIC_KEY=def \
-e WIREGUARD_PRIVATE_KEY=abc \
-e WIREGUARD_PRESHARED_KEY=ghi \
-e WIREGUARD_ADDRESS="10.66.66.2/32" \
-p 927/80 \
--label=com.centurylinklabs.watchtower.enable=true \
qmcgaw/gluetun

On peut aussi s’en servir de proxy pour un navigateur ou une application. Voici un exemple avec un proxy HTTP

/!\ pour lancer cette version du Docker wireguard, supprimez l’existant (docker stop wireguard puis docker rm wireguard)

docker run -d \
--name wireguard \
--restart always \
--cap-add=NET_ADMIN \
-e TZ=Europe/Paris \
-e VPNSP=custom \
-e VPN_TYPE=wireguard \
-e WIREGUARD_ENDPOINT_IP=123.456.789.10 \
-e WIREGUARD_ENDPOINT_PORT=60177 \
-e WIREGUARD_PUBLIC_KEY=def \
-e WIREGUARD_PRIVATE_KEY=abc \
-e WIREGUARD_PRESHARED_KEY=ghi \
-e WIREGUARD_ADDRESS="10.66.66.2/32" \
-p 927:80/tcp \
-p 8888:8888/tcp \
-e HTTPPROXY=on \
-e HTTPPROXY_PORT=8888 \
-e HTTPPROXY_USER=aerya \
-e HTTPPROXY_PASSWORD=motdepasse \
-e HTTPPROXY_STEALTH=on \
--label=com.centurylinklabs.watchtower.enable=true \
qmcgaw/gluetun

Faut bien entendu publier le port du proxy HTTP (j’ai laissé celui par défaut) : 8888. On peut l’utiliser par exemple avec l’extension de navigateurs FoxyProxy

EDIT : ajout d’un exemple de vitesse. Je suis pas resté devant l’écran pour voir le DL* mais voici l’upload au travers du VPN (ce sont des Mo/s donc x8 pour avoir des Mb/s)

*je viens de prendre 5 minutes :)

Mots clés