SSD Nodes Learn 🎉 VPS desde $5.50/mes
Guías Matt ConnorPor Matt Connor

Reenvío de puertos de Gluetun para clientes torrent

Las descargas funcionan, pero no entran conexiones. Configura el reenvío de puertos de Gluetun, actualiza el puerto del cliente torrent tras cada reconexión y verifícalo.

Por qué no entra ninguna conexión sin un puerto redirigido

El reenvío de puertos de Gluetun solicita al proveedor de VPN que asigne un puerto público de su dirección de salida y lo redirija a tu contenedor. Es la única forma de que otro peer pueda iniciar una conexión con tu cliente torrent. Sin esa asignación, el túnel funciona, las descargas se ejecutan y no llega ninguna conexión por sí sola. Todas las conexiones activas son conexiones que tu cliente inició primero.

El mecanismo es NAT (traducción de direcciones de red). Tu contenedor comparte la dirección de salida del proveedor con muchos otros clientes. Cuando tu cliente abre una conexión hacia el exterior, el proveedor registra ese flujo y envía las respuestas de vuelta por el túnel. La conexión entrante de un peer externo no coincide con ningún flujo registrado, por lo que el paquete llega a la dirección de salida y se descarta allí. Tu cliente sigue conectándose con todos los peers que sí aceptan conexiones, por lo que las descargas terminan y el problema puede pasar inadvertido. Se hace evidente al compartir, porque un seeder es un equipo al que se conectan otros usuarios.

Un puerto entrante abierto cambia dos aspectos. Te incorporas más rápido al swarm, porque los peers que no pueden aceptar conexiones ahora sí pueden llegar hasta ti. Además, puedes cargar datos a esos peers.

Por qué la mayoría de los proveedores de VPN no ofrecen reenvío de puertos

Un puerto reenviado es un recurso limitado en una dirección compartida. El proveedor reserva un número de puerto en una IP de salida para un cliente y, después, responde por todo lo que ese cliente haga con él. Varios proveedores grandes eliminaron esta función y señalaron la gestión de abusos como motivo. Considere la compatibilidad como una cuestión de categoría, no como una casilla de verificación: pregunte si el proveedor ofrece reenvío de puertos actualmente, con su plan y en servidores que realmente pueda seleccionar.

Cuando existe el reenvío, el puerto es dinámico. Pertenece a la sesión de VPN y no a su cuenta, por lo que puede ser un número distinto después de cada reconexión. Private Internet Access emite un puerto firmado que gluetun actualiza, y la documentación original indica que el mismo puerto se conserva durante 60 días siempre que monte /gluetun como bind mount para que el estado sobreviva a un reinicio. ProtonVPN asigna un puerto aleatorio mediante NAT-PMP (protocolo de asignación de puertos NAT) con una concesión breve que debe renovarse continuamente. Por eso, configurar el puerto una sola vez en el cliente nunca funciona de forma permanente.

Proveedores a los que gluetun puede solicitar un puerto

A partir de gluetun v3.41.3, publicado el 30 July 2026, la integración nativa valida cuatro nombres de proveedores: Private Internet Access, ProtonVPN, Perfect Privacy y PrivateVPN. Actívela con VPN_PORT_FORWARDING=on, que es off de forma predeterminada. Las guías antiguas usan PORT_FORWARDING o PRIVATE_INTERNET_ACCESS_VPN_PORT_FORWARDING. Ambos siguen funcionando en esta versión como nombres compatibles con versiones anteriores, pero se retirarán próximamente.

Dos detalles del proveedor determinan si la solicitud puede completarse. ProtonVPN requiere un plan de pago y NAT-PMP debe estar habilitado: active NAT-PMP (Port Forwarding) en las opciones de VPN al generar la configuración de WireGuard, o añada +pmp a su nombre de usuario cuando use OpenVPN. En OpenVPN, Private Internet Access usa PORT_FORWARD_ONLY, que limita la selección de servidores a los que admiten el reenvío de puertos. Así no se conecta a un servidor que nunca lo admitió. WireGuard y OpenVPN difieren en cómo se solicita el puerto, así que consulte la página de su proveedor antes de elegir.

Cuando gluetun usa una configuración personalizada en lugar de un proveedor integrado, VPN_PORT_FORWARDING_PROVIDER indica la API a la que gluetun debe llamar. La página de Private Internet Access en el proyecto upstream combina esa variable con VPN_PORT_FORWARDING_USERNAME y VPN_PORT_FORWARDING_PASSWORD, que contienen las credenciales de la cuenta necesarias para solicitar el puerto.

Activar el reenvío de puertos de gluetun en Docker Compose

Esto presupone que el túnel ya funciona. Si no funciona, empiece por enrutar el tráfico de los contenedores Docker a través de gluetun y vuelva cuando las descargas se ejecuten.

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

