যে মেশিনে SSH দিয়ে পৌঁছান, সেখানে সম্পূর্ণ-টানেল OpenVPN ক্লায়েন্ট চালু করলে সেশন এক সেকেন্ডের মধ্যে কেটে যেতে পারে, আর মেশিনটি কিছুই ভুল করছে না। টানেল প্যাকেট সার্ভারে পৌঁছানোর উপায় বদলায় না; বদলায় উত্তরগুলো কীভাবে বের হয়। ডিফল্ট রুট tun0-এ নির্দেশ করলেই আপনার SSH ক্লায়েন্টের উত্তর প্রোভাইডারের নেটওয়ার্কে ঢুকে যায়, যার আপনার ঠিকানায় ফেরার কোনো রুট নেই। সংযোগ আটকে যায়, পরের চেষ্টা টাইম-আউট হয়, আর ডেমন সারাক্ষণ পোর্ট 22-এ শুনতে থাকে।

VPN লগ পড়ার আগে রাউটিং টেবিল পড়ুন। লগ বলবে টানেল উঠেছে, এবং তা ঠিক। প্রশ্ন হলো প্রতিটি উত্তর কোন ইন্টারফেসে হস্তান্তরিত হয়, আর সেটি টানেল এইমাত্র পুনর্লিখিত একটি টেবিলের বিপরীতে প্রতি-প্যাকেট অনুসন্ধান।

উত্তর কেন ভুল দরজা দিয়ে বেরোয়

আগত প্যাকেট এখনও ফিজিক্যাল ইন্টারফেসে আসে, কারণ একটি VPN ক্লায়েন্ট বদলাতে পারে না কীভাবে ইন্টারনেট আপনার সার্ভারের পাবলিক ঠিকানায় পৌঁছায়। উত্তর আলাদা সিদ্ধান্ত: প্রতিটি প্যাকেটের জন্য কার্নেল গন্তব্য খোঁজে, আর --redirect-gateway-এর পরে ডিফল্ট এন্ট্রি বলে টানেল। প্রোভাইডারের এক্সিট এমন গন্তব্য দেখে যা সে পরিবেশন করে না এবং প্যাকেটটি ফেলে দেয়।

OpenVPN-এর নিজস্ব সুরক্ষা ঠিক একটি গন্তব্য ঢাকে। 2.6 ম্যানুয়াল --redirect-gateway-কে একটি ক্রম হিসেবে বর্ণনা করে: টানেলের আগে ব্যবহৃত গেটওয়ে দিয়ে VPN পিয়ারের জন্য একটি হোস্ট রুট যোগ করে, যাতে এনক্রিপ্টেড ট্রাফিক নিজের ভেতরে ফিরে যেতে না পারে, তারপর ডিফল্ট রুট প্রতিস্থাপন করে। এই হোস্ট রুট কেবল পিয়ারের জন্য। আপনার SSH ক্লায়েন্ট শুধু আরেকটি ইন্টারনেট ঠিকানা এবং কোনো ব্যতিক্রম পায় না।

একটি প্রিফিক্স ভুল আগেই বাদ দেওয়া ভালো। দৈর্ঘ্য ছাড়া ip route add -net 0.0.0.0 gw 10.8.0.1 dev tun0 কেবল 0.0.0.0 ঠিকানার সাথে মেলে, ইন্টারনেটের সাথে নয়; এটি হতে হবে 0.0.0.0/0। আর যদি ডিফল্ট নেওয়া টানেলের নিজের পরিবহন ভেঙে দেয়, তাহলে ফিজিক্যাল ইন্টারফেস দিয়ে এন্ডপয়েন্টটিকে হোস্ট রুট হিসেবে যোগ করুন, প্রোভাইডারের প্রকৃত ঠিকানা ব্যবহার করে।

তাৎক্ষণিক সমাধানের জন্য আপনার SSH ক্লায়েন্ট ঠিকানা পিন করুন

