Android, iOS ও Windows-এ ping ছাড়াই VPN স্ট্যাটাস কীভাবে যাচাই করবেন
ping শুধু এটুকু প্রমাণ করে যে একটি হোস্ট উত্তর দিয়েছে, টানেল চালু আছে তা নয়। Android, iOS ও Windows-এর স্ট্যাটাস API জিজ্ঞাসা করুন, তারপর আপনার অ্যাপের সত্যিই প্রয়োজনীয় রুট যাচাই করুন।
192.0.2.10-এ ping করা আপনাকে বলে যে একটি ঠিকানা ICMP echo-তে উত্তর দিয়েছে, এবং এটুকুই। টানেল ছাড়া নেটওয়ার্কেও এটি সফল হতে পারে, কারণ ঠিকানাটি স্থানীয় সাবনেটে থাকতে পারে; সুস্থ টানেল থাকলেও এটি ব্যর্থ হতে পারে, কারণ সার্ভার HTTPS পরিবেশন করার সময় ICMP ফেলে দেয়। আপনার স্ক্রিপ্টের প্রয়োজনীয় যাচাই হল প্ল্যাটফর্ম স্ট্যাটাস কোয়েরি এবং অ্যাপ্লিকেশনটি যে গন্তব্য ব্যবহার করে তার জন্য রুট টেস্ট। এগুলোকে দুটি আলাদা ফিল্ড হিসেবে ধরুন, কখনোই একটি boolean হিসেবে নয়।
একটি echo উত্তর আসলে কী প্রমাণ করে
ICMP একটি রিচেবিলিটি প্রোটোকল, যা ইন্টারফেস বা টানেল সম্পর্কে কিছু জানে না। উত্তর এলে কার্নেল জানায় যে একটি হোস্ট উত্তর দিয়েছে; কোন রুট অনুরোধটি বা উত্তরটি বহন করেছে তা জানায় না। ফিল্টারিং সংকেতকে আরও অস্পষ্ট করে, কারণ echo অনুরোধ ব্লক করা ফায়ারওয়াল তার পেছনের পোর্ট সম্পর্কে কিছুই বলে না। আর split-tunnel প্রোফাইল পরীক্ষিত ঠিকানাটি ইচ্ছাকৃতভাবে বাদ দিতে পারে, যদিও বাকি সব গন্তব্য কাজ করে।
আপনি আসলে জানতে চান একটি নির্দিষ্ট সেবা অ্যাপের নেওয়া পথে ব্যবহারযোগ্য কি না। অ্যাপ যে হোস্ট ও পোর্টে কল করে সেটি বেছে নিন, তারপর অ্যাপ্লিকেশন স্তরে উত্তর দাবি করুন।
রিচেবিলিটি ও টানেল অবস্থা আলাদা তথ্য, এবং একটি সত্য হতে পারে যখন অন্যটি মিথ্যা। এগুলো আলাদা রাখলে বোঝা যায় ব্যর্থতা কার। একটিমাত্র যাচাইয়ে মিলিয়ে দিলে এমন টিকিট তৈরি হয় যা কেউ রাউট করতে পারে না।
Android-কে ping নয়, ট্রান্সপোর্ট জিজ্ঞাসা করুন
Android স্ট্যাটাসের প্রশ্নের উত্তর সরাসরি ConnectivityManager-এর মাধ্যমে দেয়। সক্রিয় নেটওয়ার্কের সক্ষমতায় VPN ট্রান্সপোর্ট ফ্ল্যাগ থাকে, যা ট্রাফিক VPN ইন্টারফেস দিয়ে রাউট হলে সেট হয়। কলটি স্থানীয়, সস্তা এবং কোনো দূরবর্তী হোস্ট উত্তর দেয় কি না তার উপর নির্ভর করে না।
এই Java সংস্করণ সক্রিয় নেটওয়ার্ক না থাকলে এক্সসেপশন তোলার বদলে false ফেরায়। যেহেতু এটি সক্রিয় নেটওয়ার্ক পড়ে, তাই ব্যবহারকারী সেটিংসে যে প্রোফাইল বেছেছেন তা প্রতিফলিত করে।
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkCapabilities caps = cm.getNetworkCapabilities(cm.getActiveNetwork());
boolean tunnel = caps != null && caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
পরিবর্তনের বিজ্ঞপ্তির জন্য টাইমারে পোল করার বদলে NetworkCallback নিবন্ধন করুন। এটিকে VpnService.prepare-এর সঙ্গে গুলিয়ে ফেলবেন না, যা কেবল জানায় ব্যবহারকারী VPN-এর অনুমতি দিয়েছেন কি না, প্যাকেট প্রবাহিত হচ্ছে কি না নয়। প্রত্যাহার আসে VpnService.onRevoke দিয়ে, তবে সেটিংসে প্রোফাইল ভুলে গেলে কোনো ব্রডকাস্ট হয় না।
iOS: ইন্টারফেসের নাম একটি হিউরিস্টিক, চুক্তি নয়
অনেক iOS স্নিপেট প্রক্সি সেটিংস পরীক্ষা করে, __SCOPED__ অভিধান খুঁজে পায় এবং tap, tun, utun2, ppp বা ipsec-এর মতো ইন্টারফেস কী খোঁজে। এই পদ্ধতি নামকরণের রীতি, নথিভুক্ত নিশ্চয়তা নয়, তাই ইন্টারফেসের নাম বদলানো কোনো OS আপডেট এটি ভেঙে দিতে পারে। এটি টানেলের পরে টিকে থাকা পুরনো এন্ট্রির জন্যও সত্য রিপোর্ট করার প্রবণতা রাখে।
আপনার অ্যাপ কনফিগারেশনের মালিক হলে NEVPNManager আপনাকে প্রকৃত স্ট্যাটাস দেয়। এটি আপনার অ্যাপ যে টানেল শুরু করেছে তা বর্ণনা করে; per-app VPN-এ অন্য অ্যাপ সম্পূর্ণভাবে সেই টানেলের বাইরে থাকতে পারে।
স্ট্যাটাস পড়ার আগে পছন্দগুলো পুনরায় লোড করুন, কারণ টানেল ওঠানামার সঙ্গে মানটি বদলায়:
let manager = NEVPNManager.shared()
manager.loadFromPreferences { error in
let up = manager.connection.status == .connected
print(up)
}
প্ল্যাটফর্ম স্ট্যাটাস ফ্ল্যাগ তবুও প্রমাণ করে না যে ট্রাফিক পিয়ারে পৌঁছায়। এই ফাঁকটাই রুট টেস্ট ঢাকে, আর এজন্যই সাপোর্টের জন্য একটি boolean যথেষ্ট নয়।
Windows প্রোফাইল প্রকৃত স্ট্যাটাস ফিল্ড দেয়
Windows VPN প্রোফাইলগুলো অ্যাডাপ্টার থেকে আলাদা রাখে, এবং Get-VpnConnection তার জানা প্রতিটি প্রোফাইলের জন্য ConnectionStatus দেয়। Windows ক্লায়েন্ট বা provisioning প্যাকেজে তৈরি প্রোফাইল এখানে দেখা যায়। এই cmdlet সাধারণ টানেল শনাক্তকারী নয়।
নামযুক্ত প্রোফাইলের জন্য ফিল্ডটি পড়ুন, প্রোফাইল সব ব্যবহারকারীর হলে -AllUserConnection যোগ করুন:
Get-VpnConnection -Name "Fabrikam" | Select-Object Name, ConnectionStatus, ServerAddress
তৃতীয় পক্ষের ক্লায়েন্ট প্রায়ই তাদের টানেল চালু থাকলেও এই cmdlet-এর কাছে অদৃশ্য থাকে, তাই খালি ফলাফল মানে অজানা, সংযোগ বিচ্ছিন্ন নয়। অ্যাডাপ্টার তালিকাও সমান বিভ্রান্তিকর: ভেন্ডর অ্যাডাপ্টার নিষ্ক্রিয় থেকেও টিকে থাকতে পারে, আর কিছু অ্যাডাপ্টার কেবল সেশন চলাকালে থাকে। Windows-এর মালিকানাধীন প্রোফাইলের জন্য rasdial একটি exit code জানায় যা দিয়ে শাখা করা যায়। এগুলো সবই স্থানীয় বিশ্বাস বর্ণনা করে, পিয়ারের রিচেবিলিটি নয়।
স্ট্যাটাস প্লাস রুট: দুই অংশের যাচাই
সংযুক্ত প্রোফাইল প্যাকেট কোথায় যায় তা কিছুই বলে না। split tunneling টানেল চালু রেখে আপনার প্রয়োজনীয় গন্তব্য বাদ দিতে পারে। always-on প্রোফাইল মৃত সার্ভারের সঙ্গে সংযুক্ত থাকে, আর kill switch টানেল পড়লে উদ্দেশ্যেই ট্রাফিক ব্লক করে।
দুই স্তরই পরীক্ষা করুন: VPN ট্রান্সপোর্ট বা প্রোফাইল সক্রিয় কি না নিশ্চিত করুন, তারপর গন্তব্যটি রিজলভ হয় এবং সেই পথে উত্তর দেয় কি না নিশ্চিত করুন। Linux-এ কার্নেলকে জিজ্ঞাসা করুন কোন ইন্টারফেস ব্যবহার করবে:
ip route get 192.0.2.10
resolvectl query intranet.example.test
ক্লায়েন্ট আপনার নিয়ন্ত্রণের বাইরে হলে দুই ফলাফলই লগ করুন এবং প্যাটার্নটিকে স্তর দেখাতে দিন। সংযুক্ত এবং ব্যর্থ রুট টেস্ট split tunneling, DNS বা পলিসি নির্দেশ করে। সংযোগ বিচ্ছিন্ন এবং সফল রুট টেস্ট মানে অন্য পথ ট্রাফিক বহন করছে।
ধাপে ধাপে চালানো যায় এমন একটি টেস্ট
যেকোনো নেটওয়ার্ক অবস্থা বদলানোর আগে প্রথমে প্ল্যাটফর্ম স্ট্যাটাস রেকর্ড করুন। হোস্টনেম রিজলভ করুন এবং ঠিকানা পরিবার নোট করুন, কারণ AAAA রেকর্ড A রেকর্ডের চেয়ে ভিন্ন পথ নিতে পারে। সেবার পোর্ট খুলুন এবং শুধু হ্যান্ডশেক নয়, অ্যাপ্লিকেশন উত্তর দাবি করুন। প্রতিটি পর্যবেক্ষণ আলাদা লগ ফিল্ডে রাখুন।
dig ও curl থাকা Linux বক্সে তিনটি কমান্ড রিজলিউশন, রুট ও সেবাটি নিজেই ঢাকে। টানেল চালু অবস্থায় এবং আবার বন্ধ অবস্থায় চালান:
dig +short intranet.example.test
ip route get 198.51.100.20
curl -sS -o /dev/null -w "%{http_code}" --max-time 8 https://intranet.example.test/health
চারটি আলাদা ফিল্ড একটি boolean-এর চেয়ে ভালো, কারণ স্ট্যাটাস, DNS, রুট ও পলিসি স্বাধীনভাবে ব্যর্থ হয় এবং ভিন্ন টিমে গিয়ে পড়ে। টার্মিনালে ping হাতে করা ভালো স্যানিটি চেক থাকে। অটোমেশনের জন্য এটি সংযোগের দুর্বল সংজ্ঞা, যেখানে প্ল্যাটফর্ম API ও রুট টেস্ট প্রকৃত প্রশ্নের উত্তর দেয়।