SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor

Cara Mengatur Port Forwarding Gluetun untuk Torrent

Unduhan berjalan, tetapi tidak ada koneksi masuk? Atur port forwarding Gluetun, kirim port baru ke torrent client setiap reconnect, lalu verifikasi hasilnya.

Mengapa tidak ada koneksi masuk tanpa port yang diteruskan

Port forwarding Gluetun meminta penyedia VPN memetakan satu port publik pada alamat keluar VPN ke container Anda. Ini adalah satu-satunya cara peer lain dapat memulai koneksi ke torrent client Anda. Tanpa pemetaan tersebut, tunnel tetap sehat, unduhan berjalan, dan tidak ada koneksi yang masuk dengan sendirinya. Setiap koneksi yang berhasil adalah koneksi yang terlebih dahulu dibuka oleh client Anda.

Mekanismenya adalah NAT (network address translation). Container Anda menggunakan alamat keluar VPN yang sama dengan banyak pelanggan lain. Saat client Anda membuka koneksi ke luar, penyedia VPN mencatat aliran tersebut dan mengirimkan balasannya kembali melalui tunnel Anda. Koneksi masuk dari peer yang tidak dikenal tidak cocok dengan aliran yang tercatat, sehingga paket mencapai alamat keluar VPN lalu dibuang di sana. Client Anda tetap dapat terhubung ke setiap peer yang dapat menerima koneksi. Karena itu, unduhan selesai dan masalah ini tidak terlihat. Masalah mulai terlihat saat seeding, karena seeder adalah mesin yang menerima koneksi dari pengguna lain.

Port masuk yang terbuka mengubah dua hal. Anda bergabung ke swarm lebih cepat karena peer yang tidak dapat menerima koneksi sendiri kini dapat terhubung ke Anda. Anda juga dapat mengunggah ke peer tersebut.

Mengapa sebagian besar penyedia VPN tidak menawarkan port forwarding

Port yang diteruskan merupakan sumber daya terbatas pada alamat bersama. Penyedia mencadangkan satu nomor port pada satu IP keluar untuk satu pelanggan, lalu bertanggung jawab atas aktivitas pelanggan tersebut melalui port itu. Beberapa penyedia besar menghapus fitur ini dan menyebut penanganan penyalahgunaan sebagai alasannya. Perlakukan dukungan fitur ini sebagai pertanyaan kategoris, bukan sekadar kotak centang: tanyakan apakah penyedia menawarkan port forwarding saat ini, pada paket Anda, dan pada server yang benar-benar dapat Anda pilih.

Jika port forwarding tersedia, port tersebut bersifat dinamis. Port itu terkait dengan sesi VPN, bukan akun Anda, sehingga nomornya dapat berbeda setiap kali Anda tersambung kembali. Private Internet Access memberikan port bertanda tangan yang diperbarui oleh gluetun. Dokumentasi upstream menyatakan bahwa Anda dapat mempertahankan port yang sama selama 60 hari, asalkan melakukan bind mount pada direktori /gluetun agar statusnya tetap tersimpan setelah restart. ProtonVPN menetapkan port acak melalui NAT-PMP (NAT port mapping protocol) dengan lease singkat yang harus diperbarui secara terus-menerus. Karena itu, menetapkan port satu kali di client tidak akan membuatnya tetap berfungsi.

Penyedia yang dapat dimintai port oleh gluetun

Per 30 July 2026, gluetun v3.41.3 memvalidasi integrasi native terhadap empat nama penyedia: Private Internet Access, ProtonVPN, Perfect Privacy, dan PrivateVPN. Aktifkan integrasi ini dengan VPN_PORT_FORWARDING=on, yang secara default adalah off. Panduan lama menggunakan PORT_FORWARDING atau PRIVATE_INTERNET_ACCESS_VPN_PORT_FORWARDING. Keduanya masih berfungsi pada versi ini sebagai nama yang kompatibel dengan versi sebelumnya, tetapi keduanya akan dihentikan.

Dua detail penyedia menentukan apakah permintaan dapat berhasil. ProtonVPN memerlukan paket berbayar, dan NAT-PMP harus diaktifkan: aktifkan NAT-PMP (Port Forwarding) pada opsi VPN saat membuat konfigurasi WireGuard, atau tambahkan +pmp ke username saat menggunakan OpenVPN. Pada OpenVPN, Private Internet Access menyediakan PORT_FORWARD_ONLY. Opsi ini membatasi pemilihan server ke server yang mendukung port forwarding, sehingga Anda tidak terhubung ke server yang tidak pernah mendukungnya. WireGuard dan OpenVPN berbeda dalam cara meminta port, jadi baca halaman penyedia sebelum memilih metode.