দ্রুততম মেরামত হলো টানেলের আগে সার্ভার যে গেটওয়ে ব্যবহার করত, সেটি দিয়ে আপনার ক্লায়েন্ট ঠিকানার জন্য একটি হোস্ট রুট। আপনার দিক থেকে সার্ভার যে ঠিকানা দেখবে সেটি খুঁজুন, তারপর পুরনো গেটওয়ে জানতে সার্ভারের টেবিল পড়ুন:

curl -s https://ifconfig.co
ip route

সার্ভারে ক্লায়েন্ট শুরুর আগে ব্যতিক্রমটি যোগ করুন। এখানকার ঠিকানাগুলো প্লেসহোল্ডার; আসল বিষয় হলো আকৃতি:

sudo ip route add 80.128.240.55 via 192.168.178.1

এটি রিপোর্ট করা ঘটনায় ব্যবহৃত সমাধান, এবং এটি সাথে সাথে কাজ করে। এটি দুটি অনুমেয় উপায়ে ভঙ্গুরও: রুটটি রিবুটে হারিয়ে যায়, আর আপনার ISP ভিন্ন ঠিকানা দেওয়ার মুহূর্তেই এটি ভুল হয়ে যায়। এটিকে জরুরি ব্যবস্থা হিসেবে ধরুন এবং সচেতনভাবে টেকসই করুন, নেটওয়ার্ক ইউনিট বা ডিসপ্যাচার হুকের মাধ্যমে, অথবা মেনে নিন এটি সাময়িক এবং পুনরুদ্ধারের পথ লিখে রাখুন।

ক্লায়েন্টকে ডিফল্ট নেওয়া থেকে থামান

আরও পরিচ্ছন্ন বিকল্প হলো টানেলকে ডিফল্ট রুট প্রতিস্থাপন করতে না দেওয়া। route-nopull, --client বা --pull-এর সাথে ব্যবহৃত হলে, রুট, block-outside-dns এবং DNS সার্ভারের মতো DHCP-ধাঁচের অপশন ছাড়া পুশ করা অপশন গ্রহণ করে, তাই আপনি কেবল প্রয়োজনীয় প্রিফিক্স যোগ করেন। আরও সংকীর্ণ হাতিয়ার হলো পুল ফিল্টার, যা একটি সমস্যাযুক্ত নির্দেশ বাদ দেয় এবং বাকিটা রাখে:

route-nopull
pull-filter ignore "redirect-gateway"

একটি বা অন্যটি ব্যবহার করুন, দুটোই নয়, আর কী বদলায় তা স্পষ্ট রাখুন। টানেল দিয়ে ডিফল্ট রুট না থাকলে সার্ভার আর প্রোভাইডারের মাধ্যমে ইন্টারনেট ব্রাউজ করে না; এটি কেবল আপনার স্পষ্টভাবে রাউট করা জিনিসে পৌঁছায়। যদি সম্পূর্ণ টানেলই সেটআপের পুরো উদ্দেশ্য হয়ে থাকে, তাহলে এটি ভুল সুইচ এবং উপরের হোস্ট রুটটাই সঠিক।

সোর্স বা সংযোগ অনুযায়ী ফেরার পথ ভাগ করুন

যখন আগত ঠিকানা স্থিতিশীল, একটি সোর্স নিয়ম টানেলের নিজের রুট স্পর্শ না করেই উত্তরগুলো স্থানীয় রাখে। ফিজিক্যাল ইন্টারফেস ঠিকানাকে LAN প্রিফিক্স ও ফিজিক্যাল ডিফল্টসহ নিজের টেবিল দিন, তারপর সেখান থেকে আসা ট্রাফিকের জন্য সেই টেবিল নির্বাচন করুন:

ip rule add from 192.168.1.11 table 128
ip route add table 128 to 192.168.1.0/24 dev eth0
ip route add table 128 default via 192.168.1.1

