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

الشهادة ليست مخزن ثقة

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

القبول يأتي من مكان آخر: ملف CA توجّه العميل إليه، أو بصمة تقارنها يدويًا، أو جذر موجود أصلًا في مخزن يقرأه العميل. يمكن أن يكون النشر سليمًا تمامًا بينما تفشل شهادته في كل اختبار عام. openssl verify مقابل حزمة النظام ستبلغ عن مُصدر غير معروف، وهذا البلاغ صحيح وليس عيبًا.

خيار ca في OpenVPN أوضح حالة للثقة المحصورة في التطبيق. ذلك الملف يسمّي المراسي التي سيقبلها العميل، وقد يحمل CA خاصة واحدة أو، في نشر صغير، شهادة الخادم الموقعة ذاتيًا. الإصدار 2.6 يقبل أيضًا --peer-fingerprint لتثبيت بصمة SHA-256 بدل توزيع ملف CA. WireGuard أبعد من ذلك: لا شهادات فيه إطلاقًا، فقط مفتاح عام ثابت لكل نظير، فسؤال التوقيع الذاتي لا ينطبق عليه.

أين تثبّت الثقة يحدد من يرثها

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

على Debian أو Ubuntu، يؤدي إسقاط ملف في /usr/local/share/ca-certificates/ وتشغيل update-ca-certificates إلى تغيير حزمة النظام كلها. على Windows، يكتب certutil -addstore -f Root في مخزن الجهاز ويحتاج موجه أوامر مرتفعًا، بينما إضافة -user تستهدف مخزن المستخدم الحالي بدلًا من ذلك؛ والاثنان غير قابلين للتبادل. يحتفظ Firefox بقاعدة بيانات NSS خاصة به، لذا قد لا يظهر استيراد على مستوى نظام التشغيل هناك أبدًا.

النطاق مهم بسبب ما تستطيعه الجهة المصدرة. يمكن لـ CA مُصدرة أن توقّع لأسماء لا علاقة لها بها، لذا أي شيء يثق بذلك المخزن سيقبل تلك التواقيع. ورقة مثبتة واحدة لا تستطيع فعل ذلك؛ إنها تصادق هوية نظير واحدة بالضبط. إن كان الهدف جعل VPN واحد يتصل، فإن CA محصورة في التطبيق أو ورقة مثبتة تبلغه، بينما الجذر على مستوى الجهاز تنازل أكبر بكثير مما تتطلبه العَرَض.

ما زلت تشفّر دون CA عامة

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

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

الثقة بالمُصدر لا تتجاوز فحص الاسم

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

OpenVPN يجعل الانفصال مرئيًا. verify-x509-name يثبت الموضوع المتوقع عبر مطابقة name أو name-prefix أو subject. remote-cert-tls server يشترط أن تكون شهادة النظير صالحة للاستخدام كشهادة خادم، وهو ما يرفض شهادة عميل فقط حتى عندما يكون المُصدر موثوقًا. لا يحل شحن ملف CA محل أي من الإعدادين.

افحص الشهادة قبل أن تقرر أي شيء:

  • openssl x509 -in server.crt -noout -subject -issuer -dates -ext subjectAltName يُظهر من أصدرها، ولأي أسماء، وإلى متى.
  • openssl verify -CAfile ca.crt server.crt يتحقق مما إذا كانت السلسلة التي تنوي شحنها تصادق فعليًا على الورقة.
  • openssl s_client -connect vpn.example.net:443 -servername vpn.example.net -CAfile ca.crt -verify_return_error يعمل مع نقاط نهاية TLS مثل بوابة ويب؛ بروتوكول OpenVPN على 1194 ليس مجرى TLS عاديًا، لذا لا ينطبق ذلك الاختبار هناك.

الشهادة بتاريخ منتهٍ، أو بلا subjectAltName للاسم الذي تتصل به، أو باستخدام serverAuth مفقود، تفشل بغض النظر عن مدى عناية تركيب المرساة.

خمسة فحوص قبل أن تقبل واحدة

قارن البصمة عبر قناة ليست الاتصال الذي تحاول إصلاحه: طرفية، أو مثبّت تملكه بالفعل، أو ملف إعداد موقّع. openssl x509 -in server.crt -noout -fingerprint -sha256 على الخادم والقيمة نفسها في سجل العميل تكفيان لتعرف أنك تنظر إلى كائن واحد.

بعد ذلك، قرّر ما تثبّته: ورقة واحدة، أم جهة تستطيع إصدار المزيد. ثم قرّر أين تذهب، وسمِّ التطبيقات التي تقرأ ذلك المخزن. اكتب مسار الإزالة بينما ما زلت تتذكره، لأن ثق-و-امضِ هو كيف يتحول استيراد مؤقت إلى دائم.

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

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

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