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-stoppedZet 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_portHet 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 wegvalt. Gluetun vervangt {{PORT}} (de eerste poort), {{PORTS}} (alle poorten, gescheiden door komma's) 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 bindt 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 reageren op 127.0.0.1:8080 vanuit de gluetun-container, wat automatisch gebeurt wanneer de client de netwerk-namespace van gluetun deelt. 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 van de verbinding.
Het commando wordt uitgevoerd in de gluetun-container, die is gebaseerd 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, zal elke keer falen zodra forwarding actief wordt.
Optie 2: een proces buiten gluetun leest de poort
Het andere patroon voert een klein proces uit 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, indien 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 antwoordt zonder inloggegevens, en gluetun logt een waarschuwing die begint met route GET /v1/portforward is unprotected by default, please set up authentication. Upstream sluit die deur in een latere release. 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 een JSON-gecodeerde omgevingsvariabele wanneer u liever geen bestand mount. Poort 8000 die zonder rol wordt gepubliceerd, geeft iedereen die deze kan bereiken controle over de VPN-status, dus bepaal bewust hoe ver deze toegang 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 door één wget-aanroep kan worden aangestuurd, omdat dit precies één keer per gebeurtenis wordt uitgevoerd en niets toevoegt om draaiende te houden. Kies een extern proces wanneer de client een inlogprocedure, het herschrijven van een configuratiebestand of een herstart vereist. In een arr stack achter één gluetun container eindigt dit meestal als één kleine poller, aangezien alleen de torrent-client de poort nodig heeft.
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 lijken terwijl niemand u kan bereiken. Test dit met een listener die u beheert, vanaf een netwerk buiten de tunnel. Upstream publiceert hiervoor een kleine tool. Stop eerst de torrent-client, omdat twee processen niet aan dezelfde poort kunnen binden.
docker stop qbittorrent
docker exec -it gluetun /bin/shWijzig 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/ipOpen http://<that address>:4567 vanaf een apparaat dat niet met dezelfde VPN is verbonden. Een telefoon op mobiele data werkt prima. Een pagina die het IP-adres en de user agent van uw browser toont, waarbij een overeenkomstige aanvraag wordt gelogd door port-checker, betekent dat inkomend TCP de namespace bereikt. Een time-out betekent dat dit niet het geval is en de oorzaak ligt boven de client. Stop de tool met CTRL+C, verlaat de shell met exit en start de client opnieuw. Deze controle test alleen TCP. DHT (distributed hash table) en uTP-verkeer gebruiken UDP op hetzelfde poortnummer, wat deze test niet dekt.
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 nooit inkomende verbindingen?
Zonder een geforwarde poort heeft de VPN-provider geen NAT-regel die inkomende pakketten op een poort naar uw tunnel stuurt. Verbindingen die u niet zelf bent gestart, worden daarom bij het exit-adres geweigerd. Downloads werken wel omdat uw client deze verbindingen zelf opent en elke peer kan bereiken die wel bereikbaar is. Seeden en het deelnemen aan de swarm lijden hieronder, aangezien beide afhankelijk zijn van anderen die u kunnen bereiken. De oplossing is een provider die port forwarding aanbiedt, VPN_PORT_FORWARDING=on in gluetun, en de resulterende poort toepassen op de listening-poort 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 door de firewall van gluetun. Providerbeleid wijzigt, dus controleer de actuele providerpagina voordat u een abonnement aanschaft voor dit doel.
Moet ik de poort na elke herverbinding bijwerken?
Ja, en die update hoort automatisch te verlopen. De geforwarde 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 oude poort in de eigen configuratie bewaart. Laat gluetun dit pushen met VPN_PORT_FORWARDING_UP_COMMAND, wat 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 geforwarde poort echt open staat?
Draai een listener op die specifieke poort binnen de netwerk-namespace van gluetun en maak verbinding vanaf buiten de VPN. Stop eerst de torrent-client zodat de poort vrij is, en draai daarna het upstream port-checker-binary in de gluetun-container met --listening-address=":<port>". Haal het exit-adres op via curl -s http://127.0.0.1:8000/v1/publicip/ip en open http://<address>:<port> vanaf een telefoon op mobiele data. Een verzoek dat verschijnt in de log van de port-checker bewijst dat inkomend TCP aankomt. Een timeout betekent dat dit niet het geval is, ongeacht wat het statusicoon van de client zelf aangeeft.