Android-এ main টেবিলে যোগ করা একটি রুট প্রতিটি তালিকায় সঠিক দেখায় এবং তবুও ট্রাফিক বহন করে না। কারণ হলো main টেবিল কয়েকটি বিকল্পের মধ্যে একটি, এবং সেটিকে প্রথমে দেখা হয় না। Android-এর নেটওয়ার্কিং সার্ভিস এমন নীতি-নিয়ম তৈরি করে যা গন্তব্য ঠিকানায় না থাকা তথ্য দিয়ে রাউটিং টেবিল বেছে নেয় — অ্যাপের uid, প্যাকেটে থাকা মার্ক, প্যাকেটটি যে ইন্টারফেস দিয়ে এসেছে — আর গন্তব্যের লুকআপ ঘটে তার পরে, সেই নিয়মগুলি যে টেবিল বেছে নিয়েছে তার ভেতরে।

নির্দিষ্ট ক্রমে তিনটি সিদ্ধান্ত

বেরিয়ে যাওয়া একটি প্যাকেট তিনটি আলাদা সিদ্ধান্ত নেয়। প্রথমত, একটি নীতি-নিয়ম ঠিক করে কোন রাউটিং টেবিল প্রযোজ্য। দ্বিতীয়ত, সেই টেবিলের ভেতরের একটি রুট পরবর্তী হপ ও বহির্গামী ইন্টারফেস ঠিক করে। তৃতীয়ত, netfilter হুক ঠিক করে প্যাকেটটি টিকে থাকবে, পরিবর্তিত হবে, নাকি পুনঃনির্দেশিত হবে।

ক্রমটি গুরুত্বপূর্ণ কারণ প্রতিটি ধাপ কেবল নিজের প্রশ্নের উত্তর দিতে পারে। যে ফায়ারওয়াল নিয়ম প্যাকেট গ্রহণ করে সেটি টেবিল বেছে নেয় না, আর যে টেবিলকে কোনো নিয়ম বেছে নেয় না সেখানে যোগ করা রুট নিষ্ক্রিয় থাকে। Android VPN নিয়ে বেশিরভাগ বিভ্রান্তি আসে তিনটির একটি ঠিক করে কোনো পরিবর্তন না দেখায়, কারণ ত্রুটিটি ছিল অন্যটিতে।

StageSelectorWhat it cannot decide
Policy ruleuid range, mark, incoming interfaceWhich route exists inside the table
Route lookupDestination prefix, longest matchWhether the packet is allowed out
Netfilter hookChain position, match conditionsWhich table was selected

মার্ক হলো প্যাক করা একটি ফিল্ড, আপনার মালিকানার লেবেল নয়

Android একই মার্ক মানের মধ্যে কয়েকটি তথ্য প্যাক করে: কোন নেটওয়ার্ক বেছে নেওয়া হয়েছে, কোনো অ্যাপ স্পষ্টভাবে নেটওয়ার্ক বেছেছে কি না, কোনো সকেট VPN থেকে সুরক্ষিত কি না, এবং অনুমতি-সংশ্লিষ্ট বিট। AOSP fwmark হেডার বর্তমান ট্রির জন্য সেই বিন্যাস নির্ধারণ করে, আর বিন্যাসটি প্ল্যাটফর্মের অভ্যন্তরীণ বিষয় যা রিলিজের মধ্যে বদলায়।

এই কারণেই iptables -j MARK --set-mark দিয়ে পুরো একটি মার্ক মান লেখা Android-এ বিপজ্জনক। এটি কোনো ট্যাগ যোগ করে না; এটি সিস্টেম ইতিমধ্যে যে নেটওয়ার্ক নির্বাচন করেছে তা প্রতিস্থাপন করে। এরপর প্যাকেট ভিন্ন নিয়মের সঙ্গে মিলে যায়, যা দেখে মনে হতে পারে VPN কাজ শুরু করেছে, বা অসম্পর্কিত কোনো অ্যাপ সংযোগ হারিয়েছে — কোন বিটগুলি পুনরায় লেখা হয়েছে তার উপর নির্ভর করে।

যদি মার্ক ছুঁতেই হয়, প্রথমে বর্তমান মান পড়ুন এবং মাস্ক ব্যবহার করুন যাতে কেবল আপনি যে বিটগুলি বোঝেন সেগুলোই পরিবর্তিত হয়:

ip rule show
ip route show table all | head -40
ip route get 10.20.4.11

সংযোগ মার্ক প্যাকেট মার্ক থেকে আলাদা বস্তু, এবং কোনোটিই রুট নয়। উত্তরের প্যাকেটে মার্ক পুনরুদ্ধার করা বেরোনোর পথে টেবিল বেছে নেওয়ার থেকে আলাদা ধাপ, তাই একমুখী সমাধান এমন সংযোগ তৈরি করে যা খোলে এবং পরে আটকে যায়।

নিয়ম ও টেবিলের মালিক কে

Android-এর নেটওয়ার্ক সার্ভিস netd নিয়ম ও প্রতি-নেটওয়ার্ক টেবিল তৈরি করে। AOSP RouteController-এ VPN, ভৌত নেটওয়ার্ক ও uid রেঞ্জের জন্য সেই নিয়মগুলি একত্র করা হয়, এবং এর জীবনচক্র কনফিগ ফাইলের বদলে নেটওয়ার্ক ঘটনার সঙ্গে বাঁধা।