Fije la etiqueta. qmcgaw/gluetun:latest sigue la rama master, donde los componentes internos del reenvío de puertos están cambiando para la versión 4, por lo que una imagen sin una etiqueta fija puede cambiar su comportamiento en la siguiente docker compose pull. Mantenga la clave privada fuera del archivo de Compose mediante un archivo de entorno para los secretos de Compose.

Dónde escribe gluetun el puerto reenviado

Gluetun expone el puerto en tres lugares, y todos contienen el mismo valor.

Registra el puerto una vez por cada obtención. La línea contiene port forwarded is 45678 y no port forwarded cuando la solicitud no devuelve ningún valor.

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

Escribe el número en el archivo indicado por VPN_PORT_FORWARDING_STATUS_FILE, cuyo valor predeterminado es /tmp/gluetun/forwarded_port. El archivo contiene un puerto por línea, se escribe con el modo 0644 y se cambia su propietario al PUID y PGID del contenedor. Cuando se detiene el reenvío, gluetun vacía el archivo en lugar de eliminarlo. Así, un consumidor puede leer un archivo vacío en vez de encontrar que falta.

docker exec gluetun cat /tmp/gluetun/forwarded_port

Sirve el valor en el servidor de control, que escucha en :8000 de forma predeterminada y se configura mediante HTTP_CONTROL_SERVER_ADDRESS.

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

Gluetun también abre ese puerto en su propio firewall de la interfaz VPN. Por tanto, FIREWALL_VPN_INPUT_PORTS no es necesario mientras la integración nativa realiza el trabajo. Esa variable cubre el otro caso: un proveedor que gluetun no puede consultar, cuando se asignó un puerto estático por otro medio y es necesario permitirlo manualmente.

Uno de estos tres mecanismos es persistente y los otros dos no. La documentación del proyecto marca el archivo de estado como obsoleto desde v4.0.0, y GET /v1/openvpn/portforwarded ya responde con 301 Moved Permanently, que apunta a /v1/portforward. El código nuevo debe leer el servidor de control.

Por qué hay que informar el puerto al cliente en cada reconexión

Un cliente de torrents guarda el puerto de escucha en su propia configuración y conserva ese número después de reiniciarse. El puerto reenviado es una propiedad de la sesión VPN. Después de una reconexión, los dos números no coinciden. El proveedor asigna entonces un puerto en el que no escucha ningún proceso, mientras el cliente escucha en un puerto que no está asignado. Las reconexiones no son poco frecuentes: pueden deberse al reinicio de un contenedor, a un cambio de servidor, a una caída del túnel que el control de estado de gluetun reinicia o a una concesión que no se pudo renovar. El resultado es una configuración que ayer era accesible y hoy no lo es, sin que aparezca ningún error en los registros.

Por tanto, el puerto debe aplicarse en el momento en que gluetun lo obtiene. Hay dos formas de configurarlo y se diferencian en qué proceso realiza el trabajo.

Opción 1: gluetun actualiza el puerto con un comando up

VPN_PORT_FORWARDING_UP_COMMAND se ejecuta cuando se activa el reenvío de puertos y VPN_PORT_FORWARDING_DOWN_COMMAND cuando se desactiva. Gluetun sustituye {{PORT}} (el primer puerto), {{PORTS}} (todos los puertos, separados por comas) y {{VPN_INTERFACE}} (el nombre de la interfaz del túnel, tun0 de forma predeterminada) antes de ejecutar el comando. La sintaxis de shell requiere un contenedor /bin/sh -c explícito. Este es el ejemplo de qBittorrent del proyecto original, escrito como dos entradas de entorno de 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 de esa llamada cumple una función. listen_port es el puerto nuevo. current_network_interface vincula qBittorrent al túnel. Establecer random_port en false impide que qBittorrent elija su propio puerto en el siguiente arranque. Establecer upnp en false impide que intente asignar un puerto mediante un router que no existe.

Este enfoque tiene dos requisitos. La interfaz web de qBittorrent debe responder en 127.0.0.1:8080 desde dentro del contenedor de gluetun. Esto ocurre automáticamente cuando el cliente comparte el espacio de nombres de red de gluetun. Además, Bypass authentication for clients on localhost (bypass_local_auth) debe estar habilitado porque el comando no envía credenciales. El comando down es necesario porque qBittorrent no siempre restablece el puerto después de una desconexión.

El comando se ejecuta dentro del contenedor de gluetun, basado en Alpine, que incluye wget. Esa imagen no contiene curl. Un comando que especifique un binario ausente en la imagen falla cada vez que se activa el reenvío.

Opción 2: un proceso externo a gluetun lee el puerto

