SSD Nodes Learn Hosting plans →
Gidsen Matt ConnorDoor Matt Connor

Gluetun port forwarding instellen voor torrents

Werken uw torrents wel, maar krijgt u geen inkomende verbindingen? Leer hoe u Gluetun port forwarding configureert en het dynamische poortnummer automatisch doorgeeft aan uw client.

Waarom inkomende verbindingen zonder port forwarding falen

Gluetun port forwarding verzoekt uw VPN-provider om één publieke poort op het exit-adres door te sturen naar uw container. Dit is de enige manier waarop een andere peer een verbinding met uw torrent-client kan initiëren. Zonder deze koppeling is de tunnel in orde en werken downloads, maar komt er uit zichzelf niets binnen. Elke werkende verbinding is een verbinding die uw client zelf als eerste heeft geopend.

Het mechanisme hierachter is NAT (network address translation). Uw container deelt het exit-adres van de provider met vele andere klanten. Wanneer uw client een uitgaande verbinding opent, registreert de provider deze stroom en stuurt de antwoorden terug door uw tunnel. Een inkomende verbinding van een externe peer komt niet overeen met een geregistreerde stroom; het pakket bereikt het exit-adres en wordt daar verworpen. Uw client bereikt nog steeds elke peer die zelf wel bereikbaar is, waardoor downloads voltooien en het probleem onzichtbaar blijft. Bij het seeden wordt het probleem echter duidelijk, omdat een seeder een machine is waarmee anderen verbinding maken.

Een open inkomende poort verandert twee zaken. U sluit sneller aan bij een swarm, omdat peers die zelf geen verbindingen kunnen accepteren u nu kunnen bereiken, en u kunt daadwerkelijk uploaden naar die peers.

Waarom de meeste VPN-aanbieders geen port forwarding aanbieden

Een geforwarde poort is een schaars goed op een gedeeld IP-adres. De aanbieder reserveert één poortnummer op één exit-IP voor één klant en is vervolgens verantwoordelijk voor wat die klant ermee doet. Verschillende grote aanbieders hebben deze functie verwijderd en noemen misbruikafhandeling als reden. Beschouw ondersteuning als een categorische vraag in plaats van een checklist: vraag of de aanbieder vandaag de dag port forwarding aanbiedt, op uw abonnement, en op servers die u daadwerkelijk kunt selecteren.

Waar forwarding bestaat, is de poort dynamisch. Deze hoort bij de VPN-sessie en niet bij uw account, waardoor het nummer na elke herverbinding anders kan zijn. Private Internet Access geeft een ondertekende poort uit die gluetun ververst, en de upstream-documentatie stelt dat u dezelfde poort 60 dagen behoudt zolang u de map /gluetun bind-mount, zodat de status een herstart overleeft. ProtonVPN wijst een willekeurige poort toe via NAT-PMP (NAT port mapping protocol) met een korte lease die continu moet worden vernieuwd. Dit is de reden waarom het eenmalig instellen van de poort in de client nooit blijft werken.

Welke providers gluetun kunnen vragen om een poort

Sinds gluetun v3.41.3, uitgebracht op 30 juli 2026, valideert de native integratie vier providertitels: Private Internet Access, ProtonVPN, Perfect Privacy en PrivateVPN. Schakel dit in met VPN_PORT_FORWARDING=on, wat standaard off is. Oudere handleidingen gebruiken PORT_FORWARDING of PRIVATE_INTERNET_ACCESS_VPN_PORT_FORWARDING. Beide werken in deze versie nog als retro-compatibele namen, maar beide worden op termijn verwijderd.

Twee providerdetails bepalen of het verzoek überhaupt kan slagen. ProtonVPN vereist een betaald abonnement en NAT-PMP moet zijn ingeschakeld: activeer NAT-PMP (Port Forwarding) onder de VPN-opties bij het genereren van de WireGuard-configuratie, of voeg +pmp toe aan uw gebruikersnaam wanneer u OpenVPN gebruikt. Private Internet Access op OpenVPN heeft PORT_FORWARD_ONLY, wat de serverselectie beperkt tot servers die forwarding ondersteunen, zodat u niet op een server terechtkomt die dit nooit heeft gehad. WireGuard en OpenVPN verschillen in de manier waarop de poort wordt aangevraagd, dus lees de pagina van uw provider voordat u een keuze maakt.

