কেন আপনার Android অ্যাপ সিস্টেম VPN প্রোফাইল যোগ করতে পারে না
VpnService এমন একটি টানেল তৈরি করে যা আপনার অ্যাপের মালিকানাধীন; এটি ফোনের PPTP, L2TP বা IPsec এন্ট্রি যোগ বা সম্পাদনা করতে পারে না। সীমারেখাটি অনুসরণ করুন এবং সঠিক পথ বেছে নিন।
আপনি সেটিংসে VPN সারিতে ট্যাপ করেন, অন্য কেউ ইনস্টল করা একটি প্রোফাইল দেখেন, এবং সেটি যোগ করার কলটি খুঁজতে শুরু করেন। এমন কোনো কল নেই। একটি অ্যাপ VpnService-এর মাধ্যমে নিজের একটি টানেল খুলতে পারে, কিন্তু সেই তালিকার এন্ট্রিগুলো প্ল্যাটফর্মের এবং যে ক্লায়েন্ট সেগুলো তৈরি করেছে তার। রেখাটি ঠিক কোথায় পড়ে তা জানলে লুকানো ক্লাসের পেছনে ছোটার এক সপ্তাহ বেঁচে যায়।
সেটিংস স্ক্রিন যা দেখায় তা দিয়েই শুরু করুন
VPN তালিকাটি সিস্টেম বা কোনো ভেন্ডর ক্লায়েন্টের ইনস্টল করা প্রোফাইলের একটি রেজিস্ট্রি: PPTP, L2TP/IPsec, IKEv2, এবং OEM অ্যাপ বা MDM যে সারিগুলো ঠেলে দিয়েছে। প্রতিটি সারিতে একটি সার্ভার ঠিকানা, ক্রেডেনশিয়াল এবং একটি প্রোটোকল বাস্তবায়ন থাকে যা আপনার প্রসেসের বাইরে বাস করে। যখন ব্যবহারকারী সেখানে সংযোগে ট্যাপ করেন, টানেলটি তোলে প্ল্যাটফর্ম ক্লায়েন্ট, আপনার কোড নয়। এজন্যই সারিটি রিবুটের পরেও টেকে এবং এজন্যই আপনার অ্যাপ আনইনস্টল করলে সেটি কখনো সরে না।
ব্যবহারকারীর দিক থেকে তালিকাটি একটি API পৃষ্ঠের মতো দেখায়, এমন জায়গা যেখানে VPN যোগ করা এক ইঙ্গিতের দূরত্বে হওয়া উচিত। তা নয়। এটিকে স্পর্শ করে এমন একমাত্র পাবলিক এন্ট্রি পয়েন্ট হলো নেভিগেশন ইঙ্গিত, এবং এতে যা লেখে সবই প্ল্যাটফর্ম বা একটি বিশেষাধিকারপ্রাপ্ত কম্পোনেন্টের।
ব্যবহারিক পরিণতি: কোনো সাপোর্ট স্ক্রিপ্ট যদি ব্যবহারকারীদের সেটিংসে প্রোফাইল যোগ করতে বলে, তবে আপনার অ্যাপ সেই প্রবাহের অংশই নয়।
VpnService আসলে আপনাকে কী দেয়
VpnService এবং VpnService.Builder একটি টানেল বর্ণনা করে যা আপনার অ্যাপের মালিকানাধীন। আপনি ঠিকানা, রুট, DNS সার্ভার এবং একটি MTU যোগ করেন, addAllowedApplication() বা addDisallowedApplication() দিয়ে ট্রাফিকের পরিধি ঠিক করেন, তারপর establish() একটি TUN ইন্টারফেসের জন্য ParcelFileDescriptor ফেরত দেয়। সেই মুহূর্ত থেকে অ্যাপ IP প্যাকেট পড়ে ও উত্তর লেখে, অর্থাৎ প্রোটোকলটি বাস্তবায়ন বা এমবেড করা আপনার দায়িত্ব: OpenVPN, WireGuard, একটি কাস্টম ট্রান্সপোর্ট।
সেই ধারাবাহিকতায় কিছুই PPTP, L2TP/IPsec বা IKEv2 বলে না। Builder-এ এমন কোনো সুইচ নেই যা বলে সিস্টেমের L2TP ক্লায়েন্ট ব্যবহার করুন, এবং এমন কোনো কলব্যাক নেই যা আপনাকে প্ল্যাটফর্ম ইতিমধ্যেই যার মালিক সেই প্রোফাইল চালাতে দেয়। এটাই আসল সীমা, এবং এটি অনুমতির ফাঁক নয়, নকশার সীমা।
তাই একটি অ্যাপ Android-এ নিশ্চিতভাবেই VPN ক্লায়েন্ট হতে পারে। শুধু ফোনের সঙ্গে আসা ক্লায়েন্টগুলোর ম্যানেজার হতে পারে না।
সম্মতির ডায়ালগ সাজসজ্জা নয়
যেহেতু আপনার টানেল অন্য অ্যাপের ট্রাফিক ধরতে পারে, সিস্টেম ব্যবহারকারীকে তা স্পষ্টভাবে অনুমোদন করতে বাধ্য করে। prepare() একটি Intent ফেরত দেয় যা আপনাকে চালু করতে হবে, অনুমোদনটি আপনার প্যাকেজের সঙ্গে বাঁধা, এবং টানেল চালু থাকাকালে স্ট্যাটাস বারে একটি স্থায়ী সূচক দেখায়। দ্বিতীয় কোনো VPN উঠলে প্রথমটি নিষ্ক্রিয় হয়, কারণ Android একসঙ্গে একটি সক্রিয় VPN চালায়।
এক-সক্রিয় নিয়মটি পরীক্ষার সময় মানুষকে বিভ্রান্ত করে। কর্পোরেট ক্লায়েন্ট সংযুক্ত থাকা অবস্থায় আপনি নিজের টানেল তোলেন এবং সিদ্ধান্তে আসেন যে আপনার কোড ভাঙা, অথচ প্ল্যাটফর্ম কেবল অন্য ক্লায়েন্ট থেকে সরে গেছে। অনুমোদন পরে প্রত্যাহার করা যায়, এবং যে ডিভাইসে সম্মতি অ্যাক্টিভিটি নেই সেখানে prepare() null ফেরত দিতে পারে, তাই establish()-কে এখনো ব্যর্থতা সামলাতে হয়।
লুকানো API এবং সেটিংস ইঙ্গিত
পুরোনো উত্তরগুলো com.android.internal ক্লাস এবং AIDL ইন্টারফেসের দিকে ইশারা করে যা বিল্ট-ইন ক্লায়েন্ট ব্যবহার করে। সেগুলো SDK-তে নেই, রিলিজের মধ্যে না জানিয়ে বদলে যায়, এবং অ্যাপ স্টোর সেই অ্যাক্সেসকে ঝুঁকি হিসেবে দেখে। ডিভাইস রুট করলেও সেগুলো স্থিতিশীল হয় না, কারণ root এবং লুকানো API অ্যাক্সেস দুটি আলাদা সমস্যা।
সমর্থিত নেভিগেশন সহায়কটি হলো Settings.ACTION_VPN_SETTINGS, যার মান android.net.vpn.SETTINGS। চালু করার আগে এটি রিজলভ করুন, কারণ কিছু OEM বিল্ড সেই অ্যাক্টিভিটি দেয় না, আর রিজলভ ব্যর্থ হলে লিখিত ধাপে ফিরে যান। এটি ব্যবহারকারীকে স্ক্রিনে নিয়ে যায় এবং কিছুই কনফিগার করে না।
ডিভাইস-মালিক এবং MDM পথগুলোই সাধারণত মানুষ যে ব্যতিক্রম বোঝায়। DevicePolicyManager একটি সর্বদা-চালু VPN প্যাকেজ নির্ধারণ করতে পারে, এবং ম্যানেজড কনফিগারেশন এমন ক্লায়েন্টের জন্য সেটিংস প্রিলোড করতে পারে যে সেগুলো সমর্থন করে, কিন্তু এটা এখনো পাবলিক SDK দিয়ে PPTP প্রোফাইল লেখা নয়।
ব্যবহারকারীর দিক থেকে সিদ্ধান্তটি হেঁটে দেখুন
আপনার পণ্যকে ট্রাফিক বহন করতে হলে VpnService এবং একটি প্রকৃত প্রোটোকল স্ট্যাকের পরিকল্পনা করুন, আর সম্মতি প্রবাহ ও এক-VPN নিয়মের জন্য সময় রাখুন। লক্ষ্য যদি বিদ্যমান কর্পোরেট প্রোফাইলে সংযোগ করা হয়, তবে আপনার কাজ পথনির্দেশ: সেটিংস স্ক্রিনে ডিপ-লিংক দিন, ফিল্ডগুলো নথিভুক্ত করুন, এবং টানেলিং প্ল্যাটফর্ম ক্লায়েন্টকেই করতে দিন। অ্যাপের যদি কেবল একটি ব্যক্তিগত এন্ডপয়েন্টে পৌঁছাতে হয়, তবে তার নিজের টানেলের আদৌ দরকার নেই।
কোড লেখার আগে সেই সিদ্ধান্ত লিখে রাখুন, কারণ প্রথম স্প্রিন্টের পরে তিনটি পথের মধ্যে প্রায় কিছুই মিল নেই।
শুরু করার আগে শেষ পরীক্ষা: প্রয়োজনটি কি বলে আমাদের অ্যাপ সংযোগ করে, নাকি ডিভাইস সংযোগ করে? প্রথমটি VpnService, দ্বিতীয়টি এমন প্রোফাইল যা আপনি তৈরি করতে পারেন না। ওই বাক্যটি ঠিক করা যেকোনো রিফ্যাক্টরের চেয়ে সস্তা।