কেন আপনার LAN একটি VPN ক্লায়েন্টের সেবা পর্যন্ত পৌঁছাতে পারে না
একটি VPN ক্লায়েন্ট এমন সেবা হোস্ট করতে পারে যা LAN খুলতে পারে না। যা অনুপস্থিত থাকে তা সাধারণত ফেরার পথ: একটি রুট, একটি DNAT জোড়া, বা যে SNAT লাইনটি কেউ যোগ করে না।
আপনার টানেল চালু, সেবাটি শুনছে, তবুও অফিসের LAN কিছুই ফেরত পাচ্ছে না। কেউ VPN ভাঙেনি। LAN-এর দিক থেকে ল্যাপটপের টানেল ঠিকানার অস্তিত্বই নেই, যতক্ষণ না কিছু LAN-কে বলে দেয় কীভাবে সেখানে পৌঁছাতে হবে, এবং যে পথে অনুরোধটি গিয়েছিল ঠিক সেই পথেই উত্তরটিকে ফিরে আসতে হবে। আমি দেখেছি মানুষ একটি সম্পূর্ণ ভালো টানেল তিনবার নতুন করে বানিয়েছে, তার আগে কেউ ফেরার পথের দিকে তাকায়নি।
টানেলটিই ভাঙেনি
উভয় প্রান্তই প্রাইভেট রেঞ্জে বসে, এটাই স্বাভাবিক এবং কোনো ভুল কনফিগারেশন নয়। 10.8.0.6-এর মতো ঠিকানা টানেলের ভেতরে বাস্তব এবং অন্য কোথাও অস্তিত্বহীন, তাই LAN-এর কাছে সেখানে কিছু পাঠানোর কোনো কারণ নেই। রাউটিং স্পর্শ করার আগে নিশ্চিত করুন সেবাটি আদৌ টানেলের ভেতরে পৌঁছানোর যোগ্য কি না: ক্লায়েন্টে ss -ltn দেখায় লিসেনারটি 127.0.0.1-এ, LAN ইন্টারফেসে নাকি টানেল ঠিকানায় বাঁধা। শুধু loopback-এ বাঁধা ডেমন নিজে ছাড়া কারও উত্তর দেয় না, এবং কোনো রুট, DNAT বা পোর্ট ফরওয়ার্ড তা বদলায় না।
পোর্ট 80 বা 443-এ থাকা প্রক্সি ভিন্ন দৃশ্যমানতার ভিন্ন যন্ত্র। এটি প্যাকেট নয়, অনুরোধ সরায়, তাই কাঁচা ডেটাবেস সংযোগের জন্য এটি ভুল স্তর, এবং এটির দিকে হাত বাড়ানোই এই সমস্যাটিকে কেউ কিছু মাপার আগে তিন যন্ত্র গভীরে নিয়ে যায়।
রুটের আকৃতি: LAN-কে বলুন পুলটি কোথায়
LAN গেটওয়েতে একটি স্ট্যাটিক রুট সবচেয়ে পরিষ্কার উত্তর যখন LAN এবং টানেল পুল ওভারল্যাপ করে না। পুলটিকে টানেল শেষ করে যে মেশিনে নির্দেশ করুন:
ip route add 10.8.0.0/24 via 192.168.1.12
route add -p 10.8.0.0 mask 255.255.255.0 192.168.1.12 # Windows, persistent
এটি কেবল একটি দিক ঠিক করে, তাই এই পরিবর্তনের অর্ধসমাপ্ত সংস্করণগুলো অগ্রগতির মতো দেখায়। টানেলের দিকটিরও মিলে যাওয়া অর্ধেকটি দরকার, নাহলে উত্তরটি ক্লায়েন্টের নিজের ডিফল্ট রুটে বেরিয়ে পথেই মরে যায়:
push "route 192.168.1.0 255.255.255.0"
সার্ভারের পিছনে নয়, বরং একটি ক্লায়েন্টের পিছনে থাকা সাবনেটের জন্য সার্ভারের দরকার একটি সিস্টেম রুট এবং সেই ক্লায়েন্টের ফাইলে একটি iroute এন্ট্রি, যা client-config-dir-এর অধীনে থাকে। iroute ছাড়া OpenVPN জানে যে প্রিফিক্সটি আছে এবং কোন ক্লায়েন্ট এটির মালিক তা জানে না: প্যাকেট আসে আর ডেমনের কাছে মেলানোর মতো কিছু থাকে না।
এখানেই সেই মিথ, যার নাম দেওয়া দরকার। একটি রুট ঠিকানাকে পৌঁছানোর যোগ্য করে, কিন্তু বিপরীত পক্ষকে উত্তর দিতে ইচ্ছুক করে না। সাইট-থেকে-সাইট পিয়ার আরও একটি স্তর যোগ করে, কারণ দূরবর্তী গেটওয়ে কেবল তার নীতিতে তালিকাভুক্ত প্রিফিক্সের ভেতরের উৎস গ্রহণ করে, আর হোম পুল থেকে আসা ল্যাপটপ সেগুলোর ভেতরে থাকে না।
NAT-এর আকৃতি: ভেতরে DNAT, আর যে SNAT লাইন সবাই বাদ দেয়
যখন আপনি LAN গেটওয়ে স্পর্শ করতে পারেন না, বা ঠিক একটি পোর্ট প্রকাশ করতে চান, VPN হোস্টে ট্রান্সলেশন LAN-এ কোনো রুট ছাড়াই কাজ করে। পোর্টটি প্রকাশ করুন, ফরওয়ার্ড করুন, এবং টানেলের দিকে যাওয়ার পথে উৎসটি ট্রান্সলেট করুন:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.8.0.6:3000
iptables -A FORWARD -i eth0 -o tun0 -p tcp -d 10.8.0.6 --dport 3000 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -d 10.8.0.6 -p tcp --dport 3000 -j SNAT --to-source 10.8.0.1
তৃতীয় লাইনটিই হারিয়ে যায়। এটি বাদ দিলে ক্লায়েন্ট মূল LAN ঠিকানাকে উৎস হিসেবে দেখে, নিজের ডিফল্ট রুটে উত্তর দেয়, আর সেই উত্তর LAN-এর দিকে ফেরার বদলে টানেলের দিকে চলে যায়। সংযোগটি টিকে থাকবে কি না তা তখন নির্ভর করে এমন রাউটিংয়ের ওপর যা আপনি কখনো পরিকল্পনা করেননি। SNAT-এর সাথে ক্লায়েন্ট সার্ভারের টানেল ঠিকানা দেখে, তাই উত্তরটি ট্রান্সলেশন বাতিল করতে পারে এমন একমাত্র হোস্ট পর্যন্ত টানেল ধরে ফিরে যায়।
কনজিউমার ফার্মওয়্যার নিজের চেইন নাম ব্যবহার করে এবং আপনার জন্য সেই ট্রান্সলেশন তৈরি করে না। Tomato-তে একটি ইনবাউন্ড নিয়ম WANPREROUTING-এ ঢোকে, তারপর wanin-এর মতো ফিল্টার চেইনে, এবং সম্পূর্ণ দেখতে পাওয়া নিয়মের সেটেও হাতে লেখা একটি POSTROUTING লাইন দরকার। এটি ফার্মওয়্যারের বাগ নয়; এটি কেবল ইনবাউন্ড ট্রাফিকের জন্য লেখা নিয়মের সেট।
কেন সঠিক দেখতে পাওয়া নিয়মও প্যাকেট ফেলে দেয়
এই ব্যর্থতার বেশিরভাগই আপনি যে নিয়মটির দিকে তাকিয়ে আছেন সেটিতে নেই। এই ক্রমে চারটি জিনিস দেখুন, এবং যেটি মেলে না সেখানেই থামুন:
- চেইনের ক্রম।
iptables -Iশীর্ষে ঢোকায় আর-Aশেষে যোগ করে, তাই আগের কোনো অনুমোদনকারী বা ব্লককারী নিয়মই আগে সিদ্ধান্ত নেয়। - ভুল চেইন। রাউটারের নিজের কাছে ঠিকানা করা ট্রাফিক INPUT অতিক্রম করে, আর ফরওয়ার্ড করা ট্রাফিক সেটি কখনো ছোঁয় না। একটি সেবা প্রকাশ করতে দুই জায়গাতেই নিয়ম লাগতে পারে।
- দিকের ফ্ল্যাগ।
-i tun0ক্লায়েন্টদের কাছ থেকে আসা ট্রাফিক মেলায় আর-o tun0তাদের দিকে যাওয়া ট্রাফিক। ভুল ফ্ল্যাগসহ একটি REJECT এমন কিছু ব্লক করে যা আপনি চাননি। - উৎসের সীমাবদ্ধতা। একটি ক্লায়েন্ট ঠিকানা গ্রহণ করা একটি ফরওয়ার্ড সেই ক্লায়েন্ট থেকে কাজ করে এবং বাকি সব উৎসকে একটি কথাও না বলে ফেলে দেয়।
শূন্য প্যাকেট কাউন্টারের নিয়মটি পথেই নেই, আর কাউন্টার পড়াই ভুল-চেইনের সমস্যাকে ভুল-নিয়মের সমস্যা থেকে আলাদা করার দ্রুততম উপায়।
লোকাল ফরওয়ার্ড, যখন LAN-এ কিছুই বদলানো যায় না
একটি SSH লোকাল ফরওয়ার্ড পুরো প্রশ্নটিই পাশ কাটিয়ে যায়। এর LAN-এ কোনো রুট লাগে না, ক্লায়েন্টের ফায়ারওয়ালের কোনো সহযোগিতা লাগে না, আর কোথাও কোনো পোর্ট প্রকাশ করতে হয় না:
ssh -N -f -L 3000:10.8.0.6:3000 user@vpn-host
এরপর সেবাটি টানেল চালানো মেশিনের localhost:3000-এ দেখা যায়, আর অন্য কোথাও নয়। সীমাটি এখানেই: একটি ওয়ার্কস্টেশন, একটি পোর্ট, এবং কিছু পুনরায় চালু না করলে সেশনটির সাথে ফরওয়ার্ডটিও মরে যায়। স্টেজিং ডেটাবেস যাচাই করা অ্যাডমিনের জন্য এটি সঠিক যন্ত্র। কিন্তু ক্যামেরা বা স্ক্যানারের ক্ষেত্রে নয়, যেগুলোতে অন্য মানুষের পৌঁছাতে হয়, কারণ প্রত্যেক ব্যবহারকারীর নিজের ফরওয়ার্ড লাগবে।
আরেকটি নিয়ম যোগ করার আগে দুই দিক যাচাই করুন
ট্রান্সলেশন চিহ্ন রেখে যায়, আর সেগুলো পড়া অনুমানের চেয়ে ভালো। VPN হোস্টে conntrack -L দেখায় ট্রান্সলেশন আদৌ ঘটেছে কি না, iptables -t nat -L -n -v দেখায় কাউন্টারগুলো নড়েছে কি না, আর tcpdump -ni any port 3000 দেখায় কোন উৎস ঠিকানা সত্যিই এসেছে। ক্লায়েন্টে ss -ltn নিশ্চিত করে লিসেনারটি এমন ঠিকানায় আছে যা টানেল পৌঁছাতে পারে।
তারপর যে আকৃতিটি রাখছেন সেটি বেছে নিন। একটি প্রকাশিত পোর্ট, পুরো পুলের জন্য একটি রুট, আর একজন অ্যাডমিনের জন্য একটি ফরওয়ার্ড — এগুলো তিনটি আলাদা অঙ্গীকার, এবং এগুলো মিশিয়ে দেওয়াই একটি কাজ করা সেটআপকে এমন কিছুতে পরিণত করে যা ছয় মাস পরে কেউ ব্যাখ্যা করতে পারে না। কোন ঠিকানা কোথা থেকে পৌঁছানোর যোগ্য তা লিখে রাখুন, আর পরের যে ব্যক্তি এটি ডিবাগ করবে সে টানেল নয়, উত্তর থেকেই শুরু করবে।