Gluetun-এ host ও অন্য container-এ পৌঁছাবেন যেভাবে
Gluetun-এর network namespace-এ থাকা container-এর নিজস্ব interface নেই। port Gluetun-এ publish করুন এবং tunnel-এর বাইরে দরকারি subnet-ই শুধু firewall-এ খুলুন।
কোনো container gluetun-এর network-এ যুক্ত হলে কী ঘটে
network_mode: service:gluetun সেট করা container-এর নিজস্ব কোনো network interface থাকে না। এটি gluetun-এর network namespace-এ যুক্ত হয়। তাই port publishing এবং firewall rule আর ওই container-এর বৈশিষ্ট্য থাকে না; এগুলো gluetun service-এর বৈশিষ্ট্য হয়ে যায়। নিচের প্রতিটি বিষয় এই একটি তথ্য থেকেই বোঝা যায়।
Network namespace হলো kernel-এর network stack-এর একটি ব্যক্তিগত অনুলিপি। এতে নিজস্ব interface, routing table, firewall rule এবং listening socket থাকে। Docker ডিফল্টভাবে প্রতিটি container-কে একটি করে namespace দেয়। আপনি যখন network_mode: service:gluetun লিখবেন, Docker সেই ধাপটি বাদ দিয়ে নতুন container-কে gluetun ইতিমধ্যে যে namespace-এর মালিক, তার ভেতরে রাখে। Container-এর নিজস্ব filesystem এবং নিজস্ব /etc/hosts file বজায় থাকে। পরের বিষয়টি গুরুত্বপূর্ণ।
আপনি এটি সরাসরি দেখতে পারেন।
docker inspect -f '{{.HostConfig.NetworkMode}}' qbittorrentএটি container:-এর পরে gluetun container ID দেখায়। সাধারণ container-এর ক্ষেত্রে এখানে bridge দেখা যেত। এই নির্দেশিকাটি gluetun ব্যবহার করে Docker traffic VPN-এর মাধ্যমে route করা অংশের পর থেকে শুরু হচ্ছে: tunnel কাজ করছে, কিন্তু এখন কোনো কিছুই container-এর সঙ্গে যোগাযোগ করতে পারছে না।
gluetun-এ port publish করুন, application-এ নয়
যে service-এ network_mode সেট করা হয়, সেখানে একটি ports: block রাখলে Docker container তৈরি করতে অস্বীকার করে:
Error response from daemon: conflicting options: port publishing and the container type network modeকারণটি সরাসরি। Port publish করার অর্থ হলো একটি NAT (network address translation) rule যোগ করা, যা host port থেকে container-এর নিজস্ব network namespace-এ traffic forward করে। এই container-এর নিজস্ব network namespace নেই। Mapping-টি gluetun service-এ স্থানান্তর করুন। Port number পরিবর্তন হবে না, কারণ shared namespace-এর মধ্যে application এখনও ওই port-এই listening করছে।
services:
gluetun:
ports:
- "8080:8080/tcp" # qBittorrent web UI
qbittorrent:
network_mode: "service:gluetun"
# no ports: block hereDependent service-এ expose: block রাখাও অর্থহীন। সেখানে networks: block থাকলে Compose সরাসরি থেমে যায়। Compose জানায় যে service-টি পরস্পরবিরোধী network_mode এবং networks ঘোষণা করেছে এবং file-টি একেবারেই load করতে অস্বীকার করে।
এর একটি পরবর্তী প্রভাব আছে। Namespace-এর প্রতিটি container একই port space share করে। তাই default হিসেবে 8080 ব্যবহার করা দুটি application পরস্পরের সঙ্গে সংঘর্ষে জড়ায়। দ্বিতীয়টি start হওয়ার সময় address already in use error দিয়ে ব্যর্থ হয়। নিজের configuration-এ একটি application-এর port পরিবর্তন করুন। উদাহরণ হিসেবে LinuxServer qBittorrent image-এর WEBUI_PORT variable পরিবর্তন করতে পারেন। এরপর gluetun-এ নতুন number-টি publish করুন।
gluetun-এর পেছনের container-গুলো কীভাবে একে অপরের সঙ্গে যোগাযোগ করে?
namespace-এর ভিতরে তারা ইতিমধ্যে একই loopback interface ভাগ করে। gluetun-এর পেছনে থাকা একটি container কোনো Docker network ব্যবহার না করেই 127.0.0.1:<port>-এ তার sibling container-এ পৌঁছাতে পারে।
namespace-এর বাইরে থেকে container-টির কোনো name থাকে না। Docker-এর embedded DNS কোনো service name-কে user defined network-এ থাকা সেই service-এর address-এ resolve করে, কিন্তু এই container-এর কোনো network-এ address নেই। তাই Sonarr-এর মতো সাধারণ container http://qbittorrent:8080-এ torrent client-এ পৌঁছাতে পারে না। এটি http://gluetun:8080-এ পৌঁছায়, কারণ socket-টি gluetun-এর namespace-এ gluetun-এর address-এ listening করছে। যারা Docker Compose network এবং service name কীভাবে কাজ করে জানেন এবং সাধারণ naming এখানে প্রযোজ্য হবে বলে আশা করেন, তাদের কাছে এটি আশ্চর্যজনক হতে পারে। Host-এ কিছু publish না করেও এটি কাজ করে, কারণ উভয় container একই Compose network-এ রয়েছে।
অন্য কিছু debug করার আগে DNS পরীক্ষা করুন। Gluetun নিজস্ব resolver চালায় এবং নিজের container-এ /etc/resolv.conf পুনর্লিখন করে। কিন্তু /etc/resolv.conf প্রতি container-এর জন্য আলাদা file। তাই gluetun যে file লিখেছে, আপনার application সেটি পড়ে না।
docker exec qbittorrent cat /etc/resolv.confDocker host-এ চলমান service-এ কীভাবে পৌঁছাবেন?
host.docker.internal ব্যবহার করুন। এখানে দুটি ভিন্ন জায়গায় দুটি setting দিতে হয়, কারণ দুটি ভিন্ন বিষয় ঠিক করতে হবে।
প্রথমে নাম নির্ধারণ করুন। /etc/hosts প্রতি container-এর জন্য আলাদা, তাই extra_hosts entry-টি gluetun-এ নয়, application container-এ দিতে হবে।
prowlarr:
network_mode: "service:gluetun"
extra_hosts:
- "host.docker.internal:host-gateway"host-gateway একটি বিশেষ value, যা Docker host-এর নিজস্ব internal address দিয়ে প্রতিস্থাপন করে। সাধারণ Linux Docker install-এ এটি docker0 bridge-এর address, সাধারণত 172.17.0.1। VPS-এ ip -4 addr show docker0 চালিয়ে আপনার address নিশ্চিত করুন। Docker Desktop নিজে থেকেই এই নাম resolve করে। তাই laptop-এ লেখা guide-গুলোতে extra_hosts line বাদ থাকে, কিন্তু একই file server-এ ব্যর্থ হয়।
এরপর route নির্ধারণ করুন। শুধু নাম যোগ করলে container কোন address ব্যবহার করবে তা জানা যায়। Packet এখনও gluetun-এর default route দিয়ে বের হয়, যা tunnel। gluetun-এর firewall সেটি drop করে। এর লক্ষণ হলো connection ঝুলে থাকার পর timeout হওয়া, refused হওয়া নয়। Refusal-এর অর্থ packet পৌঁছেছে এবং কোনো service প্রত্যাখ্যানের উত্তর দিয়েছে। Timeout-এর অর্থ packet পৌঁছায়নি।
gluetun:
environment:
- FIREWALL_OUTBOUND_SUBNETS=172.17.0.1/32এরপর host service-টি সত্যিই ওই address-এ listening করছে কি না পরীক্ষা করুন। শুধু 127.0.0.1-এ bind করা PostgreSQL server কোনো container থেকেই, tunnel থাকুক বা না থাকুক, পৌঁছানো যায় না। কারণ namespace-এর ভিতরের 127.0.0.1 সেই namespace-এর নিজস্ব loopback। এর পরিবর্তে 172.17.0.1-এ bind করুন। এতে public interface-এ না খুলেই container থেকে connection গ্রহণ করা যায়। Host-এ ss -lntp | grep 5432 চালিয়ে যাচাই করুন।
FIREWALL_OUTBOUND_SUBNETS আসলে কী পরিবর্তন করে
gluetun-এর documentation-এ এটিকে এমন subnet-গুলোর comma-separated তালিকা হিসেবে বর্ণনা করা হয়েছে, যেগুলোতে gluetun এবং তার network stack ব্যবহার করা container-গুলো access করতে পারে। এতে firewall এবং routing—দুই ধরনের পরিবর্তন হয় বলেও উল্লেখ করা আছে। দুই দিকই গুরুত্বপূর্ণ। তালিকাভুক্ত প্রতিটি subnet-এর জন্য gluetun Docker bridge gateway-এর মাধ্যমে একটি route যোগ করে। ফলে ওই address-গুলোর packet tunnel-এর পরিবর্তে eth0 দিয়ে বের হয়। gluetun ওই subnet-গুলোর জন্য firewall-ও খুলে দেয়। কারণ VPN server-এর উদ্দেশে নয়—এমন outbound traffic gluetun অন্যথায় drop করে।
কমাগুলোর পরে কোনো space না দিয়ে value লিখুন।
- FIREWALL_OUTBOUND_SUBNETS=172.17.0.1/32,192.168.1.0/24,100.64.7.9/32দুটি বিষয় সহজেই চোখ এড়িয়ে যায়। এটি namespace-level setting। তাই এটি শুধু আপনার নির্দিষ্ট container-এ নয়, gluetun-এর পেছনে থাকা প্রতিটি container-এ প্রযোজ্য। এটি কেবল outbound traffic-এর জন্যও প্রযোজ্য। অর্থাৎ container যে connection শুরু করে, এটি তা নিয়ন্ত্রণ করে। কোনো published port-এ আসা connection ভিন্ন path ব্যবহার করে। তাই তার জন্য এখানে কোনো entry প্রয়োজন হয় না।
Tailscale peer থেকে web UI-তে পৌঁছানো
Tailscale প্রতিটি মেশিনকে 100.64.0.0/10-এর একটি ঠিকানা দেয়। এই range carrier-grade NAT-এর জন্য সংরক্ষিত। দুই দিকের সংযোগের জন্য আলাদা ব্যবস্থা প্রয়োজন।
Inbound দিকটি সহজ। gluetun-এ 8080:8080 publish করলে host-এর সব address-এ ওই port bind হয়। host-এর tailscale0 interface-ও সেই address-গুলোর একটি। তাই কোনো peer http://<machine-name>:8080 খুললে container-এ পৌঁছাতে পারে। এই path-এ gluetun-এর কোনো ভূমিকা নেই, কারণ Docker-এর NAT rule host-এ, namespace-এর বাইরে প্রয়োগ হয়।
UI-তে শুধু tailnet-এর মাধ্যমে পৌঁছানো যাবে এমনভাবে port bind করতে হলে সেটিকে সব address-এর পরিবর্তে host-এর Tailscale address-এ bind করুন।
ports:
- "100.101.102.103:8080:8080/tcp"host-এ tailscale ip -4 চালিয়ে ওই address খুঁজে নিন। এখানে firewall rule-এর চেয়ে binding বেশি শক্তিশালী নিয়ন্ত্রণ দেয়, কারণ public interface-এ port-টি আদৌ খোলা হয় না। এটি Docker যেভাবে ufw এড়িয়ে সরাসরি port publish করে সেই সমস্যাটিও এড়ায়।
Outbound দিকেই FIREWALL_OUTBOUND_SUBNETS আবার প্রাসঙ্গিক হয়। কোনো container-কে peer-এ connection করতে হলে সেই peer-এর address যোগ করুন। পুরো /10-এর পরিবর্তে প্রতিটি peer-এর জন্য একটি /32 ব্যবহার করাই ভালো। container host-এর resolver ব্যবহার করে না বলে তার ভেতরে MagicDNS name resolve হবে না। তাই numeric 100.x address ব্যবহার করুন অথবা extra_hosts line দিয়ে সেটি নির্দিষ্ট করে দিন। Headscale দিয়ে নিজের Tailscale control server চালালেও একই নিয়ম প্রযোজ্য।
সাধারণ কাঠামোর জন্য একটি সম্পূর্ণ compose file
VPN-এর আড়ালে একটি download client, শুধু tailnet-এ সাড়া দেওয়া দুটি web UI, এবং host-এ চলমান PostgreSQL database পড়ে এমন একটি container।
services:
gluetun:
image: qmcgaw/gluetun:latest
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
ports:
- "127.0.0.1:8000:8000/tcp" # gluetun control server, host only
- "100.101.102.103:8080:8080/tcp" # qBittorrent UI, tailnet only
- "100.101.102.103:9696:9696/tcp" # Prowlarr UI, tailnet only
volumes:
- ./gluetun:/gluetun
environment:
- VPN_SERVICE_PROVIDER=mullvad
- VPN_TYPE=wireguard
- WIREGUARD_PRIVATE_KEY=${WIREGUARD_PRIVATE_KEY}
- WIREGUARD_ADDRESSES=${WIREGUARD_ADDRESSES}
- SERVER_CITIES=Amsterdam
- FIREWALL_OUTBOUND_SUBNETS=172.17.0.1/32,100.64.7.9/32
- TZ=Europe/Amsterdam
restart: unless-stopped
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
network_mode: "service:gluetun"
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Amsterdam
- WEBUI_PORT=8080
volumes:
- ./qbittorrent:/config
- /srv/downloads:/downloads
depends_on:
gluetun:
condition: service_healthy
restart: unless-stopped
prowlarr:
image: lscr.io/linuxserver/prowlarr:latest
network_mode: "service:gluetun"
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Amsterdam
- PROWLARR__POSTGRES__HOST=host.docker.internal
- PROWLARR__POSTGRES__PORT=5432
- PROWLARR__POSTGRES__USER=prowlarr
- PROWLARR__POSTGRES__PASSWORD=${PROWLARR_DB_PASSWORD}
- PROWLARR__POSTGRES__MAINDB=prowlarr-main
- PROWLARR__POSTGRES__LOGDB=prowlarr-log
volumes:
- ./prowlarr:/config
depends_on:
gluetun:
condition: service_healthy
restart: unless-stoppedproduct name-এর বদলে কাঠামোটি লক্ষ্য করুন। দুটি UI-ই gluetun-এ publish করা এবং host-এর tailnet address-এ bind করা, তাই এগুলো Tailscale-এ সাড়া দেয় এবং অন্য কোথাও নয়। শুধু Prowlarr-এ extra_hosts line আছে, কারণ Prowlarr-ই host.docker.internal resolve করে। FIREWALL_OUTBOUND_SUBNETS-এ দুটি single address দেওয়া হয়েছে: host-এর Docker bridge address, যাতে Prowlarr database connection খুলতে পারে, এবং একটি tailnet peer।
PostgreSQL server-টি ইচ্ছাকৃতভাবে file-এ নেই। এটি VPS-এ একটি সাধারণ system service হিসেবে চলে এবং 172.17.0.1:5432-এ listen করে। এটি Docker Compose-এ একটি arr stack-এর মতোই একই layering, তবে database-টি Docker-এর বাইরে রাখা হয়েছে।
WireGuard private key compose file-এর বাইরে রাখুন। ${WIREGUARD_PRIVATE_KEY}-এ এর পাশের একটি .env file থেকে মান পড়া হয়; এই পদ্ধতিটি Docker Compose-এর env file ও secret-এ ব্যাখ্যা করা হয়েছে। condition: service_healthy clause-এ gluetun image-এর সঙ্গে থাকা healthcheck ব্যবহার করা হয়েছে, তাই tunnel নিজেকে চালু অবস্থায় report না করা পর্যন্ত কোনো কিছু start হয় না। Compose healthcheck-এ সাধারণ কাঠামোটি ব্যাখ্যা করা হয়েছে।
:::detailsসব address-এ publish করা, শুধু tailnet-এ নয়0.0.0.0-এর address prefix এবং port bind সরিয়ে দিন। এতে VPS-এর public IP-ও অন্তর্ভুক্ত হবে। এটি কেবল আপনার নিয়ন্ত্রণাধীন firewall-এর পেছনে করুন, এবং আগে উপরের ufw নোটটি পড়ুন।
ports:
- "8080:8080/tcp":::
নিশ্চিত করুন যে tunnel এখনও traffic বহন করছে
একই request দুবার চালান—একবার namespace-এর ভেতর থেকে এবং একবার host থেকে—তারপর ফলাফল তুলনা করুন।
docker run --rm --network=container:gluetun curlimages/curl:latest -s https://api.ipify.org
curl -s https://api.ipify.orgপ্রথম কমান্ডে আপনার VPN provider-এর exit address দেখানো উচিত। দ্বিতীয় কমান্ডে VPS address দেখানো উচিত। দুটির ফল একই হলে container-এর traffic tunnel-এর মধ্য দিয়ে যাচ্ছে না। এই guide-এর অন্য কোনো সমাধান প্রয়োগ করার আগে সেটি ঠিক করতে হবে।
Routing table দেখায় কোন traffic tunnel-এর বাইরে যাচ্ছে এবং কোনটি tunnel ব্যবহার করছে।
docker run --rm --network=container:gluetun alpine:3.22 ip route showDefault route-টি tunnel interface, tun0-এর দিকে নির্দেশ করা উচিত। এর নিচে FIREWALL_OUTBOUND_SUBNETS-এর প্রতিটি entry-এর জন্য একটি করে route দেখতে পাবেন, যা Docker bridge gateway-এর দিকে নির্দেশ করে। eth0 দিয়ে বাইরে যাওয়া অন্য যেকোনো route VPN এড়িয়ে যাওয়া traffic নির্দেশ করে।
Gluetun-এর control server port 8000-এ, /v1/publicip/ip-এ একই public IP দেখায়। সাম্প্রতিক version-গুলোতে control server route-এর জন্য authentication configure করা প্রয়োজন। তাই control server-এর ওপর নির্ভর করার আগে এটি configure করুন।
ভুল subnet তৈরি করা একটি ফাঁকফোকর
FIREWALL_OUTBOUND_SUBNETS হলো firewall-এ ইচ্ছাকৃতভাবে তৈরি করা একটি ফাঁক। তাই ফাঁকের আকারই ঝুঁকির পরিমাণ নির্ধারণ করে। এটিকে অতিরিক্ত বড় করার 4টি উপায় আছে:
0.0.0.0/0tunnel-এর বাইরে থাকা সবকিছু পাঠায়। উপরের 2টি IP check প্রথমবার চালানোর সময়ই এটি শনাক্ত করে, কারণ উভয় check একই address ফেরত দেবে।- target-এর চেয়ে প্রশস্ত একটি range ব্যবহার করা।
10.0.1.7-এ থাকা একটি machine-এ পৌঁছাতে10.0.0.0/8খুললে ওই range-এ কোনো torrent peer যে address ঘোষণা করতে পারে, তার প্রতিটিও খুলে যায়।10.0.1.7/32লিখুন। - tunnel-এর নিজস্ব address-এর সঙ্গে overlap করা একটি range ব্যবহার করা। gluetun documentation সতর্ক করে যে এতে gluetun VPN traffic bridge-এর মধ্য দিয়ে পাঠাতে শুরু করে, ফলে port forwarding কাজ করে না। কোনো private range খোলার আগে আপনার
WIREGUARD_ADDRESSESvalue পরীক্ষা করুন। - Tailscale-এর জন্য
100.64.0.0/10ব্যবহার করা। এর ফলে মোটামুটি 4 million address খুলে যায়, যাতে একটি peer-এ পৌঁছানো যায়। প্রয়োজনীয় peer-গুলো/32entry হিসেবে তালিকাভুক্ত করুন।
মনে রাখবেন, এই setting পুরো namespace-এর ক্ষেত্রে প্রযোজ্য। একটি indexer যাতে host service-এ পৌঁছাতে পারে, সেই উদ্দেশ্যে কোনো subnet খুললে একই namespace share করা torrent client-এর জন্যও একই subnet খুলে যায়। এই variable-এ প্রতিটি পরিবর্তনের পরে public IP check আবার চালান, কারণ পরিবর্তনটি আপনার উদ্দেশ্য অনুযায়ী কাজ করেছে কি না তা দেখানোর একমাত্র test এটিই।
gluetun restart করলে কী নষ্ট হয়
namespace-এর মালিক gluetun। তাই gluetun-এর lifecycle-ই namespace-এর lifecycle। gluetun বন্ধ থাকা অবস্থায় নির্ভরশীল container চালু করতে গেলে সঙ্গে সঙ্গে ব্যর্থ হয়:
Error response from daemon: cannot join network of a non running containergluetun-কে একই অবস্থানে restart করা তুলনামূলকভাবে নীরব ব্যর্থতা তৈরি করে। নির্ভরশীল container-গুলো চলতে থাকে, কিন্তু তাদের সংযুক্ত namespace-টি তাদের নিচে পুনর্নির্মিত হয়। ফলে docker ps সবকিছু সুস্থ দেখায়, কিন্তু কোনো service সাড়া দেয় না। gluetun service-এ যেকোনো পরিবর্তনের পরে শুধু একটি অংশ restart না করে পুরো group recreate করুন।
docker compose up -d --force-recreateimage update-এর ক্ষেত্রেও একই নিয়ম প্রযোজ্য। নতুন gluetun image pull করে শুধু ওই service recreate করলে অন্য container-গুলো এমন একটি namespace-এর দিকে নির্দেশ করতে থাকে, যেটি আর নেই।
FAQ
Docker কেন "port publishing and the container type network mode" বার্তা দেখায়?
কারণ কোনো service-এ এখনও ports: block আছে, অথচ একই service-এ network_mode: service:gluetun সেট করা হয়েছে। Port publish করলে একটি NAT rule যোগ হয়, যা host-এর একটি port থেকে container-এর নিজস্ব network namespace-এ traffic forward করে। কিন্তু এই mode-এ container-এর নিজস্ব network namespace থাকে না। ওই service থেকে ports: block মুছে gluetun service-এ একই mapping যোগ করুন। Application এখনও shared namespace-এর ওই port-এ listen করছে, তাই port number পরিবর্তন হবে না।
gluetun-এর পেছনে থাকা কোনো service-এ অন্য container কীভাবে পৌঁছাবে?
একই namespace-এর container-গুলো 127.0.0.1 ব্যবহার করে একে অপরের কাছে পৌঁছায়। Namespace-এর বাইরে থাকা container-গুলো gluetun service name ব্যবহার করে। তাই http://gluetun:8080 কাজ করে, কিন্তু http://qbittorrent:8080 কাজ করে না। Application container-এর কোনো Docker network-এ address নেই। তাই embedded DNS server তার name resolve করার মতো কোনো তথ্য পায় না। উভয় container একই Compose network share করলে এর জন্য port publishing প্রয়োজন হয় না।
FIREWALL_OUTBOUND_SUBNETS-এ কী লিখব?
gluetun-এর পেছনে থাকা container-কে যে address-গুলোতে connection শুরু করতে হবে, শুধু সেগুলোই যতটা সম্ভব সংকীর্ণভাবে লিখুন। একটি নির্দিষ্ট machine হলো /32। সাধারণ দুটি entry হলো Docker host-এর জন্য 172.17.0.1/32 এবং যে Tailscale peer-এ connection করেন, প্রতিটির জন্য একটি /32। কখনও 0.0.0.0/0 যোগ করবেন না। আপনার VPN-এর নিজস্ব tunnel address-এর সঙ্গে overlap করে এমন কোনো range-ও যোগ করবেন না। Published port-এ inbound connection-এর জন্য এখানে কোনো entry প্রয়োজন নেই।
Container আমার Tailscale MagicDNS name resolve করতে পারে না কেন?
MagicDNS host-এর resolver-কে Tailscale-এর DNS server-এ নির্দেশ করে কাজ করে। Container host-এর resolver ব্যবহার করে না। এটি তার নিজস্ব /etc/resolv.conf-এ নির্ধারিত DNS configuration ব্যবহার করে। gluetun-এর পেছনে থাকলে সেটি gluetun-এর DNS setup। docker exec <container> cat /etc/resolv.conf দিয়ে বিষয়টি নিশ্চিত করুন। Peer-এর numeric 100.x address ব্যবহার করুন, অথবা ওই container-এ একটি extra_hosts entry দিয়ে name নির্দিষ্ট করে দিন।
Traffic এখনও VPN-এর মধ্য দিয়ে যাচ্ছে কি না কীভাবে নিশ্চিত করব?
Namespace-এর ভেতর থেকে একটি request পাঠান এবং host থেকেও একই request পাঠান। এরপর দুইটির উত্তর তুলনা করুন। docker run --rm --network=container:gluetun curlimages/curl:latest -s https://api.ipify.org-এ আপনার VPN provider-এর exit address ফেরত আসা উচিত। VPS-এ curl -s https://api.ipify.org চালালে VPS address ফেরত আসা উচিত। দুইটি উত্তর একই হলে tunnel container-এর traffic বহন করছে না। FIREWALL_OUTBOUND_SUBNETS-এ প্রতিটি পরিবর্তনের পরে এই পরীক্ষা আবার চালান।