SSD Nodes Learn 🎉 VPS da $5.50/mese
Guide Matt ConnorDi Matt Connor

Port forwarding Gluetun per client torrent

I download funzionano ma non ricevi connessioni? Configura il port forwarding di Gluetun, aggiorna la porta nel client a ogni riconnessione e verifica il risultato.

Perché nulla si connette in ingresso senza una porta inoltrata

Il port forwarding di Gluetun chiede al provider VPN di associare una porta pubblica sull'indirizzo di uscita del provider al container. È l'unico modo che consente a un altro peer di avviare una connessione verso il client torrent. Senza questa associazione, il tunnel è operativo e i download funzionano, ma non arriva mai nulla spontaneamente. Ogni connessione funzionante è stata avviata dal client.

Il meccanismo coinvolto è il NAT (network address translation). Il container condivide l'indirizzo di uscita del provider con molti altri clienti. Quando il client apre una connessione verso l'esterno, il provider registra il flusso e invia le risposte attraverso il tunnel. La connessione in ingresso avviata dal peer di un altro utente non corrisponde ad alcun flusso registrato. Il pacchetto raggiunge quindi l'indirizzo di uscita e viene scartato. Il client continua a raggiungere tutti i peer che sono a loro volta raggiungibili. Per questo i download terminano e il problema può non essere evidente. Il problema emerge durante il seeding, perché un seeder è un computer al quale si connettono altri utenti.

Una porta aperta in ingresso cambia due aspetti. Il client entra più rapidamente nello swarm, perché i peer che non possono accettare connessioni possono ora raggiungerlo. Inoltre, il client può caricare dati verso quei peer.

Perché la maggior parte dei provider VPN non offre il port forwarding

Una porta inoltrata è una risorsa limitata su un indirizzo condiviso. Il provider riserva un numero di porta su un indirizzo IP di uscita per un cliente e risponde delle operazioni che il cliente esegue tramite quella porta. Diversi provider di grandi dimensioni hanno rimosso questa funzione, indicando la gestione degli abusi come motivazione. Considerate il supporto come una domanda specifica, non come una semplice casella da selezionare: chiedete se il provider offre oggi il port forwarding, se è disponibile nel vostro piano e se è attivo sui server che potete effettivamente selezionare.

Quando il forwarding è disponibile, la porta è dinamica. È associata alla sessione VPN e non al vostro account, quindi può cambiare dopo ogni riconnessione. Private Internet Access assegna una porta firmata che gluetun aggiorna; la documentazione upstream specifica che la stessa porta resta disponibile per 60 giorni, a condizione di eseguire il bind mount della directory /gluetun, in modo che lo stato venga mantenuto dopo un riavvio. ProtonVPN assegna una porta casuale tramite NAT-PMP (NAT port mapping protocol), con un lease di breve durata che deve essere rinnovato continuamente. Per questo motivo, impostare la porta una sola volta nel client non è sufficiente.

Quali provider può interrogare gluetun per richiedere una porta

A partire da gluetun v3.41.3, rilasciato il 30 July 2026, l'integrazione nativa verifica quattro nomi di provider: Private Internet Access, ProtonVPN, Perfect Privacy e PrivateVPN. Attivatela con VPN_PORT_FORWARDING=on, che per impostazione predefinita è off. Le guide meno recenti usano PORT_FORWARDING o PRIVATE_INTERNET_ACCESS_VPN_PORT_FORWARDING. In questa versione funzionano ancora entrambi come nomi retrocompatibili, ma verranno rimossi.

Due dettagli del provider determinano se la richiesta può avere esito positivo. ProtonVPN richiede un piano a pagamento e NAT-PMP deve essere attivato: abilitate NAT-PMP (Port Forwarding) nelle opzioni VPN quando generate la configurazione WireGuard, oppure aggiungete +pmp al nome utente quando usate OpenVPN. In Private Internet Access con OpenVPN è disponibile PORT_FORWARD_ONLY, che limita la selezione dei server a quelli che supportano il port forwarding. In questo modo non vi connettete a un server che non lo ha mai supportato. WireGuard e OpenVPN differiscono nel modo in cui viene richiesta la porta, quindi consultate la pagina del provider prima di scegliere.

Quando gluetun usa una configurazione personalizzata invece di un provider integrato, VPN_PORT_FORWARDING_PROVIDER indica l'API che gluetun deve chiamare. La pagina upstream di Private Internet Access associa questa variabile a VPN_PORT_FORWARDING_USERNAME e VPN_PORT_FORWARDING_PASSWORD, che contengono le credenziali dell'account necessarie per la richiesta della porta.

Attivare il port forwarding di gluetun in docker compose

Questa procedura presuppone che il tunnel sia già operativo. In caso contrario, iniziare da instradare il traffico dei container Docker attraverso gluetun e tornare qui quando i download funzionano.

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

