SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor

Gluetun: configurar port forwarding para torrents

Downloads funcionam, mas ninguém conecta? Configure o port forwarding do Gluetun, atualize a porta no cliente a cada reconexão e confirme o acesso.

Por que nada consegue estabelecer ligação sem uma porta encaminhada

O encaminhamento de portas do Gluetun pede ao fornecedor de VPN que associe uma porta pública no endereço de saída do fornecedor ao seu contentor. Esta é a única forma de outro peer iniciar uma ligação ao seu cliente de torrents. Sem esse mapeamento, o túnel funciona, os downloads decorrem e nada chega espontaneamente. Todas as ligações funcionais são iniciadas primeiro pelo seu cliente.

O mecanismo é o NAT (tradução de endereços de rede). O seu contentor partilha o endereço de saída do fornecedor com muitos outros clientes. Quando o seu cliente inicia uma ligação para o exterior, o fornecedor regista esse fluxo e envia as respostas de volta pelo túnel. Uma ligação recebida de um peer desconhecido não corresponde a nenhum fluxo registado. Por isso, o pacote chega ao endereço de saída e é descartado nesse ponto. O seu cliente continua a conseguir ligar-se a todos os peers que aceitam ligações, pelo que os downloads terminam e o problema pode passar despercebido. É durante o seeding que o problema se manifesta, porque um seeder é uma máquina à qual outras pessoas se ligam.

Uma porta de entrada aberta altera duas coisas. Entra mais rapidamente num swarm, porque os peers que não conseguem aceitar ligações também passam a conseguir ligar-se a si. Além disso, pode fazer upload para esses peers.

Por que a maioria dos provedores de VPN não oferece encaminhamento de portas

Uma porta encaminhada é um recurso escasso num endereço partilhado. O provedor reserva um número de porta num IP de saída para um cliente e passa a responder pelo que esse cliente fizer através dela. Vários provedores de grande dimensão removeram esse recurso e apontaram o tratamento de abusos como motivo. Considere o suporte como uma questão de categoria, não como uma caixa de seleção: pergunte se o provedor oferece encaminhamento de portas atualmente, no seu plano e nos servidores que pode realmente selecionar.

Quando existe encaminhamento, a porta é dinâmica. Ela pertence à sessão VPN, não à sua conta, e pode ter um número diferente depois de cada reconexão. A Private Internet Access fornece uma porta assinada que o gluetun atualiza, e a documentação upstream informa que a mesma porta é mantida durante 60 dias, desde que faça bind mount do diretório /gluetun para que o estado sobreviva a um reinício. A ProtonVPN atribui uma porta aleatória através de NAT-PMP (protocolo de mapeamento de portas NAT), com um lease curto que tem de ser renovado continuamente. Por isso, definir a porta uma única vez no cliente nunca funciona de forma permanente.

Quais provedores o gluetun pode consultar para obter uma porta

A partir do gluetun v3.41.3, lançado em 30 July 2026, a integração nativa valida quatro nomes de provedores: Private Internet Access, ProtonVPN, Perfect Privacy e PrivateVPN. Ative-a com VPN_PORT_FORWARDING=on, que é off por predefinição. Guias mais antigos usam PORT_FORWARDING ou PRIVATE_INTERNET_ACCESS_VPN_PORT_FORWARDING. Ambos continuam a funcionar nesta versão como nomes compatíveis com versões anteriores e ambos estão a ser descontinuados.

Dois detalhes do provedor determinam se o pedido pode ser concluído. O ProtonVPN requer um plano pago, e o NAT-PMP tem de estar ativado: ative NAT-PMP (Port Forwarding) nas opções da VPN quando gerar a configuração do WireGuard ou acrescente +pmp ao seu nome de utilizador quando usar OpenVPN. No OpenVPN, o Private Internet Access tem PORT_FORWARD_ONLY, que restringe a seleção de servidores aos servidores que suportam o encaminhamento, para que não fique ligado a um servidor que nunca o suportou. WireGuard e OpenVPN diferem na forma como a porta é solicitada, por isso consulte a página do seu provedor antes de escolher.

