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

استبدال واحد، تغييران منفصلان

جهة الإصدار هي اسم ومفتاح عام والمفتاح الخاص الذي يوقّع. لا يثق المدققون بـ«جهة الإصدار» في المجرّد. إنهم يثقون بشهادة محددة تقبع أصلًا في مخزن ثقة، ولا يقبلون مُصدرًا إلا إذا وصلت سلسلة تواقيع إلى تلك النسخة المخزنة. لذلك يغيّر استبدال الجهة أمرين يتعطّلان كل على حدة: أي المراسي تُقبل، وأي هويات الأقران صدرت تحتها.

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

ما يفحصه المدقق، بالترتيب

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

لتكرار ذلك المسار دون اتصال، وجّه -CAfile إلى الحزمة نفسها التي ستنشرها لا إلى مخزن النظام. وإلا فأنت تفحص المضيف، لا التغيير:

openssl verify -CAfile new-ca.crt gateway.crt
openssl verify -CAfile new-ca.crt -untrusted intermediate.crt client.crt
openssl x509 -in gateway.crt -noout -subject -issuer -dates
openssl s_client -connect gw.example.net:443 -CAfile new-ca.crt

ذلك الأمر يعمل فقط مع مستمع TLS صريح مثل صفحة إدارة HTTPS على البوابة؛ فقناة تحكم OpenVPN تسبق TLS، لذا لا يستطيع s_client فحص مصافحة النفق.

قواعد بناء المسار الكامنة وراء تلك الأخطاء في RFC 5280 القسم 6. وهي تفسّر الأعطال التي تبدو عشوائية بغير ذلك: وسيط منتهي الصلاحية لم يتذكره أحد، أو شهادة يمنع استخدام مفتاحها التوقيع، أو قيد اسم يستثني المضيف الذي تفحصه.

لماذا يظل النفق القديم يعمل

يبقي TLS وOpenVPN الجلسة القائمة حيّة بعد انتهاء المصافحة. لا شيء يعيد التحقق من شهادة القرين مع كل حزمة، لذا يستمر عميل اتصل قبل التغيير في تمرير الحركة حتى يعيد التفاوض أو يعيد الاتصال أو يسقط النفق. هذه الثغرة هي سبب أن استبدال الجهة قد يبدو سليمًا ساعة ثم يفشل في أسوأ لحظة: حاسوب محمول يستيقظ من النوم، أو تعيين NAT تنتهي مهلته، أو بوابة تعيد التشغيل.

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

أبقِ طبقة المفتاح الثابت منفصلة عن هذا. يضيف tls-auth رمز HMAC إلى قناة التحكم، ويشفّر tls-crypt تلك القناة ويتحقق منها، ولا يحمل أي منهما مادة شهادة، لذا فتدوير أي منهما تغيير منفصل بنمط فشل خاص به. النشرات التي تخلط الاثنين تنتهي بعميل مفتاحه الثابت سليم، وشهادته قديمة، ورسالة خطئه لا تذكر أيًا منهما.

فخ إعادة استخدام اسم الموضوع

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

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

تدوير لا يُسقط الشبكة

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

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

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

تحقق من النتيجة، لا من قائمة الملفات

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

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

اختم بعميل لم يتصل قط: امسح حالة ملفه التعريفي، واتصل، واقرأ السلسلة المتفاوض عليها. القرين الذي يستأنف جلسة مخزّنة سيبشّر بأن الترحيل نجح بينما لم يتحقق من شيء على الإطلاق.

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