أمر ping إلى 192.0.2.10 يخبرك بأن عنوانًا واحدًا رد على صدى ICMP، وهذا كل ما يخبرك به. على شبكة بلا نفق قد ينجح، لأن العنوان قد يكون على الشبكة الفرعية المحلية؛ ومع نفق سليم قد يفشل، لأن الخادم يُسقط ICMP بينما يخدم HTTPS. الفحص الذي يحتاجه سكربتك هو استعلام حالة المنصة مع اختبار مسار للوجهة التي يستخدمها التطبيق. تعامل معهما كحقلين منفصلين، لا كقيمة منطقية واحدة.

ما يثبته رد الصدى حقًا

ICMP بروتوكول قابلية وصول لا يعرف شيئًا عن الواجهات أو الأنفاق. عندما يصل رد، تُبلغ النواة أن مضيفًا استجاب؛ ولا تُبلغ عن المسار الذي حمل الطلب أو الذي حمل الجواب. التصفية تجعل الإشارة أكثر تشويشًا، لأن جدار حماية يحجب طلبات الصدى لا يقول شيئًا عن المنافذ خلفه. كما أن ملفًا بنفق منقسم قد يستثني العنوان المختبر عمدًا بينما تعمل كل وجهة أخرى.

ما تريد معرفته فعلاً هو ما إذا كانت خدمة معينة قابلة للاستخدام عبر المسار الذي يسلكه التطبيق. اختر المضيف والمنفذ الذي يناديه التطبيق، ثم اشترط ردًا على طبقة التطبيق.

قابلية الوصول وحالة النفق حقيقتان مختلفتان، ويمكن أن تكون إحداهما صحيحة والأخرى خاطئة. الفصل بينهما يخبرك بمن يملك الفشل. أما دمجهما في فحص واحد فينتج تذكرة لا يستطيع أحد توجيهها.

اسأل Android عن النقل، لا عن ping

يجيب Android عن سؤال الحالة مباشرة عبر ConnectivityManager. تحمل قدرات الشبكة النشطة علامة نقل VPN، وتُضبط عندما تُوجَّه الحركة عبر واجهة VPN. النداء محلي ورخيص ومستقل عن استجابة أي مضيف بعيد.

هذه النسخة من Java تُعيد false بدل أن ترمي استثناءً عندما لا توجد شبكة نشطة. ولأنها تقرأ الشبكة النشطة، فهي تعكس الملف الذي اختاره المستخدم في الإعدادات.

ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkCapabilities caps = cm.getNetworkCapabilities(cm.getActiveNetwork());
boolean tunnel = caps != null && caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);

لإشعارات التغيير، سجّل NetworkCallback بدل الاستطلاع بمؤقت. لا تخلط بينه وبين VpnService.prepare، الذي يبلغ فقط عمّا إذا منح المستخدم الإذن لـ VPN، لا عمّا إذا كانت الحزم تتدفق. يصل الإلغاء عبر VpnService.onRevoke، لكن نسيان ملف في الإعدادات لا ينتج أي بث على الإطلاق.

iOS: أسماء الواجهات قاعدة إرشادية لا عقد

تفحص مقاطع iOS كثيرة إعدادات الخادم الوكيل، وتجد قاموس __SCOPED__، وتبحث عن مفاتيح واجهات مثل tap أو tun أو utun2 أو ppp أو ipsec. هذا النهج اصطلاح تسمية لا ضمان موثّق، لذا قد يكسره تحديث للنظام يعيد تسمية واجهة. كما يميل إلى الإبلاغ بصحة إدخالات قديمة تبقى بعد زوال النفق.

عندما يملك تطبيقك الإعداد، يمنحك NEVPNManager حالة حقيقية. فهو يصف النفق الذي بدأه تطبيقك؛ ومع VPN لكل تطبيق، قد تبقى تطبيقات أخرى خارج ذلك النفق تمامًا.

أعد تحميل التفضيلات قبل قراءة الحالة، لأن القيمة تتغير مع ظهور النفق وزواله:

