مرشّح pull-filter في OpenVPN يطابق أكثر من المسار الذي تقصده
يقارن pull-filter نصَّك كبادئة مع الخيارات المدفوعة، لذا يلتقط route أيضاً route-gateway وroute-ipv6. افحص الأفعال أولاً، ثم المسارات.
تضيف سطراً واحداً للاحتفاظ بمسارك الافتراضي المحلي، وبعد ذلك لم يعد النفق يصل إلى خادم DNS الداخلي. كان السطر pull-filter ignore "route"، وهو لا يعني «تجاهل هذا المسار». بل يعني «أطرح كل خيار مدفوع يبدأ نصه بتلك الأحرف الخمسة»، وعلى خادم عادي يشمل ذلك route-gateway و route-metric و route-ipv6 إلى جانب المسارات نفسها. قائمة الفحص أدناه هي ما أتبعه قبل أن أمسّ ملف تعريف يجب أن يستخدمه شخص آخر.
المرشّح لا يعمل إلا على الخيارات المدفوعة
يعمل pull-filter على أسطر الخيارات التي يرسلها الخادم بعد إنشاء النفق، ولا يعمل على غيرها. الخيارات المكتوبة في ملفك المحلي لا تتأثر به، ولا حركة التطبيقات كذلك. إذا كنت تأمل في منع عملية من استخدام النفق، فهذه هي الأداة الخاطئة تماماً، ولن يحقق ذلك أي مزيج من المرشّحات.
هذا النطاق مفيد، لأنه يعني أنك تستطيع ترك إعدادات الخادم كما هي ورفض جزء منها محلياً. وهو أيضاً حدّ يستحق التسجيل في التذكرة: المرشّح يغيّر ما يقبله هذا العميل، لا ما يعرضه الخادم. وليس له أثر على مستخدمين آخرين للملف نفسه. ولا يصمد عند الانتقال إلى عميل آخر لا ينفّذ هذا الخيار، وهذا أمر يستحق المعرفة قبل أن تبني عليه سير عمل.
تأكد مما يرسله الخادم فعلاً قبل أن تكتب النمط. عند مستوى إسهاب مرتفع يطبع العميل سلسلة الخيارات المدفوعة التي تلقّاها، وهذا هو المصدر الصادق الوحيد للنص الدقيق الذي تطابق ضده:
sudo openvpn --config /etc/openvpn/corp.ovpn --verb 4
sudo grep -n 'pull-filter' /etc/openvpn/corp.ovpn
اقرأ السطر المدفوع كقائمة خيارات تفصل بينها فواصل، ولاحظ أن أسماء الخيارات ووسائطها تفصل بينها مسافات. يُقارن نص مرشّحك بهذا التدفق، ولهذا تكون المسافات مهمة إلى هذا الحد في الخطوة التالية.
المطابقة بادئة، لذا فإن المسافات هي اللعبة كلها
المقارنة بادئة نصية، لا اسم خيار محلَّل. لذا يطابق "route" كلاً من route-gateway 10.8.0.1 و route-ipv6 2001:db8::/32 و route-metric 100. إضافة مسافة واحدة في النهاية تحصره في العائلة التي تقصدها على الأرجح، وإضافة البادئة الكاملة تحصره أكثر في وجهة محددة.
| Filter text | What it actually matches | Typical outcome |
|---|---|---|
"route" | Every option beginning with those letters | Routes, gateway, metric and IPv6 routes all dropped |
"route " | Route entries only, not the hyphenated siblings | The routes go, the rest survives |
"route 10.60." | A single destination range | The narrowest rule, and the easiest to audit |
"dhcp-option DNS" | Pushed DNS settings | Resolver stays local, internal names stop resolving |
الصف الأخير هو الذي يفاجئ الناس أثناء العمل بنفق منقسم. الاحتفاظ بمحلّل الأسماء الخاص بك خيار مشروع، ويعني أن كل اسم داخلي يعتمد الآن على محلّل لا يرى المنطقة الخاصة. هذه نتيجة تُقبل عن عمد، لا أثر جانبي يُكتشف في الإنتاج.
المطابقة بالبادئة تعني أيضاً أن القاعدة قد تتوسع لاحقاً بصمت. عندما يضيف الخادم خياراً جديداً يبدأ بنصك، يبدأ مرشّحك في الانطباق عليه دون أن يعدّل أحد ملفك. هذا هو نمط الفشل الذي يجب التصميم ضده، والتخفيف هو أن تطابق أكبر قدر ممكن من الخيار لا أقله.
ثلاثة أفعال بثلاث نتائج مختلفة
accept و ignore و reject ليست ثلاث تهجئات للفكرة نفسها. تختلف فيما يفعله العميل عند المطابقة وفيما إذا كان أحد سيكتشف ذلك.
ignore يطرح الخيار المطابق بهدوء، وهذا ما تريده لإعداد استبدلته عمداً. reject يطرحه ويجعل العميل يشتكي، وهذا ما تريده عندما يجب أن يكون غيابه ظاهراً في السجل بدلاً من اكتشافه لاحقاً. accept هو الصيغة الإيجابية، ويُستخدم عندما تبني قائمة سماح بدلاً من إزالة خيارات فردية.
أياً كان الفعل الذي تستخدمه، تُطبَّق المرشّحات بالترتيب الذي تظهر به، لذا تنتج قاعدتان متداخلتان نتيجة تعتمد على الترتيب ويصعب مراجعتها جداً. أبقِ قاعدة واحدة لكل غرض وضع النص الأكثر تحديداً في كل منها. إن احتجت قائمة سماح، فضّل عدداً صغيراً من قواعد accept على كومة من قواعد ignore التي تؤدي إلى الشيء نفسه. عندئذ يستطيع المراجعون قراءة الملف من أوله إلى آخره والتنبؤ بالنتيجة، وهذا هو الاختبار الوحيد القابل للتوسع.
تحقّق من المسار والمحلّل المطبَّقين، لا من ملف التعريف
قد يتركك مرشّح يبدو صحيحاً في الملف مع نفق لا يوجّه شيئاً مفيداً. تحقق من الأثر على النظام العامل، حيث تكون الخيارات المدفوعة قد طُبّقت أو طُرحت بالفعل:
ip route show default
ip route show | grep -c 'proto static'
resolvectl status | grep -A4 'Link.*tun0'
curl -sS -o /dev/null -w '%{http_code}\n' --max-time 5 https://intranet.example.internal/
يخبرك السطران الأولان هل وصل المسار الافتراضي المدفوع وكم مدخلة ثابتة بقيت. يُظهر استعلام المحلّل أي خادم تستخدمه واجهة النفق فعلاً، وهو عادةً موضع مفاجأة DNS. أما السطر الأخير فيجيب السؤال الوحيد المهم للمستخدم.
اختبر الاتجاهين وأنت هناك. قاعدة تُبقي إنترنتك المحلي عاملاً لكنها تكسر تحليل الأسماء الداخلية بصمت تنجح في فحص عابر وتفشل في أول مهمة حقيقية، لذا أدرج مورداً داخلياً وموقعاً عاماً في الاختبار نفسه.
سجّل الاستثناء ومن يملكه
المرشّح استثناء من تصميم المشغّل، لذا اكتبه مع سبب ونقطة مراجعة. عبارة «يتجاهل المسارات المدفوعة للاحتفاظ بالافتراضي المحلي» قابلة للمراجعة؛ أما سطر عارٍ في ملف تعريف فليس كذلك، وسيحذفه الشخص التالي أو يوسّعه بالتخمين.
الإصدار يهم هنا أيضاً. صُقل سلوك المطابقة والصياغة المقبولة الدقيقة عبر OpenVPN 2.4 و2.5 و2.6، لذا تحقق من النمط مقابل دليل الإصدار الذي تشحنه لا مقابل منشور منتدى عن إصدار أقدم. يوثّق دليل OpenVPN 2.6 هذا الخيار وقاعدة مطابقته.
أخيراً، اتفق على الاستثناء مع من يدير الخادم. المرشّح على جانب العميل الذي يخالف سياسة خادم مقصودة هو حادثة دعم تنتظر التدقيق التالي، وتكون تسويته قبل شحن الملف أرخص بكثير من تسويته بعد أن يلاحظ أحد غياب المسارات.