Docker VPN কন্টেইনারের মাধ্যমে হোস্ট ট্রাফিক কীভাবে রাউট করবেন
VPN কন্টেইনার হলো নেটওয়ার্ক নেমস্পেস, প্রক্সি নয়। শেয়ার করা netns, সত্যিকারের SOCKS লিসেনার বা রাউটেড গেটওয়ে বেছে নিন, তারপর এক্সিট পথ যাচাই করুন।
আপনার টানেল কন্টেইনার কাজ করছে, docker compose exec vpn curl -s https://ifconfig.me প্রোভাইডারের ঠিকানা ফেরত দিচ্ছে, তবু আপনার ডেস্কটপের ব্রাউজার এখনও আপনার ISP দিয়ে বেরোচ্ছে। এই ফাঁক প্রত্যাশিত। যে কন্টেইনার VPN ক্লায়েন্ট চালায় সে একটি নেটওয়ার্ক নেমস্পেস, রুট ও একটি টানেল ইন্টারফেস ধরে রাখে, HTTP বা SOCKS বোঝে এমন কিছু নয়; তার উপর পোর্ট প্রকাশ করে এমন লিসেনার বানানো যায় না যা কখনও ছিল না।
ক্লায়েন্ট কোথায় চলে তা নকশা ঠিক করে। পাশের কন্টেইনার টানেলের নেমস্পেসে ঢুকতে পারে, ডেস্কটপ অ্যাপ্লিকেশন পারে না, আর রাউটারের প্রক্সি ফিল্ড নয়, রুট দরকার। ম্যাপিং ভুল হলে লক্ষণ একই: সংযোগ প্রত্যাখ্যান, নয়তো চুপচাপ পুরোনো পথে যাওয়া ট্রাফিক।
ক্লায়েন্ট যেখানে চলে সেই অনুযায়ী ব্যবস্থা মেলান
Compose সম্পাদনার আগে একটি প্রশ্ন করুন: ক্লায়েন্টকে কি VPN কন্টেইনারের নেটওয়ার্ক নেমস্পেসের ভিতরে চালু করা যায়? ইতিমধ্যে Linux কন্টেইনার হিসেবে চলা যেকোনো কিছু পারে। আপনার ডেস্কে থাকা ব্রাউজার, IDE বা CLI পারে না, কারণ তার প্রক্সি সেটিং প্রোটোকল সেবা আশা করে, নেমস্পেস নয়।
| Client | Arrangement | What must already exist |
|---|---|---|
| Another Compose service | Shares the vpn namespace via network_mode: service:vpn | A working tunnel and correct start order |
| Host browser, IDE or CLI | Proxy listener inside the namespace, published to host loopback | A configured SOCKS or HTTP proxy and its access rules |
| Router, VM or phone | The container as a layer-3 gateway | Forwarding, NAT and a return route |
এই তিনটি মেশে না। কন্টেইনারের ব্রিজ ঠিকানায় দেখানো HTTP প্রক্সি ফিল্ড কোনো কিছুতে পৌঁছায় না যদি সেখানে প্রক্সি না শোনে, আর প্রক্সি লিসেনার রাউটারের ট্রাফিক রাউট করে না। আগে সিদ্ধান্ত নিন, তারপর মিলিয়ে সংশ্লিষ্ট অংশ অনুসরণ করুন।
পাশের কন্টেইনারের সাথে টানেল নেমস্পেস শেয়ার করুন
এটি সবচেয়ে সস্তা বিকল্প কারণ এতে কোনো প্রক্সি প্রোটোকল নেই। অ্যাপটি vpn সেবার নেমস্পেসে যোগ দেয় এবং তার ইন্টারফেস, রুট ও পোর্ট স্পেস উত্তরাধিকারে পায়:
services:
vpn:
image: your-vpn-client
cap_add:
- NET_ADMIN
healthcheck:
test: ["CMD-SHELL", "ip link show tun0 >/dev/null"]
interval: 10s
retries: 5
app:
image: your-app
network_mode: service:vpn
depends_on:
vpn:
condition: service_healthyনেমস্পেস অন্য সেবার হওয়ার তিনটি সীমাবদ্ধতা আসে। অ্যাপ নিজের networks কী পায় না, কারণ যোগ দেওয়ার মতো নেমস্পেস তার নেই। পোর্ট প্রকাশ vpn-এর উপর, কারণ নেমস্পেস সেখানেই থাকে। আর vpn পুনরায় তৈরি করলে অ্যাপ যে নেমস্পেসে যোগ দিয়েছিল তা ধ্বংস হয়, তাই docker compose up -d --force-recreate vpn আপনাকে app-ও পুনরায় তৈরি করতে ছাড়ে; সাধারণ রিস্টার্ট সবসময় যথেষ্ট নয়। Compose সেবা রেফারেন্স এই ব্যবস্থা ও এর পোর্ট প্রকাশের সীমাবদ্ধতা কভার করে।
রিজলভার সঙ্গে আসবে ধরে নেবেন না। /etc/resolv.conf প্রতি-কন্টেইনার ফাইল, নেটওয়ার্ক নেমস্পেসের অংশ নয়, তাই অ্যাপের প্যাকেট টানেল দিয়ে বেরোলেও সে হোস্টের রিজলভারকে জিজ্ঞাসা করতে পারে। এটি কন্টেইনারের ভিতর থেকে পড়ুন এবং ব্যক্তিগত নাম টানেল দিয়ে রিজলভ করতে হলে অ্যাপে dns: সেট করুন।
docker compose exec app ip route
docker compose exec app cat /etc/resolv.conf
docker compose exec app curl -s https://ifconfig.meরুট তালিকায় টানেল ইন্টারফেস থাকলে এবং ঠিকানা প্রোভাইডারের হলে অ্যাপ টানেলের ভিতরে। ইন্টারফেস না থাকলে vpn-এর টানেল হওয়ার আগেই app চালু হয়েছে, তাই vpn সুস্থ রিপোর্ট করলে app পুনরায় তৈরি করুন।
হোস্ট ক্লায়েন্টের জন্য নেমস্পেসে সত্যিকারের প্রক্সি লিসেনার রাখুন
ডেস্কটপ ব্রাউজার নেমস্পেসে যোগ দিতে পারে না, তাই টানেলকে সেবা হিসেবে প্রকাশ করতে হবে। vpn নেমস্পেসের ভিতরে আসল SOCKS বা HTTP প্রক্সি চালান এবং কেবল তার পোর্ট প্রকাশ করুন:
services:
vpn:
ports:
- "127.0.0.1:1080:1080"
proxy:
image: your-proxy
network_mode: service:vpn
command: ["--socks", "0.0.0.0:1080"]হোস্টের দিকের ঠিকানাই সেই ম্যাপিংয়ের গুরুত্বপূর্ণ অর্ধেক। বাঁ দিকের 127.0.0.1:1080 লিসেনারকে আপনার LAN থেকে দূরে রাখে; খালি "1080:1080" আপনার মেশিনে পৌঁছাতে পারে এমন প্রতিটি ডিভাইসের জন্য খোলা প্রক্সি প্রকাশ করে।
কন্টেইনারের দিকের নিজের ফাঁদ আছে। প্রকাশিত পোর্ট কন্টেইনারের ব্রিজ ঠিকানায় পৌঁছায়, তার loopback-এ নয়, তাই নেমস্পেসের ভিতরে --socks 127.0.0.1:1080 দিয়ে চালু প্রক্সি পাশের কন্টেইনারগুলোর সংযোগ নেয় এবং প্রকাশিত পোর্ট দিয়ে আসা সব কিছু প্রত্যাখ্যান করে। এটিকে 0.0.0.0-এ বাঁধুন এবং বিচ্ছিন্নতার জন্য হোস্টের দিকের loopback বাইন্ডের উপর নির্ভর করুন। একই নিয়ম প্রক্সি কনফিগ ফাইলের লিসেন ঠিকানার ক্ষেত্রেও প্রযোজ্য।
তারপর ঠিক করুন নাম কোথায় রিজলভ হবে। curl-এ --socks5 হোস্টনেম স্থানীয়ভাবে রিজলভ করে আর --socks5-hostname নামটি প্রক্সিতে পাঠায়; ব্রাউজার একই সুইচ অন্য লেবেলে দেখায়। স্থানীয় রিজলভ পৃষ্ঠা টানেল দিয়ে লোড হলেও লুকআপ ফাঁস করে।
ফেরার রুট থাকলেই কন্টেইনারকে গেটওয়ে হিসেবে ধরুন
রাউটার, VM ও ফোন HTTP প্রক্সি ফিল্ড ব্যবহার করবে না, আর কিছু অ্যাপ্লিকেশন প্রক্সি ভেরিয়েবল পুরোপুরি উপেক্ষা করে। তাদের ট্রাফিক রাউট করা মানে লেয়ার 3: কন্টেইনার প্যাকেট ফরওয়ার্ড করে এবং টানেল ইন্টারফেসে ঠিকানা অনুবাদ করে।
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADEদুটি জিনিস সহজে বাদ পড়ে। ক্লায়েন্টের এমন রুট দরকার যা তার ডিফল্ট গেটওয়েকে এই হোস্টে পাঠায়, আর উত্তরকে ফেরার পথ খুঁজতে হবে — হয় আপস্ট্রিম রাউটারে স্ট্যাটিক রুট দিয়ে, নয়তো ক্লায়েন্টের দিকে থাকা ইন্টারফেসে NAT দিয়ে। এর একটি না থাকলে টানেল অনুরোধটি বাইরে নিয়ে যায় আর উত্তর হারিয়ে যায়।
এর প্রভাবের পরিসরও সবচেয়ে বড়। পুরো LAN-এর জন্য গেটওয়ে হওয়া হোস্ট প্রতিটি ভুল কনফিগার করা ক্লায়েন্টকে আপনার VPN অ্যাকাউন্ট দিয়ে পাঠায়, আর টানেল পড়ে গেলে kill switch-এর উপর নির্ভর করে হয় LAN অন্ধকার হয়, নয়তো ISP-তে ফিরে যায়।
এক্সিট পথ যাচাই করুন, তারপর ক্রমে ফিরিয়ে নিন
এই ক্রমে পরীক্ষা করুন এবং প্রথম ব্যর্থতায় থামুন: নেমস্পেসের ভিতরের এক্সিট ঠিকানা, হোস্ট থেকে প্রক্সি দিয়ে এক্সিট ঠিকানা, তারপর ব্যক্তিগত হোস্টের নাম রিজলভ।
docker compose exec vpn curl -s https://ifconfig.me
curl -s -x socks5h://127.0.0.1:1080 https://ifconfig.me
curl -s -x socks5h://127.0.0.1:1080 http://internal.example/healthপ্রথম দুটি ঠিকানা প্রোভাইডারের সাথে মিলতে হবে, আর তৃতীয়টি নাম-ত্রুটিতে ব্যর্থ না হয়ে প্রক্সি দিয়ে রিজলভ হওয়া উচিত। প্রথম লাইন মিলে গিয়ে দ্বিতীয় লাইন ব্যর্থ হলে বোঝায় লিসেনার বা প্রকাশিত পোর্ট ভুল, টানেল নয়।
ফিরিয়ে নেওয়া সেটআপের উল্টো। শেল প্রোফাইল ও যেকোনো systemd ইউনিট থেকে প্রক্সি এনভায়রনমেন্ট ভেরিয়েবল সরান, তারপর স্ট্যাক নামিয়ে দিন যাতে শেয়ার করা নেমস্পেস তার মালিকের সাথে অদৃশ্য হয়। প্রক্সি সেবা মুছে ফেলার আগে প্রকাশিত পোর্ট মুছুন, নইলে হোস্টে এমন loopback লিসেনার থেকে যায় যা কেউ পড়ে না।
এগিয়ে যাওয়ার আগে চারটি বিষয় নিশ্চিত করুন: আপনার আগ্রহের ক্লায়েন্ট সত্যিই টানেলে পৌঁছায়, কেবল নেমস্পেসের মালিক পোর্ট প্রকাশ করে, ব্যক্তিগত নাম আপনার ইচ্ছামতো জায়গায় রিজলভ হয়, এবং loopback নয় এমন হোস্ট ঠিকানায় কিছু শোনে না। এগুলোর প্রতিটি উৎপাদনে নিঃশব্দে ব্যর্থ হয়, আর প্রতিটি উপরের এক লাইনের পরীক্ষা।