Quando o gluetun usa uma configuração personalizada em vez de um provedor integrado, VPN_PORT_FORWARDING_PROVIDER identifica a API que o gluetun deve chamar. A página upstream do Private Internet Access associa essa variável a VPN_PORT_FORWARDING_USERNAME e VPN_PORT_FORWARDING_PASSWORD, que transportam as credenciais da conta necessárias para o pedido da porta.

Ative o encaminhamento de portas do gluetun no docker compose

Isto pressupõe que o túnel já funciona. Se não funcionar, comece por encaminhar o tráfego dos contentores Docker através do gluetun e volte quando os downloads estiverem a funcionar.

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

Fixe a tag. qmcgaw/gluetun:latest acompanha o branch master, onde os componentes internos do encaminhamento de portas estão a sofrer alterações para a v4. Uma imagem sem tag fixa pode alterar o comportamento na próxima docker compose pull. Mantenha a chave privada fora do ficheiro compose com um ficheiro de ambiente para segredos do compose.

Onde o gluetun escreve a porta encaminhada

O Gluetun expõe a porta em três locais, e todos contêm o mesmo valor.

Ele regista a porta uma vez por aquisição. A linha é port forwarded is 45678, e no port forwarded quando o pedido não produz nenhum valor.

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

Ele escreve o número no ficheiro indicado por VPN_PORT_FORWARDING_STATUS_FILE, que por predefinição é /tmp/gluetun/forwarded_port. O ficheiro contém uma porta por linha, é escrito com o modo 0644 e recebe como proprietário o PUID e o PGID do contentor. Quando o encaminhamento para, o gluetun limpa o ficheiro em vez de o apagar, para que um consumidor possa ler um ficheiro vazio em vez de encontrar um ficheiro inexistente.

docker exec gluetun cat /tmp/gluetun/forwarded_port

Ele disponibiliza o valor no servidor de controlo, que escuta em :8000 por predefinição e é configurado por HTTP_CONTROL_SERVER_ADDRESS.

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

O Gluetun também abre essa porta na sua própria firewall da interface VPN. Por isso, FIREWALL_VPN_INPUT_PORTS não é necessário enquanto a integração nativa estiver a tratar do encaminhamento. Essa variável aplica-se ao outro caso: um fornecedor que o gluetun não consegue consultar, quando recebeu uma porta estática por outro canal e tem de a permitir manualmente.

Uma destas três opções é persistente e as outras duas não são. A documentação upstream marca o ficheiro de estado como obsoleto na v4.0.0, e GET /v1/openvpn/portforwarded já responde com 301 Moved Permanently, apontando para /v1/portforward. O código novo deve ler o servidor de controlo.

Por que o cliente tem de receber a porta em cada reconexão

Um cliente BitTorrent guarda a sua porta de escuta na própria configuração e mantém esse número após os reinícios. A porta encaminhada é uma propriedade da sessão VPN. Depois de uma reconexão, os dois números deixam de coincidir. O fornecedor encaminha então uma porta onde nada está à escuta, enquanto o cliente escuta numa porta que não está encaminhada. As reconexões não são raras: podem ocorrer devido ao reinício de um contentor, a uma alteração no servidor, a uma ligação interrompida cujo túnel é reiniciado pela verificação de estado do gluetun ou a uma concessão que não pôde ser renovada. O resultado é uma configuração que estava acessível ontem e hoje está silenciosamente inacessível, sem qualquer erro em nenhum dos logs.

Por isso, a porta tem de ser aplicada no momento em que o gluetun a obtém. Há duas formas de fazer essa ligação, e diferem no processo que executa o trabalho.

Opção 1: o gluetun envia a porta com um comando up