El otro patrón ejecuta un proceso pequeño junto a gluetun. Este proceso obtiene el puerto y lo envía al cliente mediante la propia API del cliente. Léalo desde el servidor de control:

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

También puede leer el archivo si el proceso puede verlo. /tmp/gluetun/forwarded_port está dentro del contenedor de gluetun, por lo que un sidecar necesita un volumen compartido montado en /tmp/gluetun en ambos contenedores. Otra opción es apuntar VPN_PORT_FORWARDING_STATUS_FILE a una ruta situada bajo un volumen que ya esté montado.

La autenticación es importante. En v3.41.3, la ruta GET /v1/portforward pertenece a un rol predeterminado llamado public con auth = "none". Por eso responde sin credenciales y los registros de gluetun muestran una advertencia que comienza por route GET /v1/portforward is unprotected by default, please set up authentication. Upstream cerrará esta vía en una versión posterior. Defina ahora un rol en el archivo montado mediante bind mount en /gluetun/auth/config.toml:

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

Genere una clave con docker run --rm qmcgaw/gluetun:v3.41.3 genkey y envíela en la cabecera X-API-Key. HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE realiza la misma función que una variable de entorno codificada en JSON cuando prefiera no montar un archivo. Publicar el puerto 8000 sin un rol permite a cualquiera que pueda acceder a él controlar el estado de la VPN. Por tanto, decida deliberadamente hasta dónde debe estar accesible al determinar cómo acceder a gluetun desde el host y otros contenedores.

Elija el comando up cuando el cliente exponga una API que pueda ejecutar una llamada wget, porque se ejecuta exactamente una vez por evento y no añade ningún proceso que deba permanecer activo. Elija un proceso externo cuando el cliente necesite un flujo de inicio de sesión, reescribir un archivo de configuración o reiniciarse. En una pila de arr detrás de un único contenedor de gluetun, esto suele resolverse con un único proceso de sondeo pequeño, ya que sólo el cliente de torrents necesita el puerto.

La trampa: compartir el espacio de nombres no establece el puerto de escucha

Este fallo hace perder más tiempo que cualquier otro. network_mode: "service:gluetun" coloca el cliente en el espacio de nombres de red de gluetun, por lo que el cliente obtiene la dirección VPN, las rutas del túnel y las reglas del firewall de gluetun. Nada de eso establece el puerto de escucha del cliente. Gluetun abre el puerto reenviado en la interfaz VPN. Los paquetes destinados a ese puerto llegan al espacio de nombres. Si el cliente escucha en otro puerto, el kernel no tiene ningún proceso al que entregárselos. La conexión se rechaza o agota el tiempo de espera, aunque todas las comprobaciones de salida indiquen que el servicio funciona correctamente. El puerto reenviado y el puerto de escucha del cliente son dos números distintos. La tarea consiste en mantenerlos iguales.

Compárelos en lugar de adivinarlos. Ambos comandos se ejecutan en el mismo espacio de nombres:

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

Hay otro ajuste que lleva a muchos usuarios en la dirección equivocada. VPN_PORT_FORWARDING_LISTENING_PORT redirige el tráfico entrante del puerto reenviado a un puerto local fijo mediante iptables. La documentación de upstream indica que no debe usarse con clientes torrent, porque el cliente anuncia su propio puerto de escucha a los trackers y a los pares. Por tanto, el enjambre aprende el número incorrecto.

Cómo demostrar que el puerto reenviado es accesible

El indicador de conexión del propio cliente refleja las conexiones salientes con los trackers, por lo que puede aparecer en verde aunque nadie pueda conectarse desde fuera. Haga la prueba con un listener bajo su control, desde una red externa al túnel. Upstream publica una herramienta pequeña para este fin. Detenga primero el cliente de torrents, porque dos procesos no pueden asociar el mismo puerto.

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

Dentro del contenedor, cambie amd64 por la arquitectura de su CPU y 4567 por el puerto reenviado:

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"

Ahora averigüe qué dirección de salida está usando gluetun. La respuesta está en formato JSON y la dirección se encuentra en el campo public_ip.

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

Abra http://<that address>:4567 desde un dispositivo que no esté conectado a la misma VPN. Puede usar un teléfono con datos móviles. Si una página muestra la dirección IP y el user agent de su navegador, y port-checker registra una petición coincidente, significa que el tráfico TCP entrante llega al namespace. Si se agota el tiempo de espera, no llega y la causa está fuera del cliente. Detenga la herramienta con CTRL+C, salga del shell con exit y vuelva a iniciar el cliente. Esta comprobación sólo prueba TCP. El tráfico DHT (distributed hash table) y uTP usa UDP en el mismo número de puerto, y esta prueba no lo cubre.

Modos de fallo y mensajes que verá

