تجاهُل client-config-dir بعد تحوّل OpenVPN إلى خدمة
يُحلّ client-config-dir النسبي بالنسبة إلى دليل عمل البرنامج الخفي. اقرأ الوحدة، ثم تفحّص صلاحيات المسار، ثم تحقّق من البحث في السجل.
يشتغل النفق ويتصل العميل، لكن العنوان الثابت والمسارات المدفوعة التي حدّدتها لذلك المستخدم بعينه مفقودة. لا يقول السجل “file not found”، وهذا ما يدفع الناس إلى إعادة توليد الشهادات. في معظم هذه الحالات تعمل الخدمة من دليل مختلف عن الصدفة التي اختبرت فيها، ولم يُحلّ client-config-dir بالطريقة التي افترضتها. الإصلاح هو تصحيح للمسار، لا إعادة تعيين لبيانات الاعتماد.
اقرأ الوحدة قبل أن تلمس الإعدادات
ابدأ بالعملية التي تعمل فعلاً، لا بالملف الذي حرّرته. اسأل systemd عن سطر التنفيذ ودليل العمل والحساب الذي ينتقل إليه. تلك الإجابات الثلاث تفسّر معظم حالات الفشل في هذه الفئة:
systemctl show openvpn-server@server -p ExecStart -p WorkingDirectory -p User -p RootDirectoryوجود WorkingDirectory فارغاً يعني أن الوحدة تبدأ في /، لذا يُبحث عن client-config-dir ccd نسبي في /ccd. ذلك الدليل لا وجود له تقريباً، ولا تعتبر الخدمة غيابه خطأً قاتلاً.
قارن ذلك بالإطلاق التفاعلي الذي استخدمته أثناء الاختبار، حيث كان الدليل الحالي لصدفتك على الأرجح دليل الإعدادات. الملف نفسه، والكلمات المفتاحية نفسها، ونتيجتان مختلفتان.
ما يُحلّ إليه المسار النسبي
تُحلّ الكلمة المفتاحية مقابل دليل عمل العملية في لحظة استخدام الخيار. وهي لا تعني “بجانب ملف الإعدادات الذي مرّرته عبر --config”. سيقرأ OpenVPN إعدادات من مسار مطلق بكل سرور، ثم يحلّ القيم النسبية في مكان آخر، وهذا هو الفخ بعينه. يذكر دليل OpenVPN 2.6 القاعدة تحت --client-config-dir ومرة أخرى تحت --cd.
الكلمة المفتاحية cd تغيّر ذلك السياق قبل قراءة الملفات الأخرى، فالوحدة التي تضبط cd /etc/openvpn/server ثم client-config-dir ccd تُحلّ إلى /etc/openvpn/server/ccd. وإن أضفت cd، فتحقّق من ترتيب التوجيهات وتذكّر أنه يؤثر في كل مرجع نسبي آخر في الملف نفسه.
تفقّد المسار بحساب الخدمة
قد يكون المسار صحيحاً ومع ذلك غير قابل للقراءة. بعد التنازل عن الامتيازات لم تعد الخدمة root، لذا يحتاج كل دليل أب إلى صلاحية البحث لذلك الحساب، ويحتاج ملف العميل نفسه إلى صلاحية القراءة. يكفي غياب بت تنفيذ واحد في دليل أب لإخفاء الملف، ولا يظهر الخطأ إلا كعميل يحصل بهدوء على التجمع الافتراضي.
يطبع namei صلاحية كل مكوّن بالترتيب، وهو أسرع من فحص الأدلة واحداً واحداً:
namei -l /etc/openvpn/server/ccd/client1ثم اختبر القراءة بحساب الخدمة بدل حسابك:
runuser -u openvpn -- test -r /etc/openvpn/server/ccd/client1 && echo readableإذا استخدمت الوحدة chroot، فيجب أن يوجد الدليل داخل السجن، ويُفسَّر المسار في الإعدادات بعد تطبيق chroot. والملف الموجود على المضيف خارج السجن غير مرئي من داخله.
أكّد البحث بدل التخمين
ارفع مستوى السجل لإعادة تشغيل واحدة واقرأ ما يقوله الخادم عن الخيارات الخاصة بالعميل. عند verb 4 تبلّغ الخدمة عن إعدادات كل عميل استوردتها، لذا فإن غياب السطر دليل مباشر على أن أي ملف لم يُقرأ لذلك الاتصال.
openvpn --config /etc/openvpn/server.conf --verb 4 --client-config-dir /etc/openvpn/server/ccdشغّل ذلك في المقدمة على منفذ آخر ووصّل عميلاً واحداً. هذا يزيل systemd من الصورة تماماً: إذا ظهرت التجاوزات هنا ولم تظهر تحت الخدمة، فالفرق في سياق الوحدة لا في الملف.
قرّر ما ينبغي أن يحدث عندما لا يطابق أي ملف. بدون ccd-exclusive يُقبل العميل بإعدادات التجمع العامة فقط، وهو الفشل الصامت الموصوف أعلاه. ومعها يصبح الملف المفقود اتصالاً مرفوضاً، والرفض أسهل في الملاحظة لكن أصعب في التنقيح تحت الحمل.
أصلح، أعد التشغيل، تحقّق
اجعل الدليل مطلقاً في الإعدادات وأبقه كذلك. المسارات النسبية آمنة فقط عندما تثبّت الوحدة دليل العمل، وتثبيته جزء متحرك إضافي سيزيله أحدهم لاحقاً.
client-config-dir /etc/openvpn/server/ccd
ccd-exclusiveأعد تشغيل النسخة، وأعد توصيل عميل معروف، واقرأ العنوان الذي تلقاه مع المسارات المدفوعة إليه. إن طابق العنوان سطر ifconfig-push في ملف ذلك العميل، فقد نجح البحث. وإن بقي العميل في التجمع العام، فعُد إلى عدد أسطر السجل: صفر عمليات استيراد يعني أن المسار أو الهوية خطأ، وعملية استيراد واحدة بمحتوى خاطئ تعني أنك تحرّر ملفاً غير الذي تقرأه الخدمة.
تراجع باستعادة الوحدة السابقة والإعدادات معاً ثم أعد التشغيل. لا حاجة لإعادة إصدار الشهادات في أي من ذلك، ومعالجة مشكلة دليل كمشكلة بيانات اعتماد هي الطريق الذي يحوّل إصلاحاً في خمس دقائق إلى نافذة صيانة.