VPN_PORT_FORWARDING_UP_COMMAND é executado quando o encaminhamento da porta fica disponível, e VPN_PORT_FORWARDING_DOWN_COMMAND é executado quando ele é desativado. O Gluetun substitui {{PORT}} (a primeira porta), {{PORTS}} (todas as portas, separadas por vírgulas) e {{VPN_INTERFACE}} (o nome da interface do túnel, tun0 por predefinição) antes de executar o comando. A sintaxe de shell requer um wrapper /bin/sh -c explícito. Este é o exemplo upstream para qBittorrent, escrito como duas entradas de ambiente do 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'

Cada campo dessa chamada tem uma função. listen_port é a nova porta. current_network_interface associa o qBittorrent ao túnel. Definir random_port como false impede que o qBittorrent escolha a sua própria porta no arranque seguinte. Definir upnp como false impede que tente mapear uma porta através de um router que não existe.

Esta abordagem tem dois requisitos. A interface Web do qBittorrent tem de estar ativada e a escutar na porta 8080, e a partilha do namespace de rede do gluetun é o que permite que responda em 127.0.0.1:8080 a partir do interior do contentor gluetun. Além disso, Bypass authentication for clients on localhost (bypass_local_auth) tem de estar ativado, porque o comando não envia credenciais. O comando down é necessário porque o qBittorrent nem sempre restabelece a porta depois de uma desconexão.

O comando é executado dentro do contentor gluetun, que é baseado em Alpine e inclui wget. Essa imagem não contém curl. Um comando que especifique um binário inexistente na imagem falha sempre que o encaminhamento da porta é ativado.

Opção 2: um processo fora do gluetun lê a porta

O outro padrão executa um processo pequeno junto do gluetun. Esse processo obtém a porta e envia-a para o cliente através da própria API do cliente. Leia-a a partir do servidor de controlo:

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

Também pode ler o ficheiro, se o processo tiver acesso a ele. /tmp/gluetun/forwarded_port fica dentro do contentor gluetun. Por isso, um sidecar precisa de um volume partilhado montado em /tmp/gluetun nos dois contentores. Em alternativa, aponte VPN_PORT_FORWARDING_STATUS_FILE para um caminho dentro de um volume que já esteja montado.

A autenticação é importante. Na v3.41.3, a rota GET /v1/portforward pertence a uma função predefinida chamada public, com auth = "none". Por isso, responde sem credenciais, e os logs do gluetun registam um aviso que começa por route GET /v1/portforward is unprotected by default, please set up authentication. O projeto upstream vai fechar esse acesso numa versão posterior. A documentação atual do control server já descreve todas as rotas como privadas por predefinição. Defina já uma função, no ficheiro montado através de bind em /gluetun/auth/config.toml:

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

Gere uma chave com docker run --rm qmcgaw/gluetun:v3.41.3 genkey e envie-a no cabeçalho X-API-Key. HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE faz o mesmo que uma variável de ambiente codificada em JSON quando preferir não montar um ficheiro. Depois de definir qualquer função, a v3.41.3 deixa de aplicar a função incorporada public. Assim, todas as rotas chamadas a partir desse momento precisam de uma função que as liste. Sem nenhuma função definida, a função incorporada public também cobre PUT /v1/vpn/status. Por isso, publicar a porta 8000 sem configuração de autenticação permite que qualquer pessoa com acesso à porta controle o estado da VPN. Decida deliberadamente até onde esse acesso deve ser exposto ao consultar como aceder ao gluetun a partir do host e de outros contentores.

Escolha o comando up quando o cliente expuser uma API que possa ser controlada por uma chamada wget. O comando é executado exatamente uma vez por evento e não deixa nenhum processo a correr. Escolha um processo externo quando o cliente precisar de um fluxo de login, de reescrever um ficheiro de configuração ou de reiniciar. Em uma stack arr atrás de um único contentor gluetun, isto normalmente resulta num único processo de polling, porque apenas o cliente de torrents precisa da porta.

