SSD Nodes Learn 🎉 VPS dès $5.50/mois
Guides Matt ConnorPar Matt Connor

Redirection de port Gluetun pour client torrent

Les téléchargements fonctionnent, mais aucune connexion entrante n’arrive. Configurez la redirection Gluetun, transmettez le nouveau port à chaque reconnexion et vérifiez-le.

Pourquoi rien ne se connecte sans port redirigé

La redirection de port de Gluetun demande à votre fournisseur VPN d’associer un port public de son adresse de sortie à votre conteneur. C’est le seul moyen pour qu’un autre pair puisse établir une connexion vers votre client torrent. Sans cette association, le tunnel fonctionne, les téléchargements s’exécutent, et aucune connexion entrante ne peut s’établir spontanément. Chaque connexion fonctionnelle est initiée par votre client.

Le mécanisme utilisé est le NAT (network address translation). Votre conteneur partage l’adresse de sortie du fournisseur avec de nombreux autres clients. Lorsque votre client ouvre une connexion sortante, le fournisseur enregistre ce flux et renvoie les réponses dans votre tunnel. La connexion entrante d’un pair inconnu ne correspond à aucun flux enregistré. Le paquet atteint donc l’adresse de sortie, où il est supprimé. Votre client peut toujours joindre tous les pairs qui acceptent eux-mêmes les connexions. Les téléchargements se terminent donc normalement et le problème reste invisible. Il apparaît lors du seeding, car un seeder est une machine à laquelle d’autres utilisateurs se connectent.

Un port entrant ouvert change deux éléments. Vous rejoignez un swarm plus rapidement, car les pairs qui ne peuvent pas accepter eux-mêmes les connexions peuvent désormais vous joindre. Vous pouvez également leur envoyer des données.

Pourquoi la plupart des fournisseurs de VPN ne proposent pas de redirection de port

Un port redirigé est une ressource rare sur une adresse partagée. Le fournisseur réserve un numéro de port sur une adresse IP de sortie pour un client, puis répond de ce que ce client en fait. Plusieurs grands fournisseurs ont supprimé cette fonctionnalité en invoquant la gestion des abus. Considérez cette prise en charge comme une question de catégorie plutôt que comme une simple case à cocher : demandez si le fournisseur propose actuellement la redirection de port, avec votre offre et sur des serveurs que vous pouvez réellement sélectionner.

Lorsque la redirection existe, le port est dynamique. Il est associé à la session VPN et non à votre compte. Il peut donc être différent après chaque reconnexion. Private Internet Access attribue un port signé que gluetun renouvelle. La documentation en amont indique que vous conservez le même port pendant 60 jours, à condition de monter le répertoire /gluetun avec un bind mount afin que cet état soit conservé après un redémarrage. ProtonVPN attribue un port aléatoire via NAT-PMP (NAT port mapping protocol), avec un bail de courte durée qui doit être renouvelé en continu. C’est pourquoi définir le port une seule fois dans le client ne fonctionne jamais durablement.

Quels fournisseurs gluetun peut interroger pour obtenir un port

À partir de gluetun v3.41.3, publié le 30 July 2026, l’intégration native valide quatre noms de fournisseurs : Private Internet Access, ProtonVPN, Perfect Privacy et PrivateVPN. Activez-la avec VPN_PORT_FORWARDING=on, qui vaut off par défaut. Les anciens guides utilisent PORT_FORWARDING ou PRIVATE_INTERNET_ACCESS_VPN_PORT_FORWARDING. Ces deux noms fonctionnent encore dans cette version pour assurer la rétrocompatibilité, mais ils sont progressivement abandonnés.

Deux éléments propres au fournisseur déterminent si la demande peut aboutir. ProtonVPN nécessite une offre payante, et NAT-PMP doit être activé : activez NAT-PMP (Port Forwarding) dans les options VPN lors de la génération de la configuration WireGuard, ou ajoutez +pmp à votre nom d’utilisateur avec OpenVPN. Avec OpenVPN, Private Internet Access utilise PORT_FORWARD_ONLY, qui limite la sélection des serveurs à ceux qui prennent en charge le port forwarding. Vous évitez ainsi de vous connecter à un serveur qui ne l’a jamais pris en charge. WireGuard et OpenVPN diffèrent dans la façon de demander le port, consultez donc la page de votre fournisseur avant de faire votre choix.

