VPN ক্লায়েন্ট সেবায় পৌঁছানো: রিভার্স টানেল নাকি DNAT
পোর্ট ফরওয়ার্ড ছাড়া OpenVPN ক্লায়েন্টের একটি সেবায় পৌঁছানো: রিভার্স SSH টানেলের সঙ্গে সার্ভার-সাইড DNAT এবং বেছে নেওয়ার তিনটি শর্ত তুলনা করুন।
ক্যারিয়ার NAT-এর পেছনের ল্যাপটপও একজন সহকর্মীকে সেবা দিতে পারে, যদি VPN সার্ভার মিলনস্থল হিসেবে কাজ করে। সেখানে পৌঁছানোর দুটি প্রক্রিয়া আছে: ক্লায়েন্ট বাইরে ডায়াল করে সার্ভারকে একটি শ্রবণ পোর্ট ধরে রাখতে বলে, অথবা সার্ভার একটি পোর্ট প্রকাশ করে তা টানেলে অনুবাদ করে। দুটিই একই পৌঁছানোর সমস্যা সমাধান করে এবং ব্যর্থতা, তদারকি ও লগিংয়ে ভিন্নভাবে আচরণ করে। আপনার সেটআপে কোনটি মানায় তা তিনটি শর্ত ঠিক করে।
দুটি আকৃতি, একটি মিলনস্থল
প্রথম আকৃতিতে ক্লায়েন্ট বাইরের দিকে একটি SSH সেশন খোলে এবং সার্ভারকে একটি নির্বাচিত পোর্টে শুনতে বলে, প্রতিটি সংযোগ সেই সেশন দিয়ে ফেরত পাঠায়। সার্ভারে কিছুই ফরওয়ার্ড হয় না এবং কোনো প্যাকেট অনুবাদ ঘটে না, তাই একমাত্র প্রয়োজন একটি SSH অ্যাকাউন্ট, একটি অনুমোদিত ফরওয়ার্ড এবং পোর্টের জন্য একটি ফায়ারওয়াল নিয়ম। সেবাটি ক্লায়েন্টে লুপব্যাকে আবদ্ধ থাকে, যা সাধারণত আপনি চান।
ssh -N -R 8081:127.0.0.1:8080 -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 [email protected]
দ্বিতীয় আকৃতিতে সার্ভার প্রকাশ্য পোর্টটির মালিক এবং প্রতিটি সংযোগ ক্লায়েন্টের টানেল ঠিকানার দিকে পুনর্লিখন করে। এতে IP ফরওয়ার্ডিং চালু থাকা, ঢোকার পথে গন্তব্য অনুবাদ এবং বেরোনোর পথে উৎস অনুবাদ দরকার, এবং কোনো SSH সেশন না থাকলেও এটি কাজ করতে থাকে। পোর্টটি সেশনের নয়, সার্ভারের, এবং এই বৈশিষ্ট্যই বেশিরভাগ বাস্তব ক্ষেত্রে সিদ্ধান্ত দেয়।
দুটির কোনোটিই গঠনগতভাবে বেশি নিরাপদ নয়। দুটিই একটি সেবা পোর্ট সার্ভারের প্রকাশ্য ঠিকানায় পৌঁছাতে পারে এমন সবার কাছে উন্মুক্ত করে, আর দুটিই সেবার নিজের প্রমাণীকরণের ওপর নির্ভর করে।
শর্ত এক: পোর্টটি কি সেশনের চেয়ে বেশি দিন বাঁচতে হবে
রিভার্স ফরওয়ার্ড ঠিক ততদিন বাঁচে যতদিন তা তৈরি করা SSH সেশন বাঁচে। লিংক কেটে গেলে শ্রবণকারী হারিয়ে যায় এবং সহকর্মী ধীর পথের বদলে সংযোগ প্রত্যাখ্যাত দেখেন। systemd ইউনিট ও রিস্টার্ট নীতির মাধ্যমে কমান্ডটি তদারকি করলে তা ঠিক হয়, আর ExitOnForwardFailure=yes ব্যর্থ বাইন্ডকে সঙ্গে সঙ্গে দৃশ্যমান করে, ফরওয়ার্ডহীন সেশন চালু রাখার বদলে।
অনূদিত পোর্ট নিয়মগুলো সংরক্ষিত থাকলে রিবুটেও টিকে থাকে, তবে তা ক্লায়েন্টের একই টানেল ঠিকানা ধরে রাখার ওপর নির্ভর করে। পুনঃসংযোগের পর ল্যাপটপকে ভিন্ন ঠিকানা দেওয়া ডাইনামিক পুল নিয়মটিকে নীরবে কোথাও নির্দেশ করে না। আগে টানেল ঠিকানা সংরক্ষণ করুন, তারপর নিয়মটি লিখুন, এবং দুটিকে এক পরিবর্তন হিসেবে দেখুন।
সেবাটিকে যদি রাত তিনটায় কেউ না দেখেও উত্তর দিতে হয়, তবে সার্ভার-প্রকাশিত পোর্ট আকৃতিতেই কম চলমান অংশ আছে, কারণ চালু থাকতে হবে কেবল টানেল নিজেই।
শর্ত দুই: ফায়ারওয়াল ও লগের মালিক কে
রিভার্স আকৃতি সব নীতি দুটি জায়গায় রাখে। sshd ঠিক করে দূরবর্তী ফরওয়ার্ড আদৌ অনুমোদিত কি না AllowTcpForwarding দিয়ে, আর GatewayPorts ঠিক করে শ্রবণকারী লুপব্যাকে বাঁধবে না সব ঠিকানায়। ডিফল্ট no থাকলে সার্ভারের বাইরের সহকর্মী ফরওয়ার্ড সফল হলেও পোর্টে পৌঁছাতে পারেন না, আর তা ভাঙা টানেলের মতো দেখায় অথচ আসলে বাইন্ড ঠিকানার ব্যাপার।
sudo ss -ltn '( sport = :8081 )'
sudo grep -E '^(GatewayPorts|AllowTcpForwarding)' /etc/ssh/sshd_config
অনূদিত আকৃতিতে ফরওয়ার্ডিং চালু ও দুটি নিয়ম দরকার, আর দ্বিতীয় নিয়মেই বেশিরভাগ রেসিপি ভুল করে। উৎস অনুবাদকে conntrack-এর DNAT অবস্থার মধ্যে সীমাবদ্ধ করা মানে গন্তব্য নিয়ম যেসব সংযোগ তৈরি করেছে কেবল সেগুলোই পুনর্লিখিত হয়, সার্ভার টানেলে পাঠানো প্রতিটি প্যাকেট নয়।
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8081 -j DNAT --to-destination 10.88.0.6:8080
sudo iptables -t nat -A POSTROUTING -o tun0 -m conntrack --ctstate DNAT -j SNAT --to-source 10.88.0.1
এই পুনর্লিখন আরোপণও ধ্বংস করে। এর পর ক্লায়েন্ট প্রত্যেক কলকারীকে সার্ভারের টানেল ঠিকানা হিসেবে দেখে, যা প্রতি-ঠিকানার যে কোনো হার-সীমাকে এক বালতিতে নামায় এবং কে কী পাঠিয়েছে তা লুকায়। আরোপণ গুরুত্বপূর্ণ হলে সার্ভারে সংযোগটি শেষ করুন বা অনুমতির সিদ্ধান্ত সেখানেই রাখুন এবং সেবা যে হেডার বিশ্বাস করে তাতে পরিচয় পাঠান। এই দুটি সমাধানের মধ্যে বাছাই নির্ভর করে সেবাটি আদৌ প্রক্সি হেডার পড়ে কি না তার ওপর।
শর্ত তিন: একটি পোর্ট নাকি অনেক, আর নামের মালিক কে
একটি পোর্টে একটি সেবা সেই ক্ষেত্র যেখানে পরিশ্রমে রিভার্স ফরওয়ার্ড জেতে। একটি কমান্ড, একটি অ্যাকাউন্ট ও একটি ফায়ারওয়াল নিয়ম দরকার, আর পরিষ্কার করা মানে সেশনটি মারা। একই প্রকাশ্য ঠিকানায় একাধিক সেবা আপনাকে সার্ভার-প্রকাশিত আকৃতির দিকে ঠেলে, কারণ প্রতিটি রিভার্স ফরওয়ার্ডের নিজস্ব সার্ভার পোর্ট লাগে এবং প্রতিটি সেবার সঙ্গে সেটি বাড়ে।
নাম আরও জটিল করে। রিভার্স ফরওয়ার্ড SNI দিয়ে রুট করা TCP প্রক্সির পেছনে থাকতে পারে, আর অনূদিত পোর্ট সাধারণত প্রতি সেবায় একটি। সেবাটি যদি নিজেই TLS শেষ করে এবং মূল হোস্টনাম চায়, প্রক্সি পদ্ধতি তা রক্ষা করে, আর DNAT পদ্ধতি তা রক্ষা করে কেবল যদি সেবাটি সেই পোর্টে সেই হোস্টনাম গ্রহণ করে।
তিনটি শর্তের কোনটি আকৃতি নির্ধারণ করেছে তা লিখে রাখুন। নইলে দ্বিতীয় সেবা যোগ করা পরবর্তী ব্যক্তি কম প্রসঙ্গে একই তুলনা আবার খুলবে।
সিদ্ধান্ত নিন, তারপর বাইরে থেকে পরীক্ষা করুন
এমন নেটওয়ার্ক থেকে পথটি পরীক্ষা করুন যার ল্যাপটপে কোনো রুট নেই, এবং অনুরোধ চলার সময় সার্ভারের কাউন্টার দেখুন। সার্ভার থেকে তার নিজের প্রকাশ্য ঠিকানার দিকে পরীক্ষা এখানে কিছুই প্রমাণ করে না, কারণ প্যাকেটটি স্থানীয়ভাবে তৈরি হয় এবং কখনও আগত অনুবাদ হুক পর্যন্ত পৌঁছায় না, তাই পরীক্ষা পাস হতে পারে অথচ আসল পথ ভাঙা।
sudo iptables -t nat -L PREROUTING -n -v
sudo tcpdump -ni any 'tcp port 8081' -c 20
স্থির থাকা কাউন্টার মানে প্যাকেটটি কখনও নিয়মে পৌঁছায়নি, যা সরবরাহকারী বা হোস্ট ফায়ারওয়ালের দিকে ইঙ্গিত করে। সেবা প্রত্যাখ্যান করলেও নড়াচড়া করা কাউন্টার ইঙ্গিত করে ক্লায়েন্টের নিজের ফায়ারওয়াল বা সেবা যে ঠিকানায় শোনে তার দিকে। যে টানেল প্যাকেট বহন করে কিন্তু কিছু ফেরত দেয় না, তা রুট বা রিভার্স-পাথ সমস্যা, আর এই তিনটি পরিণতির কোনোটিই ক্লায়েন্ট অ্যাডাপ্টার সম্পাদনা করে ডিবাগ করা উচিত নয়। কিছু বদলানোর আগে কোন কাউন্টার নড়েছে লিখে রাখুন, কারণ পরের পরীক্ষার সেই ভিত্তি দরকার।
আকৃতিটি কাজ শুরু করলে পোর্ট, মালিক ও তদারকির পদ্ধতি টানেল কনফিগারেশনের পাশে লিখে রাখুন। যে পৌঁছানোর সমাধান কেবল কারও শেল ইতিহাসে বাঁচে, তা এক রিবুট দূরত্বে পুনরাবৃত্ত ঘটনা।