Fissare il tag. qmcgaw/gluetun:latest segue il branch master, nel quale le funzionalità interne del port forwarding stanno cambiando in vista della versione v4; un'immagine senza tag fissato può quindi cambiare comportamento al successivo docker compose pull. Tenere la chiave privata fuori dal file compose usando un file env per i secret di compose.

Dove gluetun scrive la porta inoltrata

Gluetun espone la porta in tre punti, che riportano tutti lo stesso valore.

La registra nei log una volta per ogni acquisizione. La riga contiene port forwarded is 45678 oppure no port forwarded quando la richiesta non restituisce alcun valore.

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

Scrive il numero nel file indicato da VPN_PORT_FORWARDING_STATUS_FILE, che per impostazione predefinita è /tmp/gluetun/forwarded_port. Il file contiene una porta per riga, viene scritto con la modalità 0644 e riceve come proprietari il PUID e il PGID del container. Quando l'inoltro si interrompe, gluetun svuota il file invece di eliminarlo. Un consumer può quindi leggere un file vuoto anziché ricevere un errore perché il file non esiste.

docker exec gluetun cat /tmp/gluetun/forwarded_port

Espone il valore sul control server, che per impostazione predefinita è in ascolto su :8000 ed è configurato tramite HTTP_CONTROL_SERVER_ADDRESS.

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

Gluetun apre inoltre quella porta nel proprio firewall sull'interfaccia VPN. Per questo, FIREWALL_VPN_INPUT_PORTS non è necessario quando l'integrazione nativa svolge questa funzione. Questa variabile serve nell'altro caso: quando gluetun non può interrogare un provider che assegna una porta statica fuori banda e occorre consentirla manualmente.

Uno dei tre metodi è persistente, mentre gli altri due non lo sono. La documentazione upstream indica il file di stato come deprecato in v4.0.0, e GET /v1/openvpn/portforwarded risponde già con 301 Moved Permanently indicando /v1/portforward. Per le nuove implementazioni è consigliabile leggere il control server.

Perché il client deve ricevere la porta a ogni riconnessione

Un client torrent memorizza la porta su cui è in ascolto nella propria configurazione e mantiene quel numero anche dopo i riavvii. La porta inoltrata è una proprietà della sessione VPN. Dopo una riconnessione, i due numeri non coincidono: il provider associa quindi una porta su cui non è in ascolto alcun servizio, mentre il client utilizza una porta che il provider non inoltra. Le riconnessioni non sono rare: possono essere causate dal riavvio di un container, da una modifica del server, da una disconnessione del tunnel che il controllo di integrità di gluetun riavvia oppure dal mancato rinnovo di un lease. Il risultato è una configurazione che ieri era raggiungibile e oggi non lo è più, senza errori nei log.

La porta deve quindi essere applicata nel momento in cui gluetun la acquisisce. Esistono due modalità per configurare questo comportamento, che differiscono per il processo incaricato di eseguire l'operazione.

Opzione 1: gluetun comunica la porta con un comando up