Lorsque gluetun utilise une configuration personnalisée au lieu d’un fournisseur intégré, VPN_PORT_FORWARDING_PROVIDER indique l’API que gluetun doit appeler. La page officielle de Private Internet Access associe cette variable à VPN_PORT_FORWARDING_USERNAME et VPN_PORT_FORWARDING_PASSWORD, qui contiennent les identifiants nécessaires à la demande de port.

Activer la redirection de port de gluetun dans docker compose

Cette procédure suppose que le tunnel fonctionne déjà. Si ce n’est pas le cas, commencez par faire passer le trafic des conteneurs Docker par gluetun, puis revenez ici une fois les téléchargements opérationnels.

services:
  gluetun:
    image: qmcgaw/gluetun:v3.41.3
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    ports:
      - 8080:8080/tcp
      - 8000:8000/tcp
    volumes:
      - ./gluetun:/gluetun
    environment:
      - VPN_SERVICE_PROVIDER=protonvpn
      - VPN_TYPE=wireguard
      - WIREGUARD_PRIVATE_KEY=${WIREGUARD_PRIVATE_KEY}
      - VPN_PORT_FORWARDING=on
      - TZ=Etc/UTC
    restart: unless-stopped

  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:5.2.3
    container_name: qbittorrent
    network_mode: "service:gluetun"
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - WEBUI_PORT=8080
    volumes:
      - ./qbittorrent:/config
      - ./downloads:/downloads
    depends_on:
      - gluetun
    restart: unless-stopped

Figez le tag. qmcgaw/gluetun:latest suit la branche master, où l’implémentation interne de la redirection de port évolue pour la v4. Une image sans tag figé peut donc modifier son comportement au prochain docker compose pull. Conservez la clé privée hors du fichier compose avec un fichier d’environnement pour les secrets de compose.

Où gluetun écrit le port transféré

Gluetun expose le port à trois endroits, qui contiennent tous la même valeur.

Il journalise le port une fois par acquisition. La ligne contient port forwarded is 45678, et no port forwarded lorsque la requête ne renvoie rien.

docker logs gluetun 2>&1 | grep -i "port forwarded"

Il écrit le numéro dans le fichier indiqué par VPN_PORT_FORWARDING_STATUS_FILE, dont la valeur par défaut est /tmp/gluetun/forwarded_port. Le fichier contient un port par ligne, est écrit avec le mode 0644 et son propriétaire et son groupe sont définis sur ceux du conteneur, PUID et PGID. Lorsque la redirection s’arrête, gluetun vide le fichier au lieu de le supprimer. Un consommateur peut donc lire un fichier vide au lieu d’obtenir une erreur parce que le fichier est absent.

docker exec gluetun cat /tmp/gluetun/forwarded_port

Il fournit la valeur sur le control server, qui écoute par défaut sur :8000 et est configuré par HTTP_CONTROL_SERVER_ADDRESS.

curl -s http://127.0.0.1:8000/v1/portforward
{"port":45678,"ports":[45678]}

Gluetun ouvre également ce port dans son propre firewall sur l’interface VPN. FIREWALL_VPN_INPUT_PORTS n’est donc pas nécessaire lorsque l’intégration native effectue le travail. Cette variable couvre l’autre cas : un provider que gluetun ne peut pas interroger, lorsque vous avez reçu un port statique par un autre canal et devez l’autoriser manuellement.

L’une de ces trois méthodes est durable, les deux autres ne le sont pas. La documentation amont indique que le fichier d’état est deprecated depuis v4.0.0, et GET /v1/openvpn/portforwarded renvoie déjà 301 Moved Permanently en indiquant /v1/portforward. Les nouveaux développements doivent lire le control server.

Pourquoi le client doit recevoir le port à chaque reconnexion

Un client torrent enregistre son port d’écoute dans sa propre configuration et conserve ce numéro après chaque redémarrage. Le port redirigé est une propriété de la session VPN. Après une reconnexion, les deux numéros ne correspondent plus : le fournisseur redirige un port sur lequel rien n’écoute, tandis que le client écoute sur un port qui n’est pas redirigé. Les reconnexions ne sont pas rares : redémarrage d’un conteneur, changement de serveur, tunnel interrompu puis redémarré par le health check de gluetun, ou lease qui n’a pas pu être renouvelé. Le résultat est une configuration qui était accessible hier, mais qui ne l’est plus aujourd’hui, silencieusement, sans erreur dans aucun des deux journaux.

