كيف ترسل شبكة فرعية خاصة واحدة فقط عبر الشبكة الافتراضية
اختر بين مسار على العميل ومسار يدفعه الخادم ومحدِّدات يجري التفاوض عليها، ثم مرّر شبكة فرعية خاصة واحدة دون نفق كامل.
تمرير شبكة فرعية خاصة واحدة عبر النفق وكل ما عداها عبر مسارك المعتاد طلب صغير، لكن أمامه طرق كثيرة للفشل. ما يحسم النتيجة ليس مربع الاختيار المسمّى split tunneling، بل المكان الذي يُفرض فيه القرار: جدول مسارات العميل نفسه، أو مسار يدفعه الخادم، أو سياسة يتفاوض عليها الطرفان. اختر الطبقة الخاطئة فتخرج إما بنفق كامل لم ترده، وإما بمسار يشير إلى نفق يرفض الطرف الآخر قبوله. أستخدم اختباراً من ثلاثة شروط قبل فتح أي إعداد، ثم أختار واحدة من الآليات أدناه.
ثلاثة شروط تحسم التصميم
أولاً، تحتاج البادئة والقناع الدقيقين من مالك الشبكة. شبكة 10.x ليست بادئة؛ 10.20.0.0/16 هي البادئة. تأكد من أنها لا تتقاطع مع شبكتك المحلية أو جسر Docker أو شبكة افتراضية أخرى تشغّلها، لأن التقاطع يجعل المسار ملتبساً ويختار النواة المدخلة التي لم تقصدها.
ثانياً، مَن يجيب عن حركة العودة. توجيه حزمة إلى النفق يوصلها إلى خادم الشبكة الافتراضية فقط. إذا كانت الشبكة الفرعية خلف موجّه آخر لا يملك مساراً راجعاً إلى مجموعة عملائك، فعلى الخادم أن يُخفي الحركة عبر التمثيل، أو على ذلك الموجّه أن يتعلم مجموعتك. لا مسار على جانب العميل يعالج غياب مسار العودة.
ثالثاً، نقطة الفرض. بعض العملاء يثبّتون مساراً ويتولى نظام التشغيل الباقي. وآخرون يتفاوضون على سياسة، والسياسة التي لا تقبلها البوابة لا تُنتج نفقاً على الإطلاق: تُسقط الحزم دون خطأ ظاهر. حدّد أيّ الاثنين تملكه قبل أن تكتب أي شيء.
WireGuard: AllowedIPs هو جدول المسارات
على العميل، يسرد AllowedIPs الوجهات التي يجوز لها دخول النفق، ويحوّل wg-quick كل مدخلة إلى مسار عادي. لذا نصف المهمة الخاص بالعميل سطر واحد.
[Peer]
PublicKey = ...
Endpoint = vpn.example.net:51820
AllowedIPs = 10.20.0.0/16قارن الآن مدخلة الخادم للعميل نفسه. هي تصف ما سيرسله الخادم إلى العميل، وهو عادة عنوان النفق الخاص بالعميل لا الشبكة الفرعية الخاصة.
[Peer]
PublicKey = ...
AllowedIPs = 10.99.0.2/32تبديل الاثنين هو الخطأ الذي أراه أكثر من غيره. وضع 10.20.0.0/16 تحت قسم النظير الخاص بالخادم يعني أن الشبكة الفرعية كلها تقع خلف ذلك العميل، وهذا ادعاء ربط موقع بموقع لا إذن. الحزم التي لا تطابق AllowedIPs أي نظير تُسقط بصمت، فيبدو الإدخال الخاطئ تماماً كمشكلة جدار حماية.
إن كنت تدير المسارات بنفسك، فاضبط Table = off تحت [Interface] وأضف المسار الذي تريده. حينها لا يُضاف شيء تلقائياً، لذا ينتمي المسار إلى ما يرفع الواجهة.
OpenVPN: ادفع المسار ثم تأكد من وصوله
على خادم عادي يكون التغيير توجيهاً واحداً في إعداد الخادم، إلى جانب مجموعة العملاء.
push "route 10.20.0.0 255.255.0.0"يضيفه العميل عند الاتصال. يظهر نمط الفشل عندما يدفع الملف الشخصي نفسه redirect-gateway أيضاً، أو عندما يكون أحدهم قد أضاف route-nopull سابقاً: الأول يحوّل الجلسة إلى نفق كامل، والثاني يتجاهل كل مسار مدفوع بما فيه مسارك.
العميل الذي يحتاج سلوكاً ضيقاً مع خادم نفق كامل ينبغي أن يتجاهل الأجزاء التي لا يريدها فقط. في OpenVPN 2.4 وما بعده يوجد pull-filter لهذا الغرض تحديداً.
pull-filter ignore "redirect-gateway"
route 10.20.0.0 255.255.0.0أبقِ عائلتي العناوين منفصلتين: مسار IPv4 مدفوع لا يفعل شيئاً لخدمة داخلية تُحلّ إلى IPv6، وتفشل تلك الخدمة عبر النفق بينما يبدو كل شيء آخر سليماً.
عندما لا تكون الشبكة الفرعية الخاصة على خادم الشبكة الافتراضية بل خلف عميل آخر، يجب إبلاغ الخادم. أضف ملفاً لكل عميل عبر client-config-dir يحتوي iroute 10.20.0.0 255.255.0.0، مع route المطابق كي يتعلم العملاء الآخرون المسار. بدون iroute لا سبب لدى الخادم لإرسال تلك البادئة عبر ذلك النفق تحديداً.
IPsec: يجب أن تتوافق محدِّدات الحركة
مع IPsec لا يوجد مسار لدفعه. يتفاوض الطرفان على العناوين التي تقع داخل النفق، والحركة خارج المحدِّدات المتفق عليها لا تُشفَّر ولا تُرسل عبره. على عميل strongSwan تكون المحدِّدات صريحة.
leftsubnet=192.168.1.0/24
rightsubnet=10.20.0.0/16إذا كانت البوابة مهيأة بـ 0.0.0.0/0 على الجانبين، فعادة ما يُقلّص تضييق IKEv2 الرابطة الفرعية إلى تقاطع العرضين، وهو النتيجة التي تريدها. بعض البوابات ترفض بدلاً من ذلك عرضاً لا يطابق محدِّداتها المهيأة، ويعرض السجل رابطة فرعية فاشلة لا شكوى توجيه. عندما يحدث ذلك يكون التغيير على البوابة، لأن مسار العميل لا يستطيع إنشاء نفق لمحدِّد لا يقبله الطرف الآخر.
على Windows يخفي العميل المدمج القرار نفسه خلف إعدادين. يجب تشغيل تقسيم النفق، ويجب تسجيل البادئة في الملف الشخصي.
Set-VpnConnection -Name Office -SplitTunneling $true
Add-VpnConnectionRoute -ConnectionName Office -DestinationPrefix 10.20.0.0/16تسجيل البادئة هو ما يجعلها تصمد أمام إعادة الاتصال، وهو ما لا يفعله مسار مضاف يدوياً.
أبقِ نقطة النهاية وDNS خارج القرار
يجب أن تبقى نقطة نهاية الشبكة الافتراضية قابلة للوصول دون النفق، وإلا انهار النفق على نفسه. عندما لا يُوجَّه سوى 10.20.0.0/16 يكون ذلك تلقائياً، لأن نقطة النهاية عنوان عام. في ملف نفق كامل ليس كذلك، ويحتاج العميل إلى مسار صريح للمضيف نحو نقطة النهاية قبل أن يصعد النفق.
DNS قرار ثانٍ لا يتخذه دفع المسار نيابة عنك. الأسماء الداخلية تُحلّ عادة عبر مُحلِّل لا تصل إليه إلا الشبكة الخاصة. إذا دفع الخادم خادم DNS مرّ كل اسم عبره؛ وإذا لم يفعل، فإما تفشل الأسماء الداخلية أو تُحلّ علناً إلى شيء لم تقصده. يحفظ DNS المنقسم نطاق بحث واحداً على المُحلِّل الداخلي، لكنه يعتمد على دعم العميل، فتعامل معه كمهمة قائمة بذاتها لا كأثر جانبي للتوجيه.
تحقق، ثم أعد التشغيل وتحقق مرة أخرى
ثلاثة اختبارات تغطي مسألة التوجيه. اسأل النواة إلى أين سيذهب عنوان بعيد، ثم اجلب شيئاً من داخل الشبكة الفرعية، ثم تأكد أن طلباً عاماً عادياً ما زال يخرج عبر اتصالك المعتاد.
ip route get 10.20.5.7
curl -sS http://10.20.5.7/health
curl -sS https://ifconfig.meالسطر الأول يسمّي واجهة. إذا سمّى واجهتك الفيزيائية فالمسار لم يصل أبداً. على Windows يجيب Find-NetRoute -RemoteIPAddress 10.20.5.7 عن السؤال نفسه، وينبغي أن يعرض الاختبار الأخير عنوانك المعتاد لا عنوان خادم الشبكة الافتراضية.
ثم أعد التشغيل. المسارات المضافة يدوياً تختفي، بينما تعود المسارات الآتية من الملف الشخصي أو من إعداد مدفوع أو من AllowedIPs. إذا نجح الوصول الضيق قبل إعادة التشغيل وفشل بعده، فالعيب في كيفية بدء النفق لا في المسار نفسه.
قبل أن تعتبره منتهياً، تأكد من أربعة أمور: أن البادئة جاءت من مالك الشبكة ولا تتقاطع مع شيء محلي، وأن مسار العودة موجود أو أن قاعدة تمثيل تحل محله، وأن الآلية التي هيأتها هي التي تفرض التوجيه على منصتك، وأن الاختبارات نفسها تنجح بعد إعادة تشغيل نظيفة. تستحق ملاحظات strongSwan عن إعادة التوجيه القراءة إذا كان مسار العودة هو الجزء الذي يظل يفشل.