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 দেখাত। এই guide-টি gluetun ব্যবহার করে Docker traffic একটি VPN-এর মাধ্যমে route করা অংশের পর থেকে শুরু হচ্ছে: tunnel কাজ করছে, কিন্তু এখন কোনো কিছুই container-এর সঙ্গে যোগাযোগ করতে পারছে না।
gluetun-এ port publish করুন, application-এ নয়
network_mode সেট করে এমন service-এ 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 hereনির্ভরশীল service-এ expose: block রাখারও কোনো কার্যকারিতা নেই। সেখানে networks: block রাখলে Compose সরাসরি থেমে যায়। Compose জানায়, service-টি পরস্পর-বিরোধী network_mode এবং networks ঘোষণা করেছে, এবং file-টি সম্পূর্ণ load করতে অস্বীকার করে।
এর একটি প্রভাব পরে দেখা যায়। Namespace-এর প্রতিটি container একই port space ভাগ করে। তাই default হিসেবে 8080 ব্যবহার করা দুটি application-এর মধ্যে সংঘর্ষ হয়। দ্বিতীয়টি start হওয়ার সময় address already in use error দিয়ে ব্যর্থ হয়। একটি application-এর নিজস্ব configuration-এ 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-এ পৌঁছাতে পারে।
Namespace-এর বাইরে containerটির কোনো নাম থাকে না। 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 ফাইল। তাই gluetun যে ফাইল লিখেছে, আপনার application সেই ফাইল পড়ে না।
docker exec qbittorrent cat /etc/resolv.confDocker host-এ চলমান service-এ কীভাবে পৌঁছাবেন?
host.docker.internal ব্যবহার করুন। এতে দুটি ভিন্ন জায়গায় দুটি setting দিতে হয়, কারণ দুটি ভিন্ন বিষয় ঠিক করতে হয়।
প্রথমে name দিতে হবে। /etc/hosts প্রতি container-এর জন্য আলাদা, তাই extra_hosts entry-টি application container-এ দিতে হবে, gluetun-এ নয়।
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 নিজে থেকেই এই name resolve করে। তাই laptop-এ লেখা guide-গুলোতে extra_hosts line বাদ থাকে, এবং একই file server-এ ব্যর্থ হয়।
এরপর route দিতে হবে। শুধু name যোগ করলে 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 অনুযায়ী, এটি comma-separated subnet-এর তালিকা। gluetun এবং তার network stack ব্যবহার করা container-গুলো এই subnet-এ access করতে পারে। Documentation-এ আরও বলা হয়েছে, এতে firewall এবং routing পরিবর্তন হয়। উভয় দিকই গুরুত্বপূর্ণ। তালিকাভুক্ত প্রতিটি subnet-এর জন্য gluetun Docker bridge gateway-এর মাধ্যমে একটি route যোগ করে। ফলে ওই address-গুলোর জন্য packet tunnel-এর পরিবর্তে eth0 দিয়ে বাইরে যায়। gluetun ওই subnet-গুলোর জন্য firewall-এ traffic অনুমোদনও করে। কারণ gluetun সাধারণত VPN server-এর দিকে না যাওয়া outbound traffic 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 শুরু করে, এটি সেই connection নিয়ন্ত্রণ করে। Published port-এ আসা connection ভিন্ন path ব্যবহার করে। তাই তার জন্য এখানে কোনো entry প্রয়োজন হয় না।
Tailscale peer থেকে web UI-তে পৌঁছানো
Tailscale প্রতিটি মেশিনকে 100.64.0.0/10-এ একটি address দেয়, যা carrier grade NAT-এর জন্য সংরক্ষিত range। ব্যক্তিগত tailnet-এ এর কোনো খরচ নেই। তবে অন্যদের একই UI-তে access দিতে হলে free plan-এর user ও device limit এই সুবিধা কতদিন বিনামূল্যে থাকবে তা নির্ধারণ করে। Billing মেশিনের বদলে user গণনা করে। তাই paid tailnet-এর প্রকৃত খরচ নির্ভর করে আপনি কতজনকে invite করেন তার ওপর, কতগুলো container তাদের জন্য expose করেন তার ওপর নয়। এই দুই দিকের জন্য আলাদা কাজ করতে হয়।
Inbound দিকটি সহজ। gluetun-এ 8080:8080 publish করলে সেই port host-এর সব address-এ bind হয়। host-এর tailscale0 interface-ও ওই address-গুলোর একটি। তাই কোনো peer http://<machine-name>:8080 খুললে container-এ পৌঁছাতে পারে। এই path-এ gluetun-এর কোনো ভূমিকা নেই। কারণ Docker-এর NAT rule host-এ, namespace-এর বাইরে থাকে।
UI-তে শুধু tailnet-এর মাধ্যমে access দিতে হলে published port-টি সব address-এ নয়, host-এর Tailscale address-এ bind করুন।
ports:
- "100.101.102.103:8080:8080/tcp"host-এ tailscale ip -4 চালিয়ে সেই address খুঁজে নিন। এখানে firewall rule-এর চেয়ে binding বেশি কার্যকর নিয়ন্ত্রণ, কারণ public interface-এ port-টি একেবারেই খোলা হয় না। host ও port ব্যবহার না করে HTTPS name দিয়ে UI-তে পৌঁছাতে চাইলে tailscale serve ওই published port-এর সামনে কাজ করতে পারে। তবে serve ও funnel-এর ক্ষেত্রে শেষ পর্যন্ত কারা access করতে পারে তা আলাদা, এবং দুটির মধ্যে শুধু একটিতে UI tailnet-এর মধ্যেই থাকে। এটি Docker কীভাবে ufw-এর বাইরে সরাসরি port publish করে সেই সমস্যাটিও এড়ায়।
Outbound দিকেই FIREWALL_OUTBOUND_SUBNETS আবার প্রয়োজন হয়। কোনো container-কে peer-এ সংযোগ করতে হলে সেই peer-এর address যোগ করুন। পুরো /10-এর পরিবর্তে প্রতি peer-এর জন্য একটি /32 ব্যবহার করাই ভালো। যে মেশিনে সংযোগ করছেন সেটি যদি কোনো private network-এ থাকে এবং একটি VPS সেই subnet আপনার tailnet-এ advertise করে, তাহলে router-এর নিজস্ব 100.x address-এর পরিবর্তে advertised range তালিকাভুক্ত করুন। Host নিজে ওই route গ্রহণ করেছে কি না সেটিও নিশ্চিত করুন। Container host-এর resolver ব্যবহার করে না, তাই container-এর ভিতরে MagicDNS name resolve হবে না। এজন্য numeric 100.x address ব্যবহার করুন, অথবা extra_hosts line দিয়ে সেটি নির্দিষ্ট করে দিন। Headscale দিয়ে নিজের Tailscale control server চালালেও একই নিয়ম প্রযোজ্য।
সাধারণ কাঠামোর জন্য সম্পূর্ণ compose ফাইল
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 আছে, কারণ host.docker.internal resolve করে Prowlarr container-টি। FIREWALL_OUTBOUND_SUBNETS দুটি single address নির্দিষ্ট করে: host-এর Docker bridge address, যাতে Prowlarr database connection খুলতে পারে, এবং একটি tailnet peer।
PostgreSQL server-টি ইচ্ছাকৃতভাবে ফাইলে রাখা হয়নি। এটি 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 নিজেকে up হিসেবে report না করা পর্যন্ত কোনো কিছু start হয় না। Compose healthcheck-এ সাধারণ কাঠামোটি ব্যাখ্যা করা হয়েছে।
:::detailsশুধু tailnet নয়, প্রতিটি address-এ publish করা0.0.0.0-এর address prefix এবং port bind সরিয়ে দিন; এতে VPS-এর public IP-ও অন্তর্ভুক্ত হবে। এটি কেবল আপনার নিয়ন্ত্রণাধীন firewall-এর পেছনে করুন, এবং আগে উপরের ufw নোটটি পড়ুন।
ports:
- "8080:8080/tcp":::
টানেল এখনো ট্রাফিক বহন করছে কি না নিশ্চিত করুন
একই অনুরোধ দুইবার চালান। একবার 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-এর ট্রাফিক টানেলের মধ্য দিয়ে যাচ্ছে না। এটি ঠিক না করা পর্যন্ত এই গাইডের অন্য কোনো সমাধান কার্যকর হবে না।
Routing table-এ কোন ট্রাফিক টানেলের বাইরে যাচ্ছে এবং কোনটি টানেলের মধ্য দিয়ে যাচ্ছে না, তা দেখা যায়।
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 এড়িয়ে যাচ্ছে।
Gluetun-এর control server port 8000-এ, /v1/publicip/ip-এ একই public IP দেখায়। সাম্প্রতিক version-গুলোতে control server route-এর জন্য authentication configure করা প্রয়োজন। তাই এর ওপর নির্ভর করার আগে authentication সেট আপ করুন।
একটি ভুল subnet তৈরি করা ঝুঁকিপূর্ণ ফাঁক
FIREWALL_OUTBOUND_SUBNETS হলো firewall-এ ইচ্ছাকৃতভাবে তৈরি করা একটি ফাঁক। তাই ফাঁকের আকারই ঝুঁকির পরিমাণ নির্ধারণ করে। এটি অতিরিক্ত বড় করার 4টি উপায়:
0.0.0.0/0tunnel-এর বাইরে সবকিছু পাঠায়। উপরের দুটি IP check প্রথম run-এই এটি শনাক্ত করে, কারণ উভয় check একই address ফেরত দেবে।- লক্ষ্যবস্তুর চেয়ে প্রশস্ত একটি range ব্যবহার করা।
10.0.1.7-এ থাকা একটি machine-এ পৌঁছাতে10.0.0.0/8খুললে ওই range-এ কোনো torrent peer যে address advertise করতে পারে, সেগুলোও খুলে যায়।10.0.1.7/32লিখুন। - এমন একটি range ব্যবহার করা, যা tunnel-এর নিজস্ব address-এর সঙ্গে overlap করে। 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 আবার চালান, কারণ পরিবর্তনটি আপনার উদ্দেশ্য অনুযায়ী কাজ করেছে কি না, তা দেখানোর একমাত্র পরীক্ষা এটিই।
gluetun পুনরায় চালু করলে কী নষ্ট হয়
gluetun namespace-এর মালিকানা ধরে রাখে। তাই gluetun-এর lifecycle-ই namespace-এর lifecycle। gluetun বন্ধ থাকা অবস্থায় নির্ভরশীল container চালু করতে গেলে সঙ্গে সঙ্গে ব্যর্থ হয়:
Error response from daemon: cannot join network of a non running containerজায়গাতেই gluetun পুনরায় চালু করা তুলনামূলকভাবে নীরব ব্যর্থতা ঘটায়। নির্ভরশীল container-গুলো চলতে থাকে, কিন্তু তাদের সংযুক্ত namespace আড়ালে পুনর্গঠিত হয়। ফলে docker ps সবকিছু সুস্থ দেখায়, অথচ কোনো সাড়া পাওয়া যায় না। gluetun service-এ কোনো পরিবর্তন করার পর একটি অংশ পুনরায় চালু না করে পুরো group পুনরায় তৈরি করুন।
docker compose up -d --force-recreateimage update-এর ক্ষেত্রেও একই বিষয় প্রযোজ্য। নতুন gluetun image pull করে শুধু সেই service পুনরায় তৈরি করলে অন্য container-গুলো এমন একটি namespace-এর দিকে নির্দেশ করতে থাকে, যা আর বিদ্যমান নেই।
FAQ
Docker কেন বলে "port publishing and the container type network mode"?
কারণ একই service-এ এখনও একটি ports: block রয়েছে এবং সেখানে 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 যোগ করুন। Port number অপরিবর্তিত থাকবে, কারণ shared namespace-এর ভিতরে application এখনও একই port-এ listening করছে।
gluetun-এর পেছনে থাকা service-এ অন্য container কীভাবে পৌঁছাবে?
একই namespace-এর container-গুলো 127.0.0.1 ব্যবহার করে একে অপরের কাছে পৌঁছায়। এর বাইরে থাকা 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 publish করার প্রয়োজন নেই।
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-এ নির্ধারিত resolver ব্যবহার করে। 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-এ প্রতিটি পরিবর্তনের পরে এই পরীক্ষা আবার চালান।