اقرأ DNS في Android بشكل صحيح: لكل شبكة، لا في resolv.conf
يطابق تطبيق Android لديك عبر resolver خاص بكل شبكة، لا عبر resolv.conf الذي قرأته للتو. افحص أولًا LinkProperties وارتباطات socket وPrivate DNS.
تحصل على shell على الجهاز، وتقرأ /etc/resolv.conf أو تستخرج قيمة net.dns1 قديمة، فتحصل على عنوان واحد. لكن التطبيق الذي أمامك يطابق عبر شيء آخر تمامًا. في إصدار Android الحالي يكون الـ resolver لكل شبكة: يحتفظ النظام بسياسة لكل Network ويطبقها على الـ socket الذي أرسل الطلب. الملف والخاصية القديمة من البقايا، ولا يصف أي منهما المسار الذي سلكه استعلامك فعليًا.
تظهر هذه الفجوة أثناء نشر split-tunnel وPrivate DNS، حيث يمكن لتطبيقين على الهاتف نفسه أن يريا إجابات مختلفة بشكل مشروع. يبدأ هذا الدليل من المطابقة الخاطئة أو الغائبة ويعود إلى الإعداد الذي يملكها.
الـ resolver ينتمي إلى شبكة، لا إلى الجهاز
تمر مطابقة الأسماء في Android 9 وما بعده عبر resolver نظامي يعتمد على Network التي يرتبط بها الـ socket. تحمل كل شبكة LinkProperties الخاصة بها، وتحتوي هذه الخصائص على قائمة خوادم DNS ونطاقات البحث وحالة Private DNS لتلك الشبكة وحدها. لا شيء في هذا النموذج يقابل قائمة واحدة على مستوى الجهاز يمكنك قراءتها من ملف.
يجعل VPN الانقسام واضحًا. عند صعود النفق يوفّر تطبيق VPN خوادم DNS مسجلة على شبكة VPN نفسها، فتطابق التطبيقات الموجّهة عبره على تلك الخوادم بينما تستمر التطبيقات المستبعدة في استخدام الشبكة الأساسية. جهاز واحد، مسارا إجابة، دون تناقض.
اقرأ اللقطة من داخل التطبيق المتأثر
اسأل التطبيق نفسه. يمكن لدالة تملك Context والإذن العادي android.permission.ACCESS_NETWORK_STATE أن تقرأ اللقطة دون لمس خصائص النظام:
val cm = getSystemService(ConnectivityManager::class.java) ?: return
val network = cm.activeNetwork
val links = network?.let { cm.getLinkProperties(it) }
val dnsServers = links?.dnsServers
val privateDnsActive = links?.isPrivateDnsActive
val privateDnsName = links?.privateDnsServerNameactiveNetwork هي الشبكة الافتراضية لعمليةك، وليست الشبكة الوحيدة على الجهاز، وقد تكون null عندما لا يملك المستدعي افتراضيًا صالحًا. VPN افتراضي محجوب هو السبب المعتاد. يخبرك isPrivateDnsActive ما إذا كانت الاستعلامات على تلك الشبكة تمر عبر TLS إلى resolver مسمّى، وهذا يغيّر ما ستظهره لك فحص UDP 53 البسيط. سطح API موثّق تحت LinkProperties، وكل قيمة فيه لقطة إعداد وليست دليلًا على أن استعلامًا معينًا وصل إلى خادم معين.
عندما لا تكون الشبكة الافتراضية هي التي تؤدي العمل
لا تجيب اللقطة إلا عن الافتراضية. يمكن للتطبيق أن يربط عمليته أو socket واحدًا بشبكة أخرى، فيتبع المطابقة ذلك الاختيار بينما لا يزال تشخيصك يبلّغ عن الافتراضية. المتصفح الذي يجلب resolver DNS-over-HTTPS خاصًا به لا يستشير قائمة النظام إطلاقًا، لذا لا تقول إجاباته شيئًا عن بقية الجهاز. تطبيق ملف العمل يعمل تحت مستخدم منفصل بسياسة خاصة به. تحقق من الارتباط قبل أن تلوم الخوادم.
تكامل VPN هو النصف الآخر. تلقّي سطر dhcp-option DNS في ملف OpenVPN وتسجيل ذلك العنوان على شبكة VPN في Android خطوتان منفصلتان، والمسار المفقود إلى الخادم يفشل بهدوء مثل العنوان الخاطئ. من جهاز تطوير، يطبع adb shell dumpsys connectivity خصائص الربط نفسها لكل شبكة عندما يسمح البناء بذلك، ما يؤكد القائمة دون كتابة كود.
قارن الإعداد بمطابقة واحدة يُسمح لك بها
اختر اسمًا يجب أن يُطابق داخل مساحة الأسماء الخاصة واسمًا عامًا واحدًا، وسجّل النتيجتين بجوار اللقطة: الشبكة، والخوادم المهيّأة، وحالة Private DNS، ونص الخطأ الدقيق. الاستعلام المباشر إلى خادم مسمّى يثبت أن ذلك الخادم يجيبك؛ ولا يثبت أن المطابقة العادية للتطبيق اختارته. الإجابة من الذاكرة المؤقتة ليست اختبارًا جديدًا، لذا أفرغ الذاكرة المؤقتة أو استخدم اسمًا لم يسأل عنه أحد اليوم.
إذا كان الـ resolver يخدم عملاء من شبكة وصول معينة فقط، فإن ما يراه بعد خروج VPN قد يحدد النتيجة، وهذه مسألة سياسة لمن يديره وليست دليلًا على أن المشغلين يحجبون UDP 53. حيث يكون Private DNS نشطًا، قد يُرفض اسم مضيف غير مؤهل بحكم التصميم بينما يجيب الخادم نفسه الأسماء العامة بشكل طبيعي. قراءة الخصائص تخبرك أي نمط سارٍ، فتتوقف عن تخمين مرشحات الحزم.
أصلح الطبقة التي تملك عدم التطابق
اعمل صعودًا بدلًا من تحرير الحالة العامة. إذا كان التطبيق مرتبطًا بالشبكة الخطأ، فأصلح الارتباط. إذا كان الملف يوفر خيار DNS الخطأ، فأصلح الملف. إذا كان Private DNS صارمًا على شبكة لا يستطيع resolver الخاص بها خدمة منطقتك الخاصة، فذلك قرار إدارة جهاز وليس سببًا لإيقاف الميزة في كل مكان.
دفع resolver-ات عامة إلى خطاف DHCP أو إلى خاصية نظام هو الإصلاح الذي لا يتوقف عن إحداث حوادث: تتوقف الأسماء الخاصة عن المطابقة، ويبقى التغيير بعد جلسة VPN، ويجد الشخص التالي على الجهاز عنوانًا قديمًا بلا مالك. أبقِ التغيير داخل VPN أو التطبيق أو طبقة الإدارة التي تملك عدم التطابق، ثم أعد قراءة اللقطة لتأكيد أن قائمة الخوادم تغيّرت فعلًا.
ما تريده في النهاية هو طلب تطبيق واحد مرتبط بشبكة واحدة وقائمة resolver-ات وحالة Private DNS. عندما تستطيع إظهار تلك السلسلة، يتوقف عنوان مألوف في ملف عن كونه دليلًا على أي شيء.