এটি কাজ করে কারণ আগত SSH সংযোগের উত্তর সেই ঠিকানা থেকে আসে যেখানে ক্লায়েন্ট সংযুক্ত হয়েছিল। যে রিপোর্ট করা ঘটনায় প্রতিটি আগত সেবাকে কাজ চালিয়ে যেতে হয়েছিল, সেখানে ঠিক এই আকৃতিই ব্যবহৃত হয়েছিল। যখন আগত ঠিকানা ভাসমান বা পথ গতিশীল, তখন পরিবর্তে সংযোগটি চিহ্নিত করুন: ফিজিক্যাল ইন্টারফেস থেকে আসা প্রথম প্যাকেটে একটি conntrack চিহ্ন দিন, OUTPUT-এ উত্তর প্যাকেটে সেটি কপি করুন, এবং চিহ্নিত প্যাকেটগুলো ফিজিক্যাল গেটওয়ের দিকে নির্দেশ করা একটি টেবিল দিয়ে রুট করুন।

iptables -t mangle -A PREROUTING -i eth0 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1234
iptables -t mangle -A OUTPUT -m connmark --mark 1234 -j MARK --set-mark 4321
ip route add default via 192.168.1.1 dev eth0 table 3412
ip rule add fwmark 4321 table 3412

পরীক্ষার সময় সংযোগ চিহ্ন, ফায়ারওয়াল চিহ্ন এবং টেবিল নম্বর আলাদা রাখুন। দুই ভূমিকার জন্য একটি নম্বর পুনর্ব্যবহার করলে এমন নিয়ম তৈরি হয় যা ঠিক দেখায় আর ভুল প্যাকেটের সাথে মেলে। টেবিলের ডিফল্ট এন্ট্রিতে সাধারণ ইথারনেট লিংকে LAN গেটওয়ে সহ via-ও দরকার; খালি dev eth0 ডিফল্ট কেবল তখনই কাজ করে যখন ইন্টারফেস পয়েন্ট-টু-পয়েন্ট বা পরবর্তী হপ অন্যভাবে সমাধান হয়। রিপোর্ট করা Jessie হোস্টটি সংযোগে ছিল যেখানে খালি রূপটি কাজ করেছিল, যা নকল করার মতো কোনো ডিস্ট্রিবিউশন নিয়ম নয়।

নিজেকে লক আউট না করে যাচাই করুন

সংযোগ বিচ্ছিন্ন করে পরীক্ষা করবেন না। প্রথম সেশন খোলা রাখুন, টানেল তুলুন, এবং কার্নেলকে জিজ্ঞাসা করুন আপনার নিজের ঠিকানা কোন পথ নেবে:

ip route get 80.128.240.55

উত্তরে ফিজিক্যাল ইন্টারফেস ও পুরনো গেটওয়ে থাকা উচিত, টানেল নয়। তারপর দ্বিতীয় SSH সংযোগ খুলুন; এটাই আসল পরীক্ষা, কারণ পুরনো সেশন এমন অবস্থার উপর টিকে থাকতে পারে যা নতুন সংযোগ পুনরুৎপাদন করতে পারে না। যদি দ্বিতীয়টি আটকে যায় আর প্রথমটি উত্তর দিতে থাকে, তবে নিয়মটি কখনোই গুরুত্বপূর্ণ ট্রাফিকের সাথে মেলেনি, এবং চিহ্ন বা সোর্স ঠিকানাই খোঁজার জায়গা।

পুরো অনুশীলনের জন্য একটি আউট-অব-ব্যান্ড কনসোল হাতের কাছে রাখুন। যে সার্ভারের একমাত্র প্রবেশপথ আপনি এইমাত্র ভেঙে দেওয়া টানেল, তাকে সেই টানেল দিয়েই মেরামত করা যায় না, আর আপনি যে টেবিল নম্বর ও প্রিফিক্স যোগ করেছেন তা লিখে রাখলে রোলব্যাক সহজ হয়।

সম্পর্কিত নিবন্ধ