A armadilha: partilhar o namespace não define a porta de escuta

Esta falha é a que mais tempo desperdiça. network_mode: "service:gluetun" coloca o cliente no namespace de rede do gluetun, por isso o cliente recebe o endereço VPN, as rotas do túnel e as regras de firewall do gluetun. Nada disso define a porta de escuta do cliente. O gluetun abre a porta encaminhada na interface VPN, os pacotes destinados a essa porta chegam ao namespace e, se o cliente escutar numa porta diferente, o kernel não tem nenhum processo para os receber. A ligação é recusada ou expira, embora todas as verificações de saída indiquem um estado normal. A porta encaminhada e a porta de escuta do cliente são dois números distintos. A tarefa consiste em mantê-los iguais.

Compare os valores em vez de os adivinhar. Ambos os comandos são executados no mesmo 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]*'

Há outra configuração que encaminha as pessoas na direção errada. VPN_PORT_FORWARDING_LISTENING_PORT redireciona o tráfego recebido na porta encaminhada para uma porta local fixa através do iptables. A documentação do projeto recomenda não usar esta opção com clientes de torrents, porque o cliente anuncia a sua própria porta de escuta aos trackers e peers. Assim, o swarm fica a conhecer o número errado.

Como provar que a porta encaminhada está acessível

O indicador de ligação do próprio cliente reflete as ligações de saída aos trackers. Por isso, pode aparecer a verde mesmo quando ninguém consegue estabelecer ligação consigo. Faça o teste com um listener que controla, a partir de uma rede fora do túnel. O projeto upstream disponibiliza uma ferramenta pequena para este fim. Pare primeiro o cliente de torrents, porque dois processos não podem associar-se à mesma porta.

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

Dentro do contentor, altere amd64 para a arquitetura da sua CPU e 4567 para a porta encaminhada:

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"

Agora descubra qual é o endereço de saída utilizado pelo gluetun. A resposta está em JSON e o endereço encontra-se no campo public_ip.

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

Esse pedido simples só responde enquanto a versão v3.41.3 estiver a ser executada sem configuração de autenticação. Se definiu funções como na Opção 2, adicione GET /v1/publicip/ip a routes de uma função e envie a chave dessa função, por exemplo curl -s -H "X-API-Key: myapikey" http://127.0.0.1:8000/v1/publicip/ip.

Abra http://<that address>:4567 num dispositivo que não esteja na mesma VPN. Um telemóvel a usar dados móveis serve. Uma página que mostre o endereço IP e o user agent do seu browser, com um pedido correspondente registado pelo port-checker, indica que o TCP de entrada chega ao namespace. Um timeout indica que não chega, e que a causa está acima do cliente. Pare a ferramenta com CTRL+C, saia da shell com exit e inicie novamente o cliente. Este teste verifica apenas TCP. O DHT (distributed hash table) e o tráfego uTP usam UDP no mesmo número de porta, o que este teste não abrange.

Modos de falha e mensagens que verá

Não existe qualquer linha de porta no log. Nenhum pedido de porta foi feito. Confirme se a variável chegou efetivamente ao container com docker exec gluetun printenv | grep PORT_FORWARDING, pois definir uma variável no serviço errado do compose é uma causa comum.

Gluetun recusa iniciar e apresenta uma mensagem sobre o provider. VPN_PORT_FORWARDING_PROVIDER é validado com base nos quatro nomes suportados. Um erro de digitação faz o container parar, em vez de funcionar silenciosamente sem encaminhamento.

O log indica no port forwarded. O Gluetun fez o pedido, mas o provider não devolveu nada. No ProtonVPN, isso normalmente significa que NAT-PMP não estava ativado na configuração gerada ou que o plano não inclui port forwarding. No Private Internet Access, normalmente significa que o servidor selecionado não oferece essa funcionalidade.

