Android VpnService অ্যালাউলিস্ট: অনুমোদিত পেজগুলো কেন এখনও আটকে থাকে
আপনার অ্যালাউলিস্ট সম্ভবত ঠিকই আছে। পেজ আটকে থাকে DNS উত্তর, রুট টেবিল, রিজলভার সকেট বা MTU-এর কারণে। যাচাইয়ের ক্রম এখানে।
আপনি একটি ডোমেইন অ্যালাউলিস্টে যোগ করেছেন, কোয়েরি আপনার অ্যাপে পৌঁছেছে, ম্যাচার অনুমোদিত ফেরত দিচ্ছে, তবুও পেজটি কখনও লোড হয় না। সেই পর্যায়ে বেশিরভাগ মানুষ ম্যাচার পুনর্লিখন শুরু করেন এবং ওয়াইল্ডকার্ড তুলনা যোগ করেন। আমার অভিজ্ঞতায় ম্যাচার সাধারণত সঠিক থাকে, এবং ব্যর্থতা একটি স্তর পরে বসে: আপনার তৈরি করা DNS উত্তরে, আপনার ইনস্টল করা রুটে, বা কোয়েরি ফরওয়ার্ড করতে ব্যবহৃত সকেটে। তালিকাটি সহজ অংশ; প্যাকেট পথই সেই জায়গা যেখানে অ্যালাউলিস্ট ভেঙে যায়।
ম্যাচারই বিরল ক্ষেত্রে দোষী
প্রথমে আলাদা করতে হবে ব্লকড আর ভাঙা। ব্লকড নাম দ্রুত এবং দৃশ্যমানভাবে ব্যর্থ হওয়া উচিত, কারণ ব্রাউজার এমন উত্তর পায় যে নামটির অস্তিত্ব নেই এবং থেমে যায়। ভাঙা নাম আটকে থাকে, IPv6 দিয়ে আবার চেষ্টা করে, অন্য ট্রান্সপোর্টে গিয়ে পড়ে, এবং আপনাকে একটি ঘুরন্ত চিহ্ন দিয়ে রেখে যায়। আপনি যদি ঘুরন্ত চিহ্ন দেখেন, তাহলে আপনার অ্যালাউলিস্ট সম্ভবত এমন কিছু উত্তর দিচ্ছে যা নিয়ে ক্লায়েন্ট কিছু করতে পারে না।
খালি A রেকর্ড ক্লাসিক ভুল। শূন্য উত্তরে NOERROR ফেরত দেওয়া বৈধ উত্তর বলে মনে হয়, তাই stub রিজলভার তা গ্রহণ করে, ব্রাউজার আবার চেষ্টা করে, AAAA চেষ্টা করে, অন্য রিজলভার চেষ্টা করে, এবং অনেক পরে হাল ছেড়ে দেয়। উত্তর কোড 3, অর্থাৎ NXDOMAIN, প্রশ্ন অংশ পুনরাবৃত্তি ও ট্রানজ্যাকশন আইডি কপি করে দিলে কথোপকথন সঙ্গে সঙ্গে শেষ হয়ে যায়। আপনি ইচ্ছাকৃতভাবে যে নাম প্রত্যাখ্যান করেন তার প্রত্যেকটির জন্য এটি ব্যবহার করুন।
IPv6-ও ডিফল্ট নয়, একই সিদ্ধান্ত পাওয়ার যোগ্য। আপনি যদি A-এর জন্য NXDOMAIN উত্তর দেন এবং AAAA পার হতে দেন, ক্লায়েন্ট IPv6 দিয়ে ব্লকড নামে পৌঁছাতে পারে এবং ফিল্টার ফাঁস হয়। কিছু বাস্তবায়ন ব্লকড AAAA কোয়েরির উত্তর loopback ঠিকানা দিয়ে দেয়, যাতে সংযোগ ফলব্যাক না করে সঙ্গে সঙ্গে ব্যর্থ হয়। একটি নীতি বেছে নিন, তা দুই ধরনের রেকর্ডেই প্রয়োগ করুন, এবং দুটোই লগ করুন।
সব কিছু ধরার রুট সব কিছুর মালিক
শুধু DNS-ভিত্তিক নকশা কখনও addRoute("0.0.0.0", 0) যোগ করে না, তাই TUN ইন্টারফেসে কেবল কোয়েরি ঢোকে এবং বাকি সব অন্তর্নিহিত নেটওয়ার্ক ব্যবহার করে চলে। এটাই নিরাপদ আকৃতি, এবং এটিই ব্যাখ্যা করে কেন কিছু অ্যালাউলিস্ট Wi-Fi-তে কাজ করে আর সেলুলারে ব্যর্থ হয়।
ডিফল্ট রুট থাকার মুহূর্তেই প্রতিটি ফ্লো আপনার। যে TCP প্যাকেট ইন্টারফেসে এসে ফরওয়ার্ড হয় না বা উত্তর পায় না, সেটি ক্লায়েন্টের সময় শেষ হওয়া পর্যন্ত সারিতে বসে থাকে, এবং লগ করার মতো কোনো ত্রুটি নেই কারণ কিছুই ত্রুটি দেয়নি। আমি দেখেছি কেউ এক বিকেল নষ্ট করেছে একটি ভাঙা অ্যালাউলিস্টে, যা আসলে পোর্ট 443-এর জন্য অনুপস্থিত ফরওয়ার্ডার ছিল। আপনি যে প্রতিটি প্যাকেট বাদ দিতে চান তার প্রোটোকল ও গন্তব্য লগ করুন।
রিজলভার সকেটকে টানেল থেকে বেরোতেই হবে
ফরওয়ার্ডিংয়েই পরের ফাঁদ বসে। ক্যারিয়ার রিজলভার প্রায়ই এমন ব্যক্তিগত ঠিকানায় থাকে যেখানে টানেল পৌঁছায় না, তাই আপনি যে কোয়েরি ফরওয়ার্ড করেন তা কোথাও যায় না এবং অ্যাপ রিড টাইমআউট জানায়। অনুমোদিত কোয়েরি এমন রিজলভারে পাঠান যেটি পৌঁছানো যায় বলে আপনি জানেন, এবং আগে সেই সকেটটি VpnService.protect()-এ দিন। অরক্ষিত সকেট কোয়েরিটি আপনার নিজের টানেলে ফেরত পাঠায়, যেখানে তা আবার অ্যাপে পৌঁছে টাইমআউট না হওয়া পর্যন্ত ঘুরতে থাকে।
ব্যর্থতাটি নেটওয়ার্ক বিভ্রাটের মতোই দেখায়, তাই এটি বাগ রিপোর্টে এত দিন টিকে থাকে। পাঠানো কোয়েরি ও পাওয়া উত্তরের জন্য কাউন্টার রাখুন: প্রথম সংখ্যা বাড়লে এবং দ্বিতীয়টি শূন্যে থাকলে, আপনি তালিকা নয়, সকেটের দিকে তাকিয়ে আছেন।
আকার ও চেকসাম নিঃশব্দে ব্যর্থ হয়
নীরব বাদ পড়া আকার থেকেও আসে। বড় উত্তর সেটের DNS উত্তর, বা উদার অপশনসহ TCP হ্যান্ডশেক, আপনার কখনও স্পষ্টভাবে না-সেট করা পাথ MTU ছাড়িয়ে যেতে পারে; ফ্র্যাগমেন্টটি উজানে হারিয়ে যায় এবং ক্লায়েন্ট হয় ছোট আকারে আবার চেষ্টা করে, নয়তো চেষ্টা বন্ধ করে দেয়। ইন্টারফেস MTU 1280-এ সেট করা একটি রক্ষণশীল পছন্দ যা বেশিরভাগ সেলুলার পথে টিকে যায়, এবং কেউ না-মাপা ডিফল্ট উত্তরাধিকারে পাওয়ার চেয়ে স্পষ্ট হওয়া ভালো।
আপনি নিজে প্যাকেট বানালে চেকসাম আরেক নীরব ঘাতক। যে সিউডো-হেডারে UDP দৈর্ঘ্য বা প্রোটোকল ফিল্ড বাদ দেওয়া হয়, তার উপর গণনা করা UDP চেকসাম এমন প্যাকেট দেয় যা আপনার দিকে ঠিক দেখায় আর গ্রহণকারী কোনো চিহ্ন ছাড়াই ফেলে দেয়। আপনার সিউডো-হেডার স্পেসিফিকেশনের সঙ্গে ফিল্ড ধরে ধরে মিলিয়ে দেখুন, এবং ডিবাগ করার সময় একটি জানা ফ্লোর জন্য গণনা করা চেকসাম ছাপুন।
VpnService আপনার হয়ে যা করবে না
সেগুলিকে ঘিরে নকশা করার আগে দুটি সীমা জানা দরকার। কোনো সাধারণ অ্যাপ Wi-Fi-এর বাইরে সিস্টেম-ব্যাপী প্রক্সি বা PAC ফাইল ইনস্টল করতে পারে না, এবং এই অংশটি বদলায়নি। প্রতি-অ্যাপ পথ বদলেছে: API 29-এর আগে VpnService.Builder আদৌ প্রক্সি বহন করতে পারত না, আর API 29 থেকে setHttpProxy(ProxyInfo.buildPacProxy(uri)) প্ল্যাটফর্মকে VPN নেটওয়ার্কের জন্য মূল্যায়ন করার একটি PAC স্ক্রিপ্ট দেয়। পুরোনো API লক্ষ্য করলে বা PAC মডেল নিয়মটি প্রকাশ করতে না পারলে নিজের কোডেই নিয়ম মূল্যায়ন করুন। UDP-ও বিনামূল্যে নয়: ব্রাউজার SOCKS প্রক্সির মধ্য দিয়ে কেবল TCP পাঠায়, এবং বেশিরভাগ SOCKS5 ক্লায়েন্ট কখনও UDP ASSOCIATE বাস্তবায়ন করে না, তাই প্রক্সি-ভিত্তিক নকশা UDP ফেলে দেয় বা ফাঁস করে, অথচ TCP সুস্থ দেখায়।
এই দ্বিতীয় সীমাই কারণ যে UDP-ভিত্তিক প্রোটোকল সাধারণ নেটওয়ার্কে কাজ করে, অথচ আপনার VPN সংযোগ হওয়ার মুহূর্তেই ব্যর্থ হয়। যদি টানেলের UDP বহন করার কথা হয়, ফরওয়ার্ডারকে তার জন্য ফরওয়ার্ডিং পথ বাস্তবায়ন করতে হবে, শুধু ভিন্ন সকেট ধরনের TCP পথ নয়।
এই ক্রমে যাচাই করুন
তালিকাটি ক্রমে কাজ করুন এবং যে প্রথম ধাপ ব্যর্থ হয় সেখানেই থামুন, কারণ আগেরটি টিক না দিলে পরের প্রতিটি যাচাই কেবল কোলাহল।
- ইনস্টল করা রুটগুলো তালিকাভুক্ত করুন এবং DNS-বহির্ভূত প্যাকেট আদৌ TUN ইন্টারফেসে ঢোকে কি না নিশ্চিত করুন।
- একটি ব্লকড ও একটি অনুমোদিত নামের জন্য কোয়েরি নাম, সিদ্ধান্ত ও উত্তর কোড লগ করুন।
- রিজলভার সকেট সুরক্ষিত এবং নির্বাচিত রিজলভার টানেলের ভেতর থেকে উত্তর দেয় কি না নিশ্চিত করুন।
- ইন্টারফেস MTU এবং হাতে বানানো একটি উত্তরের চেকসাম নিশ্চিত করুন।
- একই পেজ Wi-Fi ও সেলুলারে পুনরাবৃত্তি করুন, কারণ ক্যারিয়ার রিজলভার আর পাথ MTU আলাদা।
পাঁচটিই টিক দিলে এবং পেজ তবুও আটকে থাকলে, পরের সন্দেহভাজন ফরওয়ার্ডার নিজেই: ধরা একটি অনুরোধের সঙ্গে ধরা একটি উত্তরের তুলনা করুন এবং অনুপস্থিত বাইট সংখ্যা বা অর্ধ-বন্ধ সকেট খুঁজুন। VpnService.Builder রেফারেন্স রুট, DNS ও MTU চুক্তি কভার করে, আর protect() হলো builder অপশন নয়, আলাদা VpnService কল; সংযুক্ত ইন্টারফেস মানে কেবল প্রথম চুক্তিটি সফল হয়েছে।