Le port doit donc être appliqué au moment où gluetun l’obtient. Deux méthodes permettent de mettre cela en place. Elles diffèrent selon le processus qui effectue cette opération.

Option 1 : gluetun transmet le port avec une commande up

VPN_PORT_FORWARDING_UP_COMMAND s’exécute lorsque la redirection de port est disponible, et VPN_PORT_FORWARDING_DOWN_COMMAND s’exécute lorsqu’elle est supprimée. Gluetun remplace {{PORT}} (le premier port), {{PORTS}} (tous les ports, séparés par des virgules) et {{VPN_INTERFACE}} (le nom de l’interface du tunnel, tun0 par défaut) avant d’exécuter la commande. La syntaxe shell nécessite un wrapper /bin/sh -c explicite. Voici l’exemple qBittorrent fourni par le projet, écrit sous la forme de deux entrées d’environnement Compose :

      - VPN_PORT_FORWARDING_UP_COMMAND=/bin/sh -c 'wget -O- -nv --retry-connrefused --post-data "json={\"listen_port\":{{PORT}},\"current_network_interface\":\"{{VPN_INTERFACE}}\",\"random_port\":false,\"upnp\":false}" http://127.0.0.1:8080/api/v2/app/setPreferences'
      - VPN_PORT_FORWARDING_DOWN_COMMAND=/bin/sh -c 'wget -O- -nv --retry-connrefused --post-data "json={\"listen_port\":0,\"current_network_interface\":\"lo\"}" http://127.0.0.1:8080/api/v2/app/setPreferences'

Chaque champ de cet appel a une fonction. listen_port correspond au nouveau port. current_network_interface lie qBittorrent au tunnel. Définir random_port sur false empêche qBittorrent de choisir son propre port au prochain démarrage. Définir upnp sur false l’empêche d’essayer de mapper un port via un routeur qui n’existe pas.

Cette approche impose deux conditions. L’interface web de qBittorrent doit répondre sur 127.0.0.1:8080 depuis le conteneur gluetun. C’est automatique lorsque le client partage le network namespace de gluetun. Bypass authentication for clients on localhost (bypass_local_auth) doit également être activé, car la commande n’envoie aucun identifiant. La commande down est nécessaire, car qBittorrent ne rétablit pas toujours le port après une déconnexion.

La commande s’exécute dans le conteneur gluetun, basé sur Alpine, qui fournit wget. Cette image ne contient pas curl. Une commande qui fait référence à un binaire absent de l’image échoue à chaque activation de la redirection de port.

Option 2 : un processus externe à gluetun lit le port

L’autre modèle consiste à exécuter un petit processus à côté de gluetun. Il récupère le port, puis le transmet au client via l’API de celui-ci. Lisez-le depuis le serveur de contrôle :