A porta é atribuída, mas não é possível estabelecer ligações de entrada. Compare a porta encaminhada com a porta de escuta do cliente usando os dois comandos acima. Se forem iguais, verifique se o cliente está associado à interface do túnel e se a opção de porta aleatória está desativada, pois essa opção altera a porta de escuta em cada arranque.

O comando up parece não fazer nada. Execute o comando exato dentro do container para ver o erro: docker exec gluetun /bin/sh -c '<your command>'. curl: not found é o resultado habitual, porque a imagem inclui apenas wget.

401 Unauthorized a partir do servidor de controlo. Definiu uma configuração de autenticação, mas a role não inclui a route que está a chamar. As routes são correspondidas pela combinação de método e path. Por isso, uma role que inclua apenas /v1/portforward não abrange GET /v1/portforward.

Uma porta diferente no Private Internet Access após cada reinício. Faça bind mount de /gluetun para que o estado da porta guardado sobreviva ao reinício. Sem esse volume, o Gluetun solicita uma porta nova em cada arranque.

FAQ

Porque é que os meus torrents descarregam, mas nunca recebem ligações de entrada?

Sem uma porta encaminhada, o fornecedor de VPN não tem uma regra NAT que encaminhe pacotes de entrada, em nenhuma porta, para o seu túnel. Por isso, as ligações que não foram iniciadas por si são descartadas no endereço de saída. Os downloads continuam a funcionar porque o seu cliente abre essas ligações e consegue contactar qualquer peer que esteja acessível. O seeding e a entrada em swarms ficam prejudicados, porque ambos dependem de outros utilizadores conseguirem contactá-lo. A solução é usar um fornecedor que disponibilize encaminhamento de portas, VPN_PORT_FORWARDING=on no gluetun e aplicar a porta resultante à porta de escuta do cliente.

O gluetun funciona com o encaminhamento de portas de qualquer fornecedor de VPN?

Não. O gluetun v3.41.3 tem integração nativa com quatro fornecedores: Private Internet Access, ProtonVPN, Perfect Privacy e PrivateVPN. Qualquer fornecedor fora dessa lista falha a validação de VPN_PORT_FORWARDING_PROVIDER e o contentor para durante o arranque. Se o fornecedor atribuir uma porta estática através do seu próprio painel de controlo, o gluetun não pode solicitá-la por si, mas FIREWALL_VPN_INPUT_PORTS permite que essa porta fixa passe pela firewall do gluetun. As políticas dos fornecedores mudam, por isso consulte a página atual do fornecedor antes de adquirir um plano para esta finalidade.

Tenho de atualizar a porta depois de cada reconexão?

Sim, e essa atualização deve ser automática. A porta encaminhada pertence à sessão VPN. Por isso, um reinício do contentor, uma mudança de servidor ou uma renovação de concessão falhada pode gerar um novo número, enquanto o cliente mantém a porta guardada na sua própria configuração. Pode deixar o gluetun aplicá-la através de VPN_PORT_FORWARDING_UP_COMMAND, que é executado assim que o encaminhamento fica ativo, ou executar um processo pequeno que leia GET /v1/portforward do servidor de controlo e escreva o valor no cliente através da respetiva API.

Como verifico se a porta encaminhada está realmente aberta?

Execute um listener nessa porta exata dentro do namespace de rede do gluetun e ligue-se a ele a partir do exterior da VPN. Pare primeiro o cliente de torrents para libertar a porta. Em seguida, execute o binário upstream de verificação de portas dentro do contentor gluetun com --listening-address=":<port>". Obtenha o endereço de saída através de curl -s http://127.0.0.1:8000/v1/publicip/ip, adicionando -H "X-API-Key: <key>" para uma função que liste GET /v1/publicip/ip, caso tenha configurado a autenticação do servidor de controlo, e abra http://<address>:<port> num telefone ligado a dados móveis. O aparecimento de um pedido no log do verificador de portas prova que chega tráfego TCP de entrada. Um timeout significa que esse tráfego não chega, independentemente do estado apresentado pelo próprio cliente.

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