No hay ninguna línea de puerto en el registro. No se solicitó ningún puerto. Confirme que la variable haya llegado realmente al contenedor con docker exec gluetun printenv | grep PORT_FORWARDING, ya que definirla en el servicio incorrecto de Compose es una causa habitual.

Gluetun no se inicia y muestra un error sobre el proveedor. VPN_PORT_FORWARDING_PROVIDER se valida con los cuatro nombres compatibles. Un error tipográfico detiene el contenedor en lugar de ejecutarlo silenciosamente sin reenvío.

El registro muestra no port forwarded. Gluetun hizo la solicitud, pero el proveedor no devolvió ningún puerto. En ProtonVPN, normalmente significa que NAT-PMP no estaba habilitado en la configuración generada o que el plan no incluye reenvío de puertos. En Private Internet Access, normalmente significa que el servidor seleccionado no ofrece esta función.

Se asigna un puerto, pero no se puede establecer ninguna conexión entrante. Compare el puerto reenviado con el puerto de escucha del cliente mediante los dos comandos anteriores. Si coinciden, compruebe que el cliente esté asociado a la interfaz del túnel y que la opción de puerto aleatorio esté desactivada, ya que esa opción cambia el puerto de escucha en cada inicio.

El comando up parece no hacer nada. Ejecute el comando exacto dentro del contenedor para ver el error: docker exec gluetun /bin/sh -c '<your command>'. curl: not found es el resultado habitual, porque la imagen sólo incluye wget.

401 Unauthorized desde el servidor de control. Definió una configuración de autenticación, pero el rol no incluye la ruta que está invocando. Las rutas se comparan como método más ruta, por lo que un rol que sólo incluya /v1/portforward no cubre GET /v1/portforward.

Un puerto diferente en Private Internet Access después de cada reinicio. Monte /gluetun como volumen para conservar el estado del puerto guardado después del reinicio. Sin ese volumen, gluetun solicita un puerto nuevo cada vez.

FAQ

¿Por qué mis torrents se descargan, pero nunca reciben conexiones entrantes?

Sin un puerto reenviado, el proveedor de VPN no tiene ninguna regla NAT que envíe paquetes entrantes de un puerto al túnel. Por eso, las conexiones que usted no inició se descartan en la dirección de salida. Las descargas siguen funcionando porque el cliente abre esas conexiones por sí mismo y puede llegar a cualquier peer que sea accesible. La siembra y la incorporación a los enjambres se ven afectadas, porque ambas dependen de que otros usuarios puedan conectarse a usted. La solución es usar un proveedor que ofrezca reenvío de puertos, VPN_PORT_FORWARDING=on en gluetun y aplicar el puerto resultante al puerto de escucha del cliente.

¿Funciona gluetun con el reenvío de puertos de cualquier proveedor de VPN?

No. Gluetun v3.41.3 integra de forma nativa cuatro proveedores: Private Internet Access, ProtonVPN, Perfect Privacy y PrivateVPN. Todo lo que esté fuera de esa lista no supera la validación de VPN_PORT_FORWARDING_PROVIDER y el contenedor se detiene durante el arranque. Si su proveedor asigna un puerto estático mediante su propio panel de control, gluetun no puede solicitarlo por usted, pero FIREWALL_VPN_INPUT_PORTS permitirá que ese puerto fijo atraviese el firewall de gluetun. Las políticas de los proveedores cambian, así que consulte la página actual del proveedor antes de contratar un plan para este fin.

¿Tengo que actualizar el puerto después de cada reconexión?

Sí, y esa actualización debería ser automática. El puerto reenviado pertenece a la sesión de VPN. Por eso, un reinicio del contenedor, un cambio de servidor o una renovación fallida de la concesión pueden generar un número nuevo, mientras el cliente conserva el puerto almacenado en su propia configuración. Puede dejar que gluetun lo aplique mediante VPN_PORT_FORWARDING_UP_COMMAND, que se ejecuta en cuanto se activa el reenvío, o ejecutar un proceso pequeño que lea GET /v1/portforward del servidor de control y escriba el valor en el cliente mediante su API.

¿Cómo compruebo que el puerto reenviado está realmente abierto?

Ejecute un listener en ese puerto exacto dentro del espacio de nombres de red de gluetun y conéctese a él desde fuera de la VPN. Detenga primero el cliente de torrents para que el puerto quede libre. Después, ejecute el binario de comprobación de puertos del proyecto upstream dentro del contenedor gluetun mediante --listening-address=":<port>". Obtenga la dirección de salida con curl -s http://127.0.0.1:8000/v1/publicip/ip y abra http://<address>:<port> desde un teléfono conectado a datos móviles. Si aparece una solicitud en el registro del comprobador de puertos, significa que el tráfico TCP entrante llega correctamente. Un tiempo de espera agotado significa que no llega, independientemente del icono de estado que muestre el cliente.

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