port=$(curl -s http://127.0.0.1:8000/v1/portforward | jq -r .port)

Vous pouvez aussi lire le fichier si le processus peut y accéder. /tmp/gluetun/forwarded_port se trouve dans le conteneur gluetun. Un sidecar doit donc utiliser un volume partagé, monté sous /tmp/gluetun dans les deux conteneurs. Vous pouvez aussi faire pointer VPN_PORT_FORWARDING_STATUS_FILE vers un chemin situé dans un volume déjà monté.

L’authentification est importante. Dans v3.41.3, la route GET /v1/portforward appartient à un rôle par défaut nommé public, avec auth = "none". Elle répond donc sans identifiants, et gluetun journalise un avertissement commençant par route GET /v1/portforward is unprotected by default, please set up authentication. Une version ultérieure supprimera ce comportement. Définissez dès maintenant un rôle dans le fichier monté via bind mount sous /gluetun/auth/config.toml :

roles = [
  { name = "qbittorrent", routes = ["GET /v1/portforward"], auth = "apikey", apikey = "myapikey" }
]

Générez une clé avec docker run --rm qmcgaw/gluetun:v3.41.3 genkey et envoyez-la dans l’en-tête X-API-Key. HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE remplit la même fonction qu’une variable d’environnement encodée en JSON lorsque vous préférez ne pas monter de fichier. Publier le port 8000 sans rôle permet à toute personne qui peut l’atteindre de contrôler l’état du VPN. Décidez donc volontairement jusqu’où il doit être accessible lorsque vous déterminez comment atteindre gluetun depuis l’hôte et les autres conteneurs.

Choisissez la commande up lorsque le client expose une API qu’un appel wget peut piloter, car elle s’exécute exactement une fois par événement et n’a pas besoin de rester active. Choisissez un processus externe lorsque le client nécessite une procédure de connexion, la réécriture d’un fichier de configuration ou un redémarrage. Dans une stack arr derrière un seul conteneur gluetun, cela se termine généralement par un seul petit poller, car seul le client torrent utilise le port.

Le piège : partager le namespace ne définit pas le port d’écoute

Cette erreur fait perdre le plus de temps. network_mode: "service:gluetun" place le client dans le namespace réseau de gluetun. Il dispose donc de l’adresse IP du VPN, des routes du tunnel et des règles de pare-feu de gluetun. Rien de tout cela ne définit le port d’écoute du client. Gluetun ouvre le port redirigé sur l’interface VPN. Les paquets qui lui sont destinés arrivent dans le namespace. Si le client écoute sur un autre port, le kernel ne peut les remettre à aucun processus. La connexion est refusée ou expire, alors que tous les tests de trafic sortant sont concluants. Le port redirigé et le port d’écoute du client sont deux valeurs distinctes. La configuration consiste à les rendre identiques.

Comparez-les au lieu de deviner. Les deux commandes utilisent le même namespace :

docker exec gluetun cat /tmp/gluetun/forwarded_port
docker exec gluetun wget -qO- http://127.0.0.1:8080/api/v2/app/preferences | grep -o '"listen_port":[0-9]*'

Un autre réglage peut vous orienter dans la mauvaise direction. VPN_PORT_FORWARDING_LISTENING_PORT redirige le trafic entrant du port redirigé vers un port local fixe à l’aide d’iptables. La documentation en amont déconseille de l’utiliser avec les clients torrent, car le client annonce son propre port d’écoute aux trackers et aux pairs. Le swarm apprend donc un numéro incorrect.

Comment vérifier que le port redirigé est accessible

L’indicateur de connexion du client reflète ses connexions sortantes aux trackers. Il peut donc être vert alors qu’aucune connexion ne peut vous atteindre. Effectuez le test avec un listener que vous contrôlez, depuis un réseau situé en dehors du tunnel. Upstream fournit un petit outil pour cela. Arrêtez d’abord le client torrent, car deux processus ne peuvent pas écouter sur le même port.

docker stop qbittorrent
docker exec -it gluetun /bin/sh

Dans le conteneur, remplacez amd64 par l’architecture de votre CPU et 4567 par votre port redirigé :

wget -qO port-checker https://github.com/qdm12/port-checker/releases/download/v0.4.0/port-checker_0.4.0_linux_amd64
chmod +x port-checker
./port-checker --listening-address=":4567"

Recherchez maintenant l’adresse de sortie utilisée par gluetun. La réponse est au format JSON et l’adresse se trouve dans le champ public_ip.

curl -s http://127.0.0.1:8000/v1/publicip/ip

Ouvrez http://<that address>:4567 depuis un appareil qui n’utilise pas le même VPN. Un téléphone connecté au réseau mobile convient. Une page affichant l’adresse IP et le user agent de votre navigateur, avec une requête correspondante enregistrée par port-checker, indique que les connexions TCP entrantes atteignent le namespace. Un timeout indique le contraire. La cause se situe alors en amont du client. Arrêtez l’outil avec CTRL+C, quittez le shell avec exit, puis redémarrez le client. Ce test vérifie uniquement TCP. Le trafic DHT (distributed hash table) et uTP utilise UDP sur le même numéro de port, ce que ce test ne vérifie pas.

Modes d’échec et messages affichés

Aucune ligne de port dans les logs. Aucun port n’a été demandé. Vérifiez que la variable est bien parvenue au conteneur avec docker exec gluetun printenv | grep PORT_FORWARDING, car une variable définie dans le mauvais service Compose est une cause fréquente.

Gluetun refuse de démarrer et signale un problème avec le fournisseur. VPN_PORT_FORWARDING_PROVIDER est validé par rapport aux quatre noms pris en charge. Une faute de frappe arrête donc le conteneur au lieu de le laisser fonctionner sans port forwarding.

Le log contient no port forwarded. Gluetun a envoyé une demande, mais le fournisseur n’a rien renvoyé. Avec ProtonVPN, cela signifie généralement que NAT-PMP n’était pas activé dans la configuration générée ou que l’offre ne comprend pas le port forwarding. Avec Private Internet Access, cela signifie généralement que le serveur sélectionné ne le propose pas.

Un port est attribué, mais aucune connexion entrante n’aboutit. Comparez le port forwardé avec le port d’écoute du client à l’aide des deux commandes ci-dessus. S’ils correspondent, vérifiez que le client est lié à l’interface du tunnel et que son option de port aléatoire est désactivée, car cette option réécrit le port d’écoute à chaque démarrage.

La commande up semble ne rien faire. Exécutez la commande exacte dans le conteneur pour voir l’erreur : docker exec gluetun /bin/sh -c '<your command>'. curl: not found est le résultat habituel, car l’image contient uniquement wget.

401 Unauthorized depuis le serveur de contrôle. Vous avez défini une configuration d’authentification, mais le rôle ne liste pas la route que vous appelez. Les routes sont comparées selon la méthode et le chemin. Un rôle qui liste uniquement /v1/portforward ne couvre donc pas GET /v1/portforward.

Un port différent est attribué à Private Internet Access après chaque redémarrage. Montez /gluetun en bind mount afin que l’état du port enregistré survive au redémarrage. Sans ce volume, gluetun demande un nouveau port à chaque démarrage.

FAQ

Pourquoi mes torrents se téléchargent-ils sans jamais recevoir de connexions entrantes ?

Sans port redirigé, le fournisseur VPN ne dispose d’aucune règle NAT qui envoie les paquets entrants vers votre tunnel. Les connexions que vous n’avez pas initiées sont donc abandonnées à l’adresse de sortie. Les téléchargements fonctionnent quand même, car votre client ouvre lui-même ces connexions et peut joindre n’importe quel pair accessible. Le seeding et l’accès aux swarms sont en revanche limités, car ils dépendent tous deux de connexions initiées par d’autres utilisateurs vers votre client. La solution consiste à choisir un fournisseur qui propose la redirection de ports, à configurer VPN_PORT_FORWARDING=on dans gluetun, puis à appliquer le port obtenu au port d’écoute du client.

gluetun fonctionne-t-il avec la redirection de ports de n’importe quel fournisseur VPN ?

Non. gluetun v3.41.3 intègre nativement quatre fournisseurs : Private Internet Access, ProtonVPN, Perfect Privacy et PrivateVPN. Tout fournisseur absent de cette liste échoue à la validation de VPN_PORT_FORWARDING_PROVIDER, et le conteneur s’arrête au démarrage. Si votre fournisseur attribue un port statique depuis son propre panneau de contrôle, gluetun ne peut pas le demander à votre place. En revanche, FIREWALL_VPN_INPUT_PORTS permet d’autoriser ce port fixe dans le firewall de gluetun. Les politiques des fournisseurs évoluent. Consultez donc leur page actuelle avant de souscrire un abonnement.

Dois-je mettre à jour le port après chaque reconnexion ?

Oui, et cette mise à jour doit être automatique. Le port redirigé appartient à la session VPN. Un redémarrage du conteneur, un changement de serveur ou l’échec du renouvellement du bail peut donc produire un nouveau numéro, tandis que le client conserve l’ancien port dans sa propre configuration. Vous pouvez laisser gluetun le transmettre avec VPN_PORT_FORWARDING_UP_COMMAND, qui s’exécute dès que la redirection est établie. Vous pouvez aussi exécuter un processus léger qui lit GET /v1/portforward sur le serveur de contrôle et écrit la valeur dans le client via son API.

Comment vérifier que le port redirigé est réellement ouvert ?

Lancez un listener sur ce port précis dans le network namespace de gluetun, puis connectez-vous depuis l’extérieur du VPN. Arrêtez d’abord le client torrent pour libérer le port. Exécutez ensuite le binaire upstream port-checker dans le conteneur gluetun avec --listening-address=":<port>". Récupérez l’adresse de sortie avec curl -s http://127.0.0.1:8000/v1/publicip/ip, puis ouvrez http://<address>:<port> depuis un téléphone connecté au réseau mobile. L’apparition d’une requête dans le log du port-checker prouve que le trafic TCP entrant arrive bien. Un timeout signifie que ce n’est pas le cas, quel que soit l’état affiché par l’icône du client.

#gluetun#vpn#port-forwarding#docker#torrenting