Saat gluetun menjalankan konfigurasi khusus, bukan provider bawaan, VPN_PORT_FORWARDING_PROVIDER menentukan API yang harus dipanggil gluetun. Halaman Private Internet Access di upstream memasangkan variabel tersebut dengan VPN_PORT_FORWARDING_USERNAME dan VPN_PORT_FORWARDING_PASSWORD, yang berisi kredensial akun yang diperlukan untuk meminta port.

Aktifkan penerusan port gluetun di docker compose

Panduan ini mengasumsikan tunnel sudah berfungsi. Jika belum, mulai dengan mengarahkan trafik container Docker melalui gluetun, lalu kembali setelah unduhan berjalan.

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

Tetapkan tag secara eksplisit. qmcgaw/gluetun:latest mengikuti branch master, tempat mekanisme internal penerusan port sedang mengalami perubahan untuk v4. Karena itu, image tanpa tag tetap dapat mengubah perilakunya pada docker compose pull berikutnya. Simpan private key di luar file compose menggunakan file env untuk secret compose.

Lokasi gluetun menulis port yang diteruskan

Gluetun mengekspos port di tiga tempat, dan semuanya berisi nilai yang sama.

Gluetun mencatat port satu kali setiap kali port diperoleh. Baris tersebut berbunyi port forwarded is 45678, dan no port forwarded jika permintaan tidak menghasilkan apa pun.

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

Gluetun menulis nomor tersebut ke file yang ditentukan oleh VPN_PORT_FORWARDING_STATUS_FILE, yang secara default adalah /tmp/gluetun/forwarded_port. File tersebut berisi satu port per baris, ditulis dengan mode 0644, dan kepemilikannya diubah ke PUID dan PGID milik container. Saat penerusan berhenti, gluetun mengosongkan file tersebut tanpa menghapusnya. Dengan demikian, consumer dapat membaca file kosong, bukan mendapatkan error karena file tidak ditemukan.

docker exec gluetun cat /tmp/gluetun/forwarded_port

Gluetun menyediakan nilai tersebut melalui control server, yang secara default mendengarkan pada :8000 dan dikonfigurasi dengan HTTP_CONTROL_SERVER_ADDRESS.

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

Gluetun juga membuka port tersebut pada firewall-nya sendiri di antarmuka VPN. Karena itu, FIREWALL_VPN_INPUT_PORTS tidak diperlukan saat integrasi native menjalankan proses ini. Variabel tersebut digunakan pada kasus lain: provider yang tidak dapat dikueri oleh gluetun, ketika Anda menerima port statis melalui jalur di luar sistem dan harus mengizinkannya secara manual.

Dari ketiga cara tersebut, satu bersifat persisten dan dua lainnya tidak. Dokumentasi upstream menandai status file sebagai deprecated pada v4.0.0, dan GET /v1/openvpn/portforwarded sudah memberikan respons 301 Moved Permanently yang mengarah ke /v1/portforward. Pekerjaan baru sebaiknya membaca control server.

Mengapa client harus diberi tahu port pada setiap koneksi ulang

Torrent client menyimpan port listening dalam konfigurasinya sendiri dan mempertahankan nomor tersebut setelah restart. Port yang diteruskan merupakan properti sesi VPN. Setelah koneksi ulang, kedua nomor tersebut tidak sama. Akibatnya, provider memetakan port yang tidak digunakan untuk listening oleh apa pun, sedangkan client melakukan listening pada port yang tidak dipetakan oleh apa pun. Koneksi ulang bukan kejadian yang jarang: restart container, perubahan server, tunnel yang terputus lalu direstart oleh health check gluetun, atau lease yang tidak dapat diperbarui. Hasilnya adalah setup yang kemarin masih dapat diakses, tetapi hari ini diam-diam tidak dapat diakses, tanpa error pada kedua log.

Karena itu, port harus diterapkan saat gluetun mendapatkannya. Ada dua cara untuk menghubungkannya, dan perbedaannya terletak pada proses yang menjalankan pekerjaan tersebut.

Opsi 1: gluetun meneruskan port dengan perintah up

