Aller au contenu

L'architecture

Le principe

Un conteneur Docker possède par défaut sa propre pile réseau : ses interfaces, sa table de routage, ses règles de pare-feu, ses sockets. C'est exactement ce qu'il faut ici.

                    ┌─────────────────── serveur unique ───────────────────┐
                    │                                                      │
   IP rés. #1 ◄─────┼── wg-1 ──► [ passerelle 1 ] ◄── [ myst-node-1 ]      │
   IP rés. #2 ◄─────┼── wg-2 ──► [ passerelle 2 ] ◄── [ myst-node-2 ]      │
   IP rés. #3 ◄─────┼── wg-3 ──► [ passerelle 3 ] ◄── [ myst-node-3 ]      │
        ...         │                     ...                              │
                    └──────────────────────────────────────────────────────┘

Chaque node vit dans la pile réseau de sa passerelle. Il ne voit qu'une seule interface, celle du tunnel, et l'adresse publique qu'il détecte est celle du fournisseur résidentiel. Du point de vue de Mysterium, ce sont N machines distinctes sur N adresses distinctes — ce que la règle « un node par IP publique » exige.

Pourquoi ça satisfait la règle de Mysterium

La règle interdit plusieurs nodes derrière la même IP publique. Ici chaque node sort par une adresse différente. Le fait qu'ils partagent le même processeur n'entre pas en compte : le réseau ne voit que des adresses.

Ce que Mysterium exige du réseau

Élément Valeur Source
Port du service par défaut 1194/UDP centre d'aide
Plage de ports du service 10000-60000/UDP Kryptex
Perçage de NAT drapeau --nat-port-mapping=false pour donner la priorité au hole punching centre d'aide
Docker sans interface publique --net default --publish "1194:1194/udp" puis redirection IP_PUBLIQUE:1194 → IP_NODE:1194 image Docker officielle

Le piège de --net host

La documentation Docker de Mysterium recommande --net host « pour détecter correctement l'IP du service VPN sous Linux ». C'est précisément ce qu'il ne faut pas faire ici : --net host place le conteneur dans la pile réseau de l'hôte, donc tous les nodes partageraient la même adresse — exactement le cas interdit.

La documentation fournit elle-même l'alternative, citée dans le tableau ci-dessus : mode réseau normal, publication du port, redirection. C'est cette voie qu'il faut suivre, avec une pile par node.

Le point critique : rendre le node joignable

C'est là que tout se joue, et c'est ce qu'il faut vérifier auprès du fournisseur avant d'acheter.

Deux voies possibles, par ordre de préférence :

Voie A — Redirection de port côté fournisseur

La meilleure. Le fournisseur redirige un port entrant de l'IP résidentielle vers votre extrémité du tunnel. Le node est directement joignable, sans dépendre d'aucune heuristique.

Limite à anticiper : la plupart des fournisseurs qui proposent la redirection n'ouvrent qu'un seul port, alors que le service utilise une plage de 10000 à 60000. Il faut donc soit une plage, soit épingler le node sur le port unique disponible via sa configuration de service.

Voie B — Perçage de NAT à travers le tunnel

WireGuard transporte de l'UDP nativement, donc le hole punching peut fonctionner à travers le tunnel. Le succès dépend entièrement du type de NAT que le fournisseur applique en sortie :

Type de NAT côté fournisseur Perçage
Cone (full, restricted, port-restricted) Fonctionne
Symétrique Échoue

C'est exactement l'objet de l'issue #3817 du dépôt, consacrée à l'activation du perçage de NAT sous Docker en NAT port restricted cone.

La question à poser au support avant de payer

« Quel type de NAT appliquez-vous en sortie sur les IP résidentielles dédiées, et proposez-vous une redirection de port entrante ? »

Si la réponse est « NAT symétrique, pas de redirection », le montage ne fonctionnera pas — c'est le scénario de l'issue #4083, avec le débit qui s'effondre à 51 ko.

Le squelette Docker Compose

Le motif standard est celui de la passerelle en side-car : un conteneur qui monte le tunnel, et un conteneur applicatif qui rejoint sa pile réseau via network_mode: container:<nom>. C'est le fonctionnement documenté de gluetun, qui gère WireGuard et OpenVPN et inclut un coupe-circuit.

# ponytail: un bloc de 2 services par IP. Répétitif mais explicite —
# une boucle de génération viendra quand le nombre de nodes le justifiera.
services:

  gw-1:
    image: qmcgaw/gluetun
    cap_add: [NET_ADMIN]
    devices: ["/dev/net/tun:/dev/net/tun"]
    environment:
      VPN_SERVICE_PROVIDER: custom
      VPN_TYPE: wireguard
      WIREGUARD_PRIVATE_KEY: ${WG1_PRIVATE_KEY}
      WIREGUARD_ADDRESSES: ${WG1_ADDRESS}
      WIREGUARD_PUBLIC_KEY: ${WG1_PEER_PUBLIC_KEY}
      WIREGUARD_ENDPOINT_IP: ${WG1_ENDPOINT_IP}
      WIREGUARD_ENDPOINT_PORT: ${WG1_ENDPOINT_PORT}
      FIREWALL_OUTBOUND_SUBNETS: 172.16.0.0/12
    restart: unless-stopped

  myst-1:
    image: mysteriumnetwork/myst:latest
    network_mode: "container:gw-1"     # <- la clé de tout le montage
    depends_on: [gw-1]
    cap_add: [NET_ADMIN]
    devices: ["/dev/net/tun:/dev/net/tun"]
    volumes: ["./data/myst-1:/var/lib/mysterium-node"]
    command: >
      --nat-port-mapping=false
      service --agreed-terms-and-conditions
    restart: unless-stopped

  # gw-2 / myst-2, gw-3 / myst-3, … : idem avec les variables WG2_, WG3_…

Une limite de gluetun à connaître

gluetun ne monte qu'un seul tunnel par conteneur. Il faut donc autant de conteneurs passerelle que d'adresses — c'est la solution que la communauté applique, un utilisateur rapportant avoir monté 43 conteneurs identiques (discussion #1455).

Ce n'est pas un problème de fond, seulement du texte à générer. Un fichier Compose de 40 nodes se produit avec une boucle de dix lignes.

Vérifications après démarrage

Trois contrôles, à faire node par node :

  1. L'adresse de sortie est la bonne et elle est résidentielle.

    docker exec gw-1 wget -qO- https://ipinfo.io/json
    
    Vérifier le champ org (doit être un opérateur grand public, pas un hébergeur) et l'absence de mention hosting dans les champs de confidentialité.

  2. Deux nodes ne sortent jamais par la même adresse. Comparer les sorties de la commande précédente pour toutes les passerelles. Une collision signifie un node qui ne gagnera rien.

  3. Le node est joignable. Le tableau de bord MystNodes doit afficher le node en ligne avec le bon pays, et le type de NAT détecté doit être différent de « symétrique ».

Le seul indicateur qui compte ensuite

Ni le nombre de conteneurs qui démarrent, ni le drapeau vert du tableau de bord. Le volume de données réellement transféré, comparé à celui d'un node direct sur la même période. C'est la mesure du facteur de qualité, et c'est l'objet du protocole de test.


Suite : Les fournisseurs compatibles