Wanneer gluetun een aangepaste configuratie draait in plaats van een ingebouwde provider, benoemt VPN_PORT_FORWARDING_PROVIDER de API die gluetun moet aanroepen. De upstream-pagina van Private Internet Access koppelt die variabele aan VPN_PORT_FORWARDING_USERNAME en VPN_PORT_FORWARDING_PASSWORD, die de accountgegevens bevatten die nodig zijn voor het poortverzoek.

Port forwarding inschakelen voor gluetun in docker compose

Dit gaat ervan uit dat de tunnel al werkt. Als dit niet het geval is, begin dan met het routeren van Docker-containerverkeer via gluetun en keer terug zodra de downloads functioneren.

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

Zet de tag vast. qmcgaw/gluetun:latest volgt de master-branch, waar de interne werking van port forwarding voor v4 verandert; een niet-vastgezette image kan dus bij de volgende docker compose pull ander gedrag vertonen. Houd de private key buiten het compose-bestand met een env-bestand voor compose-geheimen.

Waar gluetun de doorgestuurde poort schrijft

Gluetun stelt de poort op drie plaatsen beschikbaar en op alle drie staat dezelfde waarde.

Het logt de poort eenmaal per verkrijging. De regel luidt port forwarded is 45678, en no port forwarded wanneer het verzoek niets opleverde.

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

Het schrijft het nummer naar het bestand dat wordt benoemd door VPN_PORT_FORWARDING_STATUS_FILE, wat standaard /tmp/gluetun/forwarded_port is. Het bestand bevat één poort per regel, wordt geschreven met modus 0644 en de eigenaar wordt gewijzigd naar de PUID en PGID van de container. Wanneer het doorsturen stopt, maakt gluetun het bestand leeg in plaats van het te verwijderen, zodat een consument een leeg bestand kan lezen in plaats van een foutmelding te krijgen bij een ontbrekend bestand.

docker exec gluetun cat /tmp/gluetun/forwarded_port

Het serveert de waarde op de control server, die standaard luistert op :8000 en wordt ingesteld door HTTP_CONTROL_SERVER_ADDRESS.

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

Gluetun opent die poort ook in zijn eigen firewall op de VPN-interface, dus FIREWALL_VPN_INPUT_PORTS is niet nodig wanneer de native integratie het werk doet. Die variabele dekt het andere geval: een provider die gluetun niet kan bevragen, waarbij u buiten het systeem om een statische poort hebt gekregen en deze handmatig moet toestaan.

Eén van deze drie is duurzaam en twee niet. De upstream-documentatie markeert het statusbestand als deprecated in v4.0.0, en GET /v1/openvpn/portforwarded antwoordt al met 301 Moved Permanently dat verwijst naar /v1/portforward. Nieuwe implementaties dienen de control server uit te lezen.

Waarom de client bij elke herverbinding op de hoogte moet worden gesteld van de poort

Een torrent-client slaat het luisterpoortnummer op in de eigen configuratie en behoudt dit nummer na een herstart. De geforwarde poort is echter een eigenschap van de VPN-sessie. Na een herverbinding komen de twee nummers niet meer overeen; de provider mapt dan een poort waarop niets luistert, terwijl de client luistert op een poort waarvoor geen mapping bestaat. Herverbindingen komen regelmatig voor: door een herstart van een container, een wijziging van server, een weggevallen tunnel die door de health check van gluetun wordt herstart, of een lease die niet kon worden vernieuwd. Het resultaat is een configuratie die gisteren bereikbaar was, maar vandaag stilletjes onbereikbaar is, zonder dat er foutmeldingen in de logs verschijnen.

De poort moet daarom worden toegepast op het moment dat gluetun deze verkrijgt. Er zijn twee manieren om dit in te richten, afhankelijk van welk proces de taak uitvoert.

Optie 1: gluetun pusht de poort met een up-commando