VPN_PORT_FORWARDING_UP_COMMAND viene eseguito quando il port forwarding diventa disponibile, mentre VPN_PORT_FORWARDING_DOWN_COMMAND viene eseguito quando viene disattivato. Prima di eseguire il comando, Gluetun sostituisce {{PORT}} (la prima porta), {{PORTS}} (tutte le porte, separate da virgole) e {{VPN_INTERFACE}} (il nome dell'interfaccia del tunnel, tun0 per impostazione predefinita). La sintassi della shell richiede un wrapper /bin/sh -c esplicito. Questo è l'esempio upstream per qBittorrent, scritto come due voci di ambiente di 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'

Ogni campo di questa chiamata ha una funzione. listen_port è la nuova porta. current_network_interface associa qBittorrent al tunnel. Impostare random_port su false impedisce a qBittorrent di scegliere una porta propria al successivo avvio. Impostare upnp su false impedisce a qBittorrent di tentare il port mapping tramite un router che non è presente.

Questo approccio richiede due condizioni. L'interfaccia web di qBittorrent deve rispondere su 127.0.0.1:8080 dall'interno del container gluetun. Ciò avviene automaticamente quando il client condivide il namespace di rete di gluetun. Deve inoltre essere abilitato Bypass authentication for clients on localhost (bypass_local_auth), perché il comando non invia credenziali. Il comando down è necessario perché qBittorrent non ristabilisce sempre la porta dopo una disconnessione.

Il comando viene eseguito all'interno del container gluetun, basato su Alpine e dotato di wget. Nell'immagine non è presente curl. Un comando che richiama un binario assente nell'immagine fallisce ogni volta che il port forwarding viene attivato.

Opzione 2: un processo esterno a gluetun legge la porta

L’altro modello prevede un piccolo processo accanto a gluetun. Il processo recupera la porta e la invia al client tramite la relativa API. Leggila dal server di controllo:

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

Oppure leggi il file, se il processo può accedervi. /tmp/gluetun/forwarded_port si trova all’interno del container gluetun. Un sidecar deve quindi usare un volume condiviso montato in /tmp/gluetun in entrambi i container. In alternativa, puoi impostare VPN_PORT_FORWARDING_STATUS_FILE su un percorso appartenente a un volume già montato.

L’autenticazione è importante. In v3.41.3, la route GET /v1/portforward appartiene a un ruolo predefinito chiamato public con auth = "none". Per questo risponde senza credenziali e gluetun registra un avviso che inizia con route GET /v1/portforward is unprotected by default, please set up authentication. Upstream eliminerà questa possibilità in una release successiva. Definisci subito un ruolo nel file montato tramite bind mount in /gluetun/auth/config.toml:

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

Genera una chiave con docker run --rm qmcgaw/gluetun:v3.41.3 genkey e inviala nell’header X-API-Key. HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE svolge la stessa funzione di una variabile d’ambiente codificata in JSON quando preferisci non montare un file. Pubblicare la porta 8000 senza un ruolo consente a chiunque possa raggiungerla di controllare lo stato della VPN. Perciò, quando stabilisci come raggiungere gluetun dall’host e dagli altri container, decidi consapevolmente fin dove esporla.

Scegli il comando up quando il client espone un’API che può essere gestita con una sola chiamata wget. Viene eseguito esattamente una volta per evento e non richiede un processo persistente. Scegli invece un processo esterno quando il client richiede un flusso di accesso, la riscrittura di un file di configurazione o un riavvio. In uno stack arr dietro un unico container gluetun, di solito è sufficiente un piccolo processo di polling, perché solo il client torrent utilizza la porta.

La trappola: condividere lo spazio dei nomi non imposta la porta di ascolto

Questo errore fa perdere più tempo di qualsiasi altro. network_mode: "service:gluetun" inserisce il client nello spazio dei nomi di rete di gluetun, quindi il client usa l'indirizzo IP della VPN, le route del tunnel e le regole firewall di gluetun. Nessuno di questi elementi imposta la porta di ascolto del client. Gluetun apre la porta inoltrata sull'interfaccia VPN, i pacchetti destinati a quella porta arrivano nello spazio dei nomi e, se il client è in ascolto su una porta diversa, il kernel non ha alcun processo a cui consegnarli. La connessione viene rifiutata oppure va in timeout, mentre tutti i controlli sul traffico in uscita risultano corretti. La porta inoltrata e la porta di ascolto del client sono due numeri distinti; il compito consiste nel mantenerli uguali.

Confrontale invece di procedere per tentativi. Entrambi i comandi vengono eseguiti nello stesso spazio dei nomi:

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'altra impostazione porta spesso nella direzione sbagliata. VPN_PORT_FORWARDING_LISTENING_PORT reindirizza il traffico in ingresso dalla porta inoltrata a una porta locale fissa usando iptables. La documentazione upstream sconsiglia di usarla con i client torrent, perché il client comunica ai tracker e ai peer la propria porta di ascolto e quindi la swarm apprende il numero errato.

Come dimostrare che la porta inoltrata è raggiungibile

L'indicatore di connessione del client riflette le connessioni in uscita ai tracker. Può quindi risultare verde anche quando nessuna connessione in ingresso può raggiungerti. Esegui il test con un listener sotto il tuo controllo, da una rete esterna al tunnel. Upstream mette a disposizione un piccolo strumento per questo scopo. Arresta prima il client torrent, perché due processi non possono associarsi alla stessa porta.

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

All'interno del container, sostituisci amd64 con l'architettura della tua CPU e 4567 con la porta inoltrata:

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"

Ora individua l'indirizzo di uscita utilizzato da gluetun. La risposta è in formato JSON e l'indirizzo si trova nel campo public_ip.

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

Apri http://<that address>:4567 da un dispositivo che non si trova sulla stessa VPN. Va bene anche un telefono con la rete dati attiva. Una pagina che mostra l'indirizzo IP e lo user agent del browser, insieme a una richiesta corrispondente registrata da port-checker, indica che il traffico TCP in ingresso raggiunge il namespace. Un timeout indica che non lo raggiunge e che la causa si trova a un livello superiore rispetto al client. Arresta lo strumento con CTRL+C, esci dalla shell con exit e avvia nuovamente il client. Questo controllo verifica solo TCP. Il traffico DHT (distributed hash table) e uTP usa UDP sullo stesso numero di porta, ma questo test non lo verifica.

Modalità di errore e stringhe visualizzate

Nel log non compare alcuna riga relativa alla porta. Nessun componente ha richiesto una porta. Verifica con docker exec gluetun printenv | grep PORT_FORWARDING che la variabile sia effettivamente arrivata nel container, perché definire una variabile nel servizio Compose errato è una causa comune.

Gluetun non si avvia e segnala un problema con il provider. VPN_PORT_FORWARDING_PROVIDER viene validata rispetto ai quattro nomi supportati. Un errore di battitura arresta quindi il container, invece di eseguirlo senza inoltro.

Il log contiene no port forwarded. Gluetun ha inviato la richiesta, ma il provider non ha restituito alcun valore. Su ProtonVPN, questo significa di solito che NAT-PMP non era abilitato nella configurazione generata oppure che il piano non include il port forwarding. Su Private Internet Access, di solito significa che il server selezionato non lo supporta.

La porta viene assegnata, ma nessuna connessione riesce a raggiungere il servizio. Confronta la porta inoltrata con la porta in ascolto del client usando i due comandi precedenti. Se coincidono, verifica che il client sia associato all'interfaccia del tunnel e che l'opzione per la porta casuale sia disabilitata, perché questa opzione riscrive la porta in ascolto a ogni avvio.

Il comando up sembra non fare nulla. Esegui il comando esatto all'interno del container per visualizzare l'errore: docker exec gluetun /bin/sh -c '<your command>'. curl: not found è il risultato più comune, perché l'immagine include soltanto wget.

401 Unauthorized dal control server. Hai definito una configurazione di autenticazione, ma il ruolo non elenca la route che stai chiamando. Le route vengono confrontate come combinazione di metodo e percorso, quindi un ruolo che elenca soltanto /v1/portforward non copre GET /v1/portforward.

Una porta diversa su Private Internet Access dopo ogni riavvio. Crea un bind mount per /gluetun, in modo che lo stato della porta salvata sopravviva al riavvio. Senza quel volume, gluetun richiede una nuova porta a ogni avvio.

FAQ

Perché i torrent vengono scaricati, ma non ricevono mai connessioni in ingresso?

Senza una porta inoltrata, il provider VPN non dispone di una regola NAT che invii i pacchetti in ingresso su una porta al tunnel. Le connessioni non avviate dal client vengono quindi scartate sull'indirizzo di uscita. I download continuano a funzionare perché il client apre autonomamente queste connessioni e può raggiungere qualsiasi peer connettibile. Il seeding e l'ingresso nei gruppi di peer ne risentono, perché dipendono entrambi dalla possibilità che altri peer raggiungano il client. La soluzione consiste nell'utilizzare un provider che offra il port forwarding, configurare VPN_PORT_FORWARDING=on in gluetun e impostare la porta risultante come porta di ascolto del client.

gluetun funziona con il port forwarding di qualsiasi provider VPN?

No. gluetun v3.41.3 dispone dell'integrazione nativa per quattro provider: Private Internet Access, ProtonVPN, Perfect Privacy e PrivateVPN. Qualsiasi provider non incluso nell'elenco non supera la validazione di VPN_PORT_FORWARDING_PROVIDER e il container si arresta all'avvio. Se il provider assegna una porta statica tramite il proprio pannello di controllo, gluetun non può richiederla per conto del client, ma FIREWALL_VPN_INPUT_PORTS consente di autorizzare quella porta fissa attraverso il firewall di gluetun. Le policy dei provider cambiano; verificare quindi la pagina aggiornata del provider prima di acquistare un piano per questo scopo.

Devo aggiornare la porta dopo ogni riconnessione?

Sì. L'aggiornamento dovrebbe essere automatico. La porta inoltrata appartiene alla sessione VPN. Un riavvio del container, un cambio di server o il mancato rinnovo del lease possono quindi produrre un nuovo numero, mentre il client continua a utilizzare la porta memorizzata nella propria configurazione. È possibile lasciare che gluetun la trasferisca tramite VPN_PORT_FORWARDING_UP_COMMAND, che viene eseguito non appena il port forwarding diventa attivo, oppure eseguire un processo semplice che legge GET /v1/portforward dal control server e scrive il valore nel client tramite la relativa API.

Come posso verificare che la porta inoltrata sia realmente aperta?

Eseguire un listener sulla porta esatta all'interno del network namespace di gluetun e collegarsi a tale listener dall'esterno della VPN. Arrestare prima il client torrent per liberare la porta, quindi eseguire il port-checker binary upstream all'interno del container gluetun con --listening-address=":<port>". Ottenere l'indirizzo di uscita da curl -s http://127.0.0.1:8000/v1/publicip/ip e aprire http://<address>:<port> da un telefono connesso alla rete mobile. La comparsa di una richiesta nel log del port-checker dimostra che il traffico TCP in ingresso raggiunge il container. Un timeout indica che il traffico non arriva, indipendentemente dall'icona di stato mostrata dal client.

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