let manager = NEVPNManager.shared()
manager.loadFromPreferences { error in
    let up = manager.connection.status == .connected
    print(up)
}

علامة حالة المنصة لا تثبت أيضًا أن الحركة تصل إلى النظير. تلك الفجوة هي ما يغطيه اختبار المسار، ولهذا لا تكفي قيمة منطقية واحدة للدعم.

ملفات Windows تكشف حقل حالة حقيقيًا

يتتبع Windows ملفات VPN بشكل منفصل عن المحولات، ويعرض Get-VpnConnection حقل ConnectionStatus لكل ملف يعرفه. تظهر هنا الملفات التي أُنشئت عبر عميل Windows أو حزمة تزويد. الأمر ليس كاشفًا عامًا للأنفاق.

اقرأ الحقل لملف مُسمّى، وأضف -AllUserConnection عندما يكون الملف لكل المستخدمين:

Get-VpnConnection -Name "Fabrikam" | Select-Object Name, ConnectionStatus, ServerAddress

غالبًا ما يبقى عملاء الطرف الثالث غير مرئيين لهذا الأمر حتى ونفقهم قائم، لذا نتيجة فارغة تعني مجهولًا لا منفصلًا. قوائم المحولات مضللة بالقدر نفسه: قد يبقى محول مورّد قائمًا وهو خامل، وبعض المحولات لا توجد إلا أثناء الجلسة. وبالنسبة لملف يملكه Windows، يبلّغ rasdial برمز خروج يمكنك التفرع عليه. كل هذا يصف اعتقادًا محليًا، لا قابلية وصول النظير.

الحالة مع المسار: فحص من جزأين

الملف المتصل لا يقول شيئًا عن وجهة الحزم. يمكن للنفق المنقسم أن يبقي النفق قائمًا مع استثناء الوجهة التي تهمك. ملفات Always-on تبقى متصلة بخادم ميت، ومفتاح الإيقاف يحجب الحركة عمدًا عندما يسقط النفق.

اختبر الطبقتين: تأكد من أن نقل VPN أو ملفًا نشط، ثم تأكد من أن الوجهة تُحلّ وتجيب عبر ذلك المسار. على Linux، اسأل النواة عن الواجهة التي ستستخدمها:

ip route get 192.0.2.10
resolvectl query intranet.example.test

عندما يكون العميل خارج سيطرتك، سجّل النتيجتين ودع النمط يشير إلى الطبقة. متصل مع فشل اختبار المسار يشير إلى نفق منقسم أو DNS أو سياسة. منفصل مع اختبار مسار ناجح يعني أن مسارًا آخر يحمل الحركة.

اختبار يمكنك تنفيذه بالترتيب

سجّل حالة المنصة أولاً، قبل أن تغيّر أي حالة شبكة. حلّل اسم المضيف ولاحظ عائلة العنوان، لأن سجل AAAA قد يسلك مسارًا مختلفًا عن سجل A. افتح منفذ الخدمة واطلب ردًا من طبقة التطبيق لا مجرد مصافحة. احتفظ بكل ملاحظة في حقل سجل خاص بها.

على جهاز Linux فيه dig وcurl، تغطي ثلاثة أوامر التحليل والمسار والخدمة نفسها. نفّذها والنفق قائم ثم مرة أخرى وهو متوقف:

dig +short intranet.example.test
ip route get 198.51.100.20
curl -sS -o /dev/null -w "%{http_code}" --max-time 8 https://intranet.example.test/health

أربعة حقول منفصلة أفضل من قيمة منطقية واحدة، لأن الحالة وDNS والمسار والسياسة تفشل باستقلال وتصل إلى فرق مختلفة. يبقى ping في الطرفية فحصًا يدويًا جيدًا للسلامة. لكنه تعريف ضعيف للاتصال في الأتمتة، حيث تجيب واجهة المنصة واختبار المسار عن السؤال الفعلي.

مقالات ذات صلة