এখান থেকে দুটি পরিণতি আসে। প্রথমত, একটি হ্যান্ডসেটে যে অগ্রাধিকার ও টেবিল নম্বর পাবেন সেগুলো বিল্ডের অভ্যন্তরীণ বিষয়, ইন্টারফেস নয়: অন্য Android সংস্করণে একই রকম দেখানো নম্বর সম্পূর্ণ ভিন্ন কিছু বোঝাতে পারে। দ্বিতীয়ত, নেটওয়ার্ক বদলালে অবস্থা পুনরায় তৈরি হয়, তাই আজ root শেল থেকে যোগ করা নিয়ম পরবর্তী Wi-Fi পরিবর্তনের পরে না-ও থাকতে পারে।

এই অন্তর্ধানকে প্রায়ই বলা হয় সিস্টেম একটি রুট উপেক্ষা করছে। আসলে ঘটেছে যে টেবিলটি বেছে নেওয়া নিয়মটির আর অস্তিত্ব নেই, আর টেবিলের ভেতরের রুটটি এখন প্যাকেটের দৃষ্টিতে অপ্রাপ্য। পুনঃসংযোগের পরে কাজ করা কনফিগারেশন কাজ করা বন্ধ করলে রুট তালিকা নয়, নিয়ম তালিকা দেখুন।

হুকের ক্রম নিয়ে প্রশ্নের সর্বজনীন উত্তর নেই

iptables VPN রাউটিংয়ের আগে চলে কি না — প্যাকেটের পথ না বললে এর উত্তর দেওয়া যায় না। স্থানীয়ভাবে তৈরি প্যাকেট output হুক অতিক্রম করে, যেখানে মার্ক পরিবর্তন পুনঃরাউটিং পরীক্ষা চালায় — দ্বিতীয় লুকআপ, প্রথমটির পিছনে গিয়ে সম্পাদনা নয়। tether করা ক্লায়েন্ট থেকে আসা প্যাকেট prerouting পথে যায় এবং বরং ফরওয়ার্ড হয়, আর যে চেইনগুলি সেটি দেখে সেগুলি ভিন্ন।

তাই একই নিয়ম একটি অ্যাপের ট্রাফিকের জন্য কার্যকর এবং tether ট্রাফিকের জন্য অদৃশ্য হতে পারে, আর শূন্যে থাকা কাউন্টার আপনাকে বলে প্যাকেট কোন পথে গেছে, নিয়মটি ভুল কি না তা নয়। কোনো মিলের শর্ত বদলানোর আগে কাউন্টার দিয়ে পথটি প্রতিষ্ঠা করুন।

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

সিস্টেমের ভেতরে নির্ণয় করুন, নয়তো হাত দিন না

অনুমোদিত পর্যালোচনার জন্য কিছু ছোঁয়ার আগে চারটি তথ্য প্রতিষ্ঠা করুন: অ্যাপের uid ও প্রোফাইল, Android তার জন্য যে নেটওয়ার্ক বেছেছে, VPN আদৌ সেই অ্যাপকে অন্তর্ভুক্ত করে কি না, এবং সমস্যাটি দুই ঠিকানা পরিবারেই আছে কি না। প্রতি-অ্যাপ বাদ দেওয়া কোনো রাউটিং ত্রুটি ছাড়াই অনেক VPN কাজ করছে না রিপোর্ট ব্যাখ্যা করে।

তারপর প্রকৃতপক্ষে কার্যকর নিয়ম, মাস্ক ও টেবিল পড়ুন, আর পর্যবেক্ষণ-জানালার মধ্যে একটি নেটওয়ার্ক পরিবর্তন রাখুন। পুনঃসংযোগের মধ্যে আচরণ বদলালে আপনি দেখছেন পরিচালিত জীবনচক্র, অনুপস্থিত রুট নয়।

সাধারণ প্রয়োজনে সমর্থিত নিয়ন্ত্রণ ব্যবহার করুন: প্রতি-অ্যাপ অন্তর্ভুক্তি ও বাদ VPN অ্যাপ্লিকেশনে, এবং নির্দিষ্ট পথ দরকার এমন সবকিছুর জন্য প্ল্যাটফর্মের নিজস্ব নেটওয়ার্ক নির্বাচন। যদি কোনো বিশেষাধিকারী ইন্টিগ্রেশন সত্যিই রাউটিং মেশিনারির সঙ্গে সহযোগিতা করতে হয়, আপনি যে নির্দিষ্ট Android সংস্করণ সমর্থন করেন তার বাস্তবায়নকে লক্ষ্য করুন এবং যে কম্পোনেন্ট এর মালিক তার মাধ্যমে এর জীবনচক্র রক্ষণাবেক্ষণ করুন। প্ল্যাটফর্ম চেইন ফ্লাশ করা বা উচ্চ-অগ্রাধিকার নিয়ম সন্নিবেশ করা تشخیصকে দ্বিতীয় নেটওয়ার্ক ম্যানেজারে পরিণত করে, আর ফোন সেই অনুযায়ী আচরণ করবে।

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