রুট ছাড়া অ্যান্ড্রয়েড VPN: সম্মতি, রুট ও ব্লকিং কার অধিকারে
সম্মতি, TUN ইন্টারফেস এবং সিস্টেমের ব্লকিং নীতিমালা তিনটি আলাদা অনুমতি। অ্যান্ড্রয়েড VPN অ্যাপ পর্যালোচনা করার আগে প্রতিটির মালিক কোন উপাদান তা চিহ্নিত করুন।
অ্যান্ড্রয়েড VPN অ্যাপকে ট্রাফিক বহন করা, লিক ব্লক করা বা রিবুটের পরেও টিকে থাকা সম্ভব করে তোলে রুট নয়। মানুষ এসবকে একসাথে „অ্যাপটির VPN অনুমতি আছে“ বলে সারসংক্ষেপ করে, যা তিনটি আলাদা প্রক্রিয়া লুকিয়ে রাখে: ব্যবহারকারীর দেওয়া সম্মতি, সিস্টেম যে প্যাকেট ইন্টারফেস তৈরি করে, এবং প্ল্যাটফর্মের ব্লকিং নীতিমালা যা নির্ধারণ করা অ্যাপের কাজ নয়। অ্যান্ড্রয়েড VPN ডিজাইন পর্যালোচনা মানে জিজ্ঞাসা করা কোনো দাবি আসলে এই তিনটির কোনটির উপর দাঁড়িয়ে আছে, কারণ প্রতিটির মালিক ও ব্যর্থতার ধরন আলাদা।
সম্মতি আসে একটি সিস্টেম অ্যাক্টিভিটির মাধ্যমে
VpnService.prepare() কোনো কিছু দেয় না। সম্মতি না থাকলে এটি সিস্টেম সম্মতি অ্যাক্টিভিটি-তে একটি intent ফেরত দেয়, এবং অ্যাপ সেই ডায়ালগ চালু করে যাতে ব্যবহারকারী সেবাটি অনুমোদন করতে পারেন। অ্যাপের নিজস্ব প্রসেস চালু করা, ম্যানিফেস্টে অনুমতি যোগ করা, বা কাস্টম „VPN চালু করুন“ স্ক্রিন দেখানো সম্মতি তৈরি করে না।
সম্মতিটি পরিধিতেও সীমিত। এটি একটি ব্যবহারকারী প্রোফাইলের একটি প্যাকেজের অন্তর্গত, তাই ব্যক্তিগত কপি ও কাজের কপি আলাদা সিদ্ধান্ত, এবং ডিভাইস মালিক একটি ম্যানেজড প্রোফাইলকে ব্যক্তিগত প্রোফাইল থেকে ভিন্নভাবে প্রস্তুত করতে পারেন। ডায়ালগ কখনো না দেখালে এবং prepare() null ফেরত দিলে, সেই প্রোফাইলে সেই প্যাকেজের সম্মতি আগেই আছে; এটি অ্যাপের বিশ্বস্ততার প্রমাণ নয়, শুধু সম্মতি আছে বোঝায়।
ইন্টারফেস হলো একটি অনুরোধ যা সিস্টেম পূরণ করে
সম্মতির পরে অ্যাপ VpnService.Builder দিয়ে জানায় কী চায়: ঠিকানা, রুট, DNS সার্ভার, MTU এবং যেখানে সমর্থিত, অন্তর্ভুক্ত বা বাদ দেওয়ার অ্যাপ। establish() সিস্টেমকে টানেল ইন্টারফেস তৈরি করে মিলে যাওয়া ট্রাফিক সেখানে পাঠাতে বলে। রাউটিং সিদ্ধান্ত সিস্টেমের; অ্যাপ ফাইল ডেসক্রিপ্টর পায় এবং এরপর প্যাকেটগুলো দিয়ে কিছু কাজ করতে হয়।
| What you observe | Who actually owns it |
|---|---|
| VPN consent dialog | The system, triggered by prepare() |
| Routes, DNS and app lists | The app requests them; the system applies them |
| One active VPN per profile | The platform; a new service replaces the old one |
| Always-on and block-without-VPN | Device policy enforced by the platform |
এই টেবিলটি এক জায়গায় স্থাপত্য। অ্যাপ প্যাকেট হ্যান্ডলিংয়ে অংশ নেয়; ইন্টারফেস, রাউটিং টেবিল বা কতগুলো সেবা চলতে পারে তা তার নয়।
টানেল সকেটকে নিজের টানেল থেকে বের হতে হয়
এনক্রিপ্টেড ট্রাফিক বহনকারী সংযোগটি নিজেই একটি সকেট। যদি এটি অ্যাপের সদ্য তৈরি করা ইন্টারফেসে ফিরে যায়, তাহলে টানেল টানেলের উপর নির্ভর করে আটকে যায়। VpnService.protect() সেই সকেটকে অন্তর্নিহিত নেটওয়ার্কে বেঁধে দেয় যাতে এটি ক্যাপচার এড়িয়ে যায়, এজন্য সঠিক ক্লায়েন্ট প্রথম হ্যান্ডশেকের আগে তার বাইরের সকেট সুরক্ষিত করে।
adb shell dumpsys connectivity | grep -i -A5 vpn
adb shell settings get global always_on_vpn_app
adb shell settings get global always_on_vpn_lockdown
এই কমান্ডগুলো ইনস্টল করা VPN নেটওয়ার্ক, অলওয়েজ-অন প্যাকেজ এবং লকডাউন সেট আছে কি না দেখায়। এগুলো কেবল পঠনযোগ্য পর্যবেক্ষণ: মানগুলো ডিজাইনের দাবির সাথে না মিললে দাবিটি সিস্টেমের অবস্থা নয়, অ্যাপের UI সম্পর্কে।
ব্লকিং প্ল্যাটফর্মের হতে পারে
অ্যান্ড্রয়েড এমন একটি নীতিমালা নথিভুক্ত করে যা VPN ব্যবহার করে না এমন সংযোগ ব্লক করে। সেই প্রয়োগ প্ল্যাটফর্মের চুক্তি, অ্যাপের লুপে সংযোগ পুনরায় চেষ্টা নয়। সুইচটি ডিভাইসের VPN সেটিংসে „VPN ছাড়া সংযোগ ব্লক করুন“ হিসেবে থাকে, এবং ম্যানেজড ডিভাইসে ডিভাইস মালিক এটি পুরো প্রোফাইলের জন্য চালু করতে পারেন। মার্কেটিং দাবি মূল্যায়নের সময় এই পার্থক্য জরুরি: ক্লায়েন্ট তালার আইকন দেখিয়ে জোরালোভাবে পুনরায় সংযোগ করতে পারে অথচ সরাসরি ট্রাফিক তখনো সম্ভব, অথবা আওতাভুক্ত অ্যাপ অফলাইন থাকতে পারে কারণ সিস্টেম লকডাউন প্রয়োগ করছে।
তালার আইকন অ্যাপ আঁকে, তাই এটি কেবল প্রমাণ করে অ্যাপ মনে করে সে সংযুক্ত। অন্য অ্যাপ নেটওয়ার্ক অ্যাক্সেস হারাবে কি না তা প্ল্যাটফর্ম ঠিক করে, তাই কার্যকর পরীক্ষা হলো টানেল চালু থাকা অবস্থায় সেই অ্যাপ ব্যর্থ হতে দেখা।
অ্যাপ স্টোরের „অলওয়েজ অন“ লেবেলও সেই চুক্তি প্রতিস্থাপন করে না। অলওয়েজ-অন ও লকডাউন ডিভাইস সেটিংস, প্রায়ই ডিভাইস মালিক প্রয়োগ করেন, এবং বাদ দেওয়া অ্যাপের জন্য তাদের আচরণ প্ল্যাটফর্ম নির্ধারণ করে। ব্যাজ নয়, সেটিং পড়ুন।
ডিজাইন পর্যালোচনার জন্য চারটি প্রশ্ন
প্রথম, কে সম্মতি দিয়েছে: কোন প্যাকেজ, কোন প্রোফাইল, এবং এটি ব্যবহারকারী না ম্যানেজড-ডিভাইস নীতিমালা? দ্বিতীয়, অ্যাপ কী চেয়েছে: কোন রুট, কোন ঠিকানা পরিবার, কোন অ্যাপ অন্তর্ভুক্ত বা বাদ? তৃতীয়, টানেল অনুপলব্ধ হলে কী হয়: সিস্টেম ব্লক করে, না ট্রাফিক অন্তর্নিহিত নেটওয়ার্কে ফিরে যায়? চতুর্থ, অ্যাপ যে প্যাকেট পায় তা দিয়ে কী করে?
চতুর্থ প্রশ্নটির উত্তর অনুমতি মডেল দিতে পারে না। সম্মতি ও TUN ইন্টারফেস প্রমাণ করে অ্যাপ ট্রাফিক পেতে পারে, কিন্তু তা এনক্রিপ্ট করে, প্রান্ত যাচাই করে বা পরিষ্কারভাবে পুনরুদ্ধার করে তা নয়। এসব বাস্তবায়নের বৈশিষ্ট্য, আর সৎ পর্যালোচনা এখানেই সময় ব্যয় করে।
অপ্রয়োজনীয় রুট অনুরোধকে ফলাফলের নাম কিল সুইচ দিলে তা বৈধ হয় না, আর সম্মতি ডায়ালগ কোনো নিরাপত্তা নিরীক্ষা নয়। তিনটি অনুমতি আলাদা রাখুন, প্রতিটি দাবি যাচাইযোগ্য হয়ে যায়।