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

شكلان للتخزين، وتوجيه واحد

تقبل توجيهات cert وkey وca كلٌّ منها مسارًا أو كتلة مضمّنة. وعندما تكون القيمة مسارًا، يفتح OpenVPN ذلك الملف ويقرأ الكائن من القرص. وعندما يحتوي الإعداد على كتلة محدّدة بوسمَي cert، يستهلك التوجيه نفسه المحتوى الواقع بين هذين الوسمين بدلًا من ذلك، ولا يكون هناك ملف منفصل.

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

والعكس غير صحيح. إنزال client.crt بجوار ملف شخصي يضمّن بياناته الخاصة لا يغيّر شيئًا، لأن لا شيء في الإعداد يشير إلى ذلك الملف. وهذا هو السبب الأكثر شيوعًا لظهور ملف موجود بوضوح وكأنه متجاهَل.

كيف تتحول الكتلة المضمّنة إلى كائن

يُستخرج المحتوى المضمّن من الإعداد ويُسلّم إلى محلّل PEM كنص. ويتوقع ذلك المحلّل الحدود المعتادة: سطر BEGIN، وحمولة base64، وسطر END مطابق. وإذا قُطعت الكتلة بسبب نسخة فاشلة، أو غُلّفت بوسم HTML من صفحة تنزيل، أو فُتحت في محرر طبّع الشرطات، يفشل المحلّل في محتوى يبدو موجودًا.

<cert>
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
</cert>

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

تحقّق من الشكل الذي يستخدمه الملف الشخصي المحمّل فعلًا، لا من الملف الذي فتحه محررك صدفةً:

grep -nE '^(ca|cert|key) |^<(ca|cert|key)>' client.ovpn

كيف يُحلّ مرجع المسار

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

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

بالنسبة إلى شهادة مخزّنة بشكل منفصل، يؤكد تحليل دون اتصال الكائن قبل أن تنقّح أي شيء فوقه:

openssl x509 -in client.crt -noout -subject -issuer -dates
openssl pkey -in client.key -noout -check

تثبت تلك الأوامر أن الملفات قابلة للقراءة وصالحة بنيويًا. لكنها لا تثبت أن النظير يثق بالمُصدر، ولا أن الشهادة لا تزال داخل نافذة صلاحيتها، ولا أن المفتاح يخصّها.

ما يمكن أن يخبرك به خطأ المحلّل وما لا يمكن

يحدّد فشل التحليل موضع المشكلة في مُدخل واحد ومرحلة واحدة. ولا يخبرك أيّ من شكلي التخزين استخدمه العميل، ولا يخبرك هل كان الكائن سيُقبل. فهذه أسئلة منفصلة بأدلة منفصلة.

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

أبقِ النصف الحساس خارج التقارير العامة أثناء التحقيق. شارك أسماء التوجيهات ونص الخطأ وبنية الكتلة، مع إزالة مادة المفتاح وأي حمولة تعرّفية. وتوثّق دليل openvpn(8) كلا شكلي توجيهات الملف وسلوك دليل العمل وراءهما.

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