VPN_PORT_FORWARDING_UP_COMMAND wordt uitgevoerd wanneer port forwarding actief wordt en VPN_PORT_FORWARDING_DOWN_COMMAND wordt uitgevoerd wanneer deze wordt verbroken. Gluetun vervangt {{PORT}} (de eerste poort), {{PORTS}} (alle poorten, door komma's gescheiden) en {{VPN_INTERFACE}} (de naam van de tunnelinterface, standaard tun0) voordat het commando wordt uitgevoerd. Shell-syntaxis vereist een expliciete /bin/sh -c-wrapper. Dit is het upstream qBittorrent-voorbeeld, geschreven als twee compose-omgevingsvariabelen:

      - 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'

Elk veld in die aanroep heeft een functie. listen_port is de nieuwe poort. current_network_interface koppelt qBittorrent aan de tunnel. random_port ingesteld op false voorkomt dat qBittorrent bij de volgende start zelf een poort kiest. upnp ingesteld op false voorkomt dat het probeert een poort te mappen via een router die niet aanwezig is.

Aan deze aanpak zijn twee vereisten verbonden. De web-UI van qBittorrent moet zijn ingeschakeld en luisteren op poort 8080. Het delen van de netwerk-namespace van gluetun zorgt ervoor dat het kan antwoorden op 127.0.0.1:8080 vanuit de gluetun-container. En Bypass authentication for clients on localhost (bypass_local_auth) moet zijn ingeschakeld, omdat het commando geen inloggegevens meestuurt. Het down-commando is aanwezig omdat qBittorrent de poort niet altijd opnieuw instelt na een verbreking.

Het commando wordt uitgevoerd binnen de gluetun-container, die is gebouwd op Alpine en wget bevat. Er is geen curl in die image aanwezig. Een commando dat verwijst naar een binary die niet in de image staat, faalt elke keer wanneer forwarding actief wordt.

Optie 2: een proces buiten gluetun leest de poort

Het andere patroon draait een klein proces naast gluetun dat de poort ophaalt en deze via de eigen API van de client naar de client pusht. Lees deze uit vanaf de control server:

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

Of lees het bestand, als het proces dit kan inzien. /tmp/gluetun/forwarded_port bevindt zich in de gluetun-container, dus een sidecar heeft een gedeeld volume nodig dat is gemount op /tmp/gluetun in beide containers, of u wijst VPN_PORT_FORWARDING_STATUS_FILE naar een pad onder een volume dat u al mount.

Authenticatie is hier van belang. In v3.41.3 behoort de route GET /v1/portforward tot een standaardrol genaamd public met auth = "none", waardoor deze zonder inloggegevens antwoordt en gluetun een waarschuwing logt die begint met route GET /v1/portforward is unprotected by default, please set up authentication. Upstream sluit die deur in een latere release, en de huidige documentatie van de control server beschrijft elke route al als standaard privé. Definieer nu een rol in het bestand dat bind-gemount is op /gluetun/auth/config.toml:

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

Genereer een sleutel met docker run --rm qmcgaw/gluetun:v3.41.3 genkey en stuur deze mee in de X-API-Key header. HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE doet hetzelfde als één JSON-gecodeerde omgevingsvariabele wanneer u liever geen bestand mount. Zodra u een rol definieert, stopt v3.41.3 met het toepassen van de ingebouwde public rol, dus elke route die u daarna aanroept, heeft een rol nodig die deze vermeldt. Zonder enige rol dekt die ingebouwde public rol ook PUT /v1/vpn/status, dus poort 8000 die zonder auth-configuratie wordt gepubliceerd, geeft iedereen die deze kan bereiken controle over de VPN-status. Bepaal bewust hoe ver dit reikt wanneer u uitwerkt hoe u gluetun bereikt vanaf de host en andere containers.

Kies het up-commando wanneer de client een API blootstelt die met één wget aanroep kan worden aangestuurd, omdat dit precies één keer per gebeurtenis wordt uitgevoerd en niets toevoegt aan het draaiende proces. Kies een extern proces wanneer de client een inlogflow, een herschreven configuratiebestand of een herstart nodig heeft. In een arr stack achter één gluetun container eindigt dit meestal als één kleine poller, aangezien alleen de torrent-client om de poort geeft.

De valkuil: het delen van de namespace stelt de luisterpoort niet in

Deze fout kost de meeste tijd. network_mode: "service:gluetun" plaatst de client in de netwerk-namespace van gluetun, waardoor deze beschikt over het VPN-adres, de tunnelroutes en de firewallregels van gluetun. Niets hiervan stelt de luisterpoort van de client in. Gluetun opent de doorgestuurde poort op de VPN-interface, pakketten hiervoor komen aan in de namespace, en als de client op een andere poort luistert, heeft de kernel niets om ze aan af te leveren. De verbinding wordt geweigerd of loopt vast, terwijl elke uitgaande controle er gezond uitziet. De doorgestuurde poort en de luisterpoort van de client zijn twee afzonderlijke getallen, en het gelijk houden ervan is de volledige taak.

Vergelijk ze in plaats van te gokken. Beide commando's worden uitgevoerd in dezelfde 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]*'

Nog één instelling stuurt mensen in de verkeerde richting. VPN_PORT_FORWARDING_LISTENING_PORT leidt inkomend verkeer van de doorgestuurde poort om naar een vaste lokale poort met behulp van iptables. De upstream-documentatie adviseert dit niet te gebruiken met torrent-clients, omdat de client zijn eigen luisterpoort aankondigt aan trackers en peers, waardoor het swarm-netwerk het verkeerde nummer leert.

Hoe u controleert of de doorgestuurde poort bereikbaar is

De verbindingsindicator van de client zelf geeft uitgaande tracker-verbindingen weer; deze kan dus groen zijn terwijl u vanaf de buitenkant onbereikbaar bent. Test dit met een listener die u beheert, vanaf een netwerk buiten de tunnel. De upstream-partij stelt hiervoor een kleine tool beschikbaar. Stop eerst de torrent-client, aangezien twee processen niet tegelijkertijd aan dezelfde poort kunnen binden.

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

Wijzig in de container amd64 naar uw CPU-architectuur en 4567 naar uw doorgestuurde poort:

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"

Zoek nu het exit-adres dat gluetun gebruikt. Het antwoord is JSON en het adres staat in het veld public_ip.

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

Dat eenvoudige verzoek werkt alleen zolang v3.41.3 draait zonder auth-configuratie. Als u rollen heeft gedefinieerd zoals in Optie 2, voeg dan GET /v1/publicip/ip toe aan de routes van een rol en stuur de sleutel van die rol mee, bijvoorbeeld curl -s -H "X-API-Key: myapikey" http://127.0.0.1:8000/v1/publicip/ip.

Open http://<that address>:4567 vanaf een apparaat dat zich niet op hetzelfde VPN bevindt. Een telefoon op mobiele data werkt prima. Een pagina die het IP-adres en de user agent van uw browser toont, waarbij een overeenkomstig verzoek wordt gelogd door port-checker, betekent dat inkomend TCP de namespace bereikt. Een timeout betekent dat dit niet het geval is; de oorzaak ligt dan buiten de client. Stop de tool met CTRL+C, verlaat de shell met exit en start de client opnieuw. Deze controle test uitsluitend TCP. DHT (distributed hash table) en uTP-verkeer gebruiken UDP op hetzelfde poortnummer, wat met deze test niet wordt gedekt.

Foutmodi en de meldingen die u zult zien

Geen poortregel in het logbestand. Er is nergens om een poort gevraagd. Controleer of de variabele de container daadwerkelijk heeft bereikt met docker exec gluetun printenv | grep PORT_FORWARDING, aangezien een variabele die in de verkeerde compose-service is ingesteld een veelvoorkomende oorzaak is.

Gluetun weigert te starten en klaagt over de provider. VPN_PORT_FORWARDING_PROVIDER wordt gevalideerd aan de hand van de vier ondersteunde namen; een typefout zorgt er dus voor dat de container stopt in plaats van dat deze stilzwijgend draait zonder doorsturing.

Het logbestand vermeldt no port forwarded. Gluetun heeft een verzoek gedaan, maar de provider gaf geen antwoord. Bij ProtonVPN betekent dit meestal dat NAT-PMP niet was ingeschakeld in de configuratie die u heeft gegenereerd, of dat het abonnement geen port forwarding ondersteunt. Bij Private Internet Access betekent dit meestal dat de geselecteerde server dit niet aanbiedt.

Er komt een poort binnen, maar er is geen verbinding mogelijk. Vergelijk de doorgestuurde poort met de luisterpoort van de client met behulp van de twee bovenstaande commando's. Als deze overeenkomen, controleer dan of de client is gebonden aan de tunnelinterface en of de optie voor willekeurige poorten (random-port) is uitgeschakeld, omdat die optie de luisterpoort bij elke start herschrijft.

Het up-commando lijkt niets te doen. Voer het exacte commando uit in de container om de foutmelding te zien: docker exec gluetun /bin/sh -c '<your command>'. curl: not found is het gebruikelijke resultaat, omdat de image alleen wget bevat.

401 Unauthorized van de control server. U heeft een auth-configuratie gedefinieerd en de rol bevat niet de route die u aanroept. Routes worden gematcht op basis van methode plus pad, dus een rol die alleen /v1/portforward vermeldt, dekt GET /v1/portforward niet.

Een andere poort bij Private Internet Access na elke herstart. Gebruik een bind mount voor /gluetun zodat de opgeslagen poortstatus behouden blijft na een herstart. Zonder dat volume vraagt gluetun elke keer een nieuwe poort aan.

FAQ

Waarom downloaden mijn torrents wel, maar krijg ik geen inkomende verbindingen?

Zonder een doorgeschakelde poort heeft de VPN-provider geen NAT-regel die inkomende pakketten op een willekeurige poort naar uw tunnel stuurt. Hierdoor worden verbindingen die u niet zelf bent gestart, bij het exit-adres geweigerd. Downloads werken nog wel omdat uw client deze verbindingen zelf opent en elke peer kan bereiken die wel bereikbaar is. Seeden en deelname aan de swarm lijden hieronder, aangezien beide afhankelijk zijn van het feit dat anderen u kunnen bereiken. De oplossing is een provider die port forwarding aanbiedt, VPN_PORT_FORWARDING=on in gluetun, en de resulterende poort toe te passen op de luisterpoort van de client.

Werkt gluetun met de port forwarding van elke VPN-provider?

Nee. Gluetun v3.41.3 heeft native integratie voor vier providers: Private Internet Access, ProtonVPN, Perfect Privacy en PrivateVPN. Alles buiten die lijst faalt bij de validatie voor VPN_PORT_FORWARDING_PROVIDER, en de container stopt bij het opstarten. Als uw provider een statische poort uitgeeft via het eigen configuratiescherm, kan gluetun deze niet voor u aanvragen, maar FIREWALL_VPN_INPUT_PORTS staat die vaste poort toe via de firewall van gluetun. Het beleid van providers verandert, dus controleer de huidige providerpagina voordat u een abonnement hiervoor aanschaft.

Moet ik de poort na elke herverbinding bijwerken?

Ja, en die update hoort automatisch te verlopen. De doorgeschakelde poort hoort bij de VPN-sessie. Een herstart van de container, een serverwissel of een mislukte leaseverlenging kan een nieuw nummer opleveren, terwijl de client de poort in de eigen configuratie bewaart. Laat gluetun dit pushen met VPN_PORT_FORWARDING_UP_COMMAND, dat wordt uitgevoerd zodra de forwarding actief is, of draai een klein proces dat GET /v1/portforward leest van de control server en de waarde via de API in de client schrijft.

Hoe controleer ik of de doorgeschakelde poort echt open staat?

Start een listener op die specifieke poort binnen de netwerk-namespace van gluetun en maak vanaf buiten de VPN verbinding. Stop eerst de torrent-client zodat de poort vrij is, en voer daarna het upstream port-checker binary uit binnen de gluetun-container met --listening-address=":<port>". Haal het exit-adres op via curl -s http://127.0.0.1:8000/v1/publicip/ip, voeg -H "X-API-Key: <key>" toe voor een rol die GET /v1/publicip/ip vermeldt als u authenticatie voor de control server heeft ingesteld, en open http://<address>:<port> vanaf een telefoon via mobiele data. Een verzoek dat verschijnt in het logboek van de port-checker bewijst dat inkomend TCP aankomt. Een time-out betekent dat dit niet het geval is, ongeacht wat het statusicoon van de client zelf aangeeft.

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