VPN_PORT_FORWARDING_UP_COMMAND dijalankan saat port forwarding aktif, sedangkan VPN_PORT_FORWARDING_DOWN_COMMAND dijalankan saat port tersebut dinonaktifkan. Gluetun mengganti {{PORT}} (port pertama), {{PORTS}} (semua port, dipisahkan dengan koma), dan {{VPN_INTERFACE}} (nama antarmuka tunnel, secara default tun0) sebelum menjalankan perintah. Sintaks shell memerlukan wrapper /bin/sh -c secara eksplisit. Berikut contoh qBittorrent dari upstream, yang ditulis sebagai dua entri environment pada 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'

Setiap field dalam pemanggilan tersebut memiliki fungsi. listen_port adalah port baru. current_network_interface mengikat qBittorrent ke tunnel. random_port yang disetel ke false mencegah qBittorrent memilih port sendiri saat start berikutnya. upnp yang disetel ke false mencegah qBittorrent mencoba memetakan port melalui router yang tidak tersedia.

Pendekatan ini memiliki dua persyaratan. Web UI qBittorrent harus diaktifkan dan listening pada port 8080. Berbagi network namespace gluetun memungkinkan qBittorrent merespons pada 127.0.0.1:8080 dari dalam container gluetun. Selain itu, Bypass authentication for clients on localhost (bypass_local_auth) harus diaktifkan karena perintah tersebut tidak mengirimkan kredensial. Perintah down diperlukan karena qBittorrent tidak selalu mengaktifkan kembali port setelah koneksi terputus.

Perintah tersebut dijalankan di dalam container gluetun, yang berbasis Alpine dan menyertakan wget. Image tersebut tidak memiliki curl. Perintah yang menyebut binary yang tidak tersedia di image akan selalu gagal setiap kali port forwarding aktif.

Opsi 2: proses di luar gluetun membaca port

Pola lainnya menjalankan proses kecil di samping gluetun. Proses ini mengambil port, lalu mengirimkannya ke client melalui API milik client tersebut. Baca port dari control server:

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

Atau baca file tersebut jika proses dapat melihatnya. /tmp/gluetun/forwarded_port berada di dalam container gluetun. Karena itu, sidecar memerlukan shared volume yang di-mount pada /tmp/gluetun di kedua container, atau Anda dapat mengarahkan VPN_PORT_FORWARDING_STATUS_FILE ke path di bawah volume yang sudah Anda mount.

Autentikasi penting di sini. Pada v3.41.3, route GET /v1/portforward dimiliki role default bernama public dengan auth = "none". Karena itu, route tersebut merespons tanpa kredensial, dan gluetun mencatat peringatan yang diawali dengan route GET /v1/portforward is unprotected by default, please set up authentication. Upstream akan menutup akses tersebut pada rilis berikutnya. Dokumentasi control server saat ini juga sudah menjelaskan bahwa setiap route secara default bersifat privat. Definisikan role sekarang, di file yang di-bind mount pada /gluetun/auth/config.toml:

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

Buat key dengan docker run --rm qmcgaw/gluetun:v3.41.3 genkey, lalu kirimkan key tersebut dalam header X-API-Key. HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE menjalankan fungsi yang sama seperti satu environment variable yang dienkode sebagai JSON jika Anda tidak ingin melakukan mount file. Setelah Anda mendefinisikan role apa pun, v3.41.3 berhenti menerapkan role bawaan public. Karena itu, setiap route yang Anda panggil setelahnya harus memiliki role yang mencantumkan route tersebut. Tanpa role apa pun, role bawaan public juga mencakup PUT /v1/vpn/status. Artinya, port 8000 yang dipublikasikan tanpa konfigurasi autentikasi memberikan kendali atas status VPN kepada siapa pun yang dapat menjangkaunya. Tentukan dengan sengaja sejauh mana akses tersebut dapat menyebar saat Anda menentukan cara mengakses gluetun dari host dan container lain.

Pilih perintah up jika client menyediakan API yang dapat dikendalikan oleh satu pemanggilan wget. Perintah tersebut berjalan tepat satu kali untuk setiap event dan tidak memerlukan proses yang terus berjalan. Pilih proses eksternal jika client memerlukan alur login, penulisan ulang file konfigurasi, atau restart. Dalam stack arr di balik satu container gluetun, biasanya hasil akhirnya adalah satu poller kecil karena hanya client torrent yang memerlukan port tersebut.

Jebakan: berbagi namespace tidak menetapkan port listening

Kegagalan ini paling banyak membuang waktu. network_mode: "service:gluetun" menempatkan client dalam network namespace milik gluetun, sehingga client tersebut menggunakan alamat VPN, rute tunnel, dan aturan firewall gluetun. Semua itu tidak menetapkan port listening client. Gluetun membuka port yang diteruskan pada interface VPN. Paket untuk port tersebut tiba di namespace. Jika client melakukan listening pada port yang berbeda, kernel tidak memiliki tujuan untuk meneruskan paket tersebut. Koneksi ditolak atau mengalami timeout, sementara semua pemeriksaan koneksi keluar terlihat normal. Port yang diteruskan dan port listening client adalah dua angka yang berbeda. Tugas utamanya adalah menyamakan keduanya.

Bandingkan keduanya, bukan menebak. Kedua perintah berikut dijalankan pada namespace yang sama:

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

Ada satu pengaturan lain yang dapat mengarahkan Anda ke pemeriksaan yang keliru. VPN_PORT_FORWARDING_LISTENING_PORT mengalihkan trafik masuk dari port yang diteruskan ke port lokal tetap menggunakan iptables. Dokumentasi upstream menyarankan agar pengaturan ini tidak digunakan bersama torrent client, karena client mengumumkan port listening-nya sendiri kepada tracker dan peer. Akibatnya, swarm mengetahui nomor port yang salah.

Cara membuktikan bahwa port yang diteruskan dapat dijangkau

Indikator koneksi milik client hanya mencerminkan koneksi keluar ke tracker. Karena itu, indikator dapat terlihat hijau meskipun tidak ada koneksi masuk yang dapat menjangkau Anda. Lakukan pengujian menggunakan listener yang Anda kendalikan dari jaringan di luar tunnel. Upstream menyediakan tool kecil untuk keperluan ini. Hentikan client torrent terlebih dahulu karena dua proses tidak dapat melakukan bind pada port yang sama.

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

Di dalam container, ubah amd64 sesuai arsitektur CPU Anda dan 4567 sesuai port yang diteruskan:

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"

Sekarang cari alamat keluar yang digunakan gluetun. Responsnya berupa JSON, dan alamat tersebut berada di field public_ip.

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

Request sederhana tersebut hanya merespons ketika v3.41.3 berjalan tanpa konfigurasi auth. Jika Anda mendefinisikan role seperti pada Option 2, tambahkan GET /v1/publicip/ip ke routes milik sebuah role, lalu kirim key role tersebut, misalnya curl -s -H "X-API-Key: myapikey" http://127.0.0.1:8000/v1/publicip/ip.

Buka http://<that address>:4567 dari perangkat yang tidak terhubung ke VPN yang sama. Ponsel dengan koneksi data seluler dapat digunakan. Halaman yang menampilkan alamat IP dan user agent browser Anda, disertai request yang sesuai pada log port-checker, menunjukkan bahwa TCP masuk mencapai namespace tersebut. Timeout berarti koneksi tidak dapat mencapainya, dan penyebabnya berada di atas client. Hentikan tool dengan CTRL+C, keluar dari shell menggunakan exit, lalu jalankan kembali client. Pengujian ini hanya memeriksa TCP. Traffic DHT (distributed hash table) dan uTP menggunakan UDP pada nomor port yang sama, tetapi tidak tercakup dalam pengujian ini.

Mode kegagalan dan string yang akan ditampilkan

Tidak ada baris port sama sekali di log. Tidak ada permintaan port. Pastikan variabel benar-benar diteruskan ke container dengan docker exec gluetun printenv | grep PORT_FORWARDING, karena variabel yang ditetapkan pada service compose yang salah merupakan penyebab umum.

Gluetun menolak start dan menampilkan keluhan tentang provider. VPN_PORT_FORWARDING_PROVIDER divalidasi terhadap empat nama yang didukung. Kesalahan penulisan membuat container berhenti, bukan berjalan tanpa forwarding.

Log menampilkan no port forwarded. Gluetun mengajukan permintaan, tetapi provider tidak memberikan hasil. Pada ProtonVPN, biasanya NAT-PMP belum diaktifkan pada konfigurasi yang Anda buat, atau paket layanan tidak mencakup port forwarding. Pada Private Internet Access, biasanya server yang dipilih tidak menyediakannya.

Port diterima, tetapi tidak ada koneksi yang masuk. Bandingkan port yang diteruskan dengan port listening milik client menggunakan dua perintah di atas. Jika sama, pastikan client terikat ke interface tunnel dan opsi random-port dinonaktifkan, karena opsi tersebut menulis ulang port listening setiap kali start.

Perintah up tampaknya tidak melakukan apa pun. Jalankan perintah yang sama persis di dalam container untuk melihat error: docker exec gluetun /bin/sh -c '<your command>'. curl: not found biasanya muncul karena image hanya menyertakan wget.

401 Unauthorized dari control server. Anda menetapkan konfigurasi autentikasi, tetapi role tidak mencantumkan route yang Anda panggil. Route dicocokkan berdasarkan method dan path. Karena itu, role yang hanya mencantumkan /v1/portforward tidak mencakup GET /v1/portforward.

Port Private Internet Access berbeda setiap kali restart. Bind mount /gluetun agar status port yang tersimpan tetap ada setelah restart. Tanpa volume tersebut, gluetun meminta port baru setiap kali.

FAQ

Mengapa torrent saya mengunduh, tetapi tidak pernah menerima koneksi masuk?

Tanpa port forwarding, penyedia VPN tidak memiliki aturan NAT yang meneruskan paket masuk pada port mana pun ke tunnel Anda. Karena itu, koneksi yang tidak Anda mulai akan dibuang pada alamat keluar. Pengunduhan tetap berfungsi karena client Anda sendiri yang membuka koneksi tersebut. Client juga dapat menjangkau peer mana pun yang dapat menerima koneksi. Seeding dan bergabung ke swarm terganggu karena keduanya bergantung pada perangkat lain yang dapat menjangkau Anda. Solusinya adalah menggunakan penyedia yang menyediakan port forwarding, VPN_PORT_FORWARDING=on di gluetun, lalu menerapkan port yang dihasilkan ke port listening client.

Apakah gluetun berfungsi dengan port forwarding dari penyedia VPN mana pun?

Tidak. gluetun v3.41.3 memiliki integrasi native untuk 4 penyedia: Private Internet Access, ProtonVPN, Perfect Privacy, dan PrivateVPN. Penyedia di luar daftar tersebut gagal dalam validasi VPN_PORT_FORWARDING_PROVIDER, lalu container berhenti saat startup. Jika penyedia Anda memberikan port statis melalui control panel miliknya, gluetun tidak dapat memintanya untuk Anda. Namun, FIREWALL_VPN_INPUT_PORTS akan mengizinkan port tetap tersebut melalui firewall gluetun. Kebijakan penyedia dapat berubah. Periksa halaman penyedia yang berlaku sebelum membeli paket untuk kebutuhan ini.

Apakah saya harus memperbarui port setelah setiap koneksi ulang?

Ya. Pembaruan tersebut seharusnya berlangsung otomatis. Port yang diteruskan terkait dengan sesi VPN. Karena itu, restart container, pergantian server, atau kegagalan perpanjangan lease dapat menghasilkan nomor baru, sementara client tetap menyimpan port lama dalam konfigurasinya sendiri. Biarkan gluetun meneruskannya dengan VPN_PORT_FORWARDING_UP_COMMAND, yang dijalankan segera setelah forwarding aktif. Alternatifnya, jalankan proses kecil yang membaca GET /v1/portforward dari control server dan menulis nilainya ke client melalui API client.

Bagaimana cara memeriksa apakah port yang diteruskan benar-benar terbuka?

Jalankan listener pada port yang sama persis di dalam network namespace gluetun, lalu sambungkan ke port tersebut dari luar VPN. Hentikan client torrent terlebih dahulu agar port tersedia. Kemudian, jalankan binary port-checker dari upstream di dalam container gluetun dengan --listening-address=":<port>". Dapatkan alamat keluar dari curl -s http://127.0.0.1:8000/v1/publicip/ip. Tambahkan -H "X-API-Key: <key>" untuk role yang mencantumkan GET /v1/publicip/ip jika Anda telah mengatur autentikasi control server. Setelah itu, buka http://<address>:<port> dari ponsel yang menggunakan data seluler. Permintaan yang muncul dalam log port-checker membuktikan bahwa TCP masuk telah tiba. Timeout berarti koneksi tersebut tidak sampai, apa pun status yang ditampilkan ikon client.

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