SSD Nodes Learn 🎉 VPS من $5.50/شهر
الأدلة Matt Connorبقلم Matt Connor

إضافة CA الخاصة بك إلى مخزن الثقة في Ubuntu

أنشئ CA خاصة باستخدام openssl، ووقّع شهادة خادم، ثم ثبّت الجذر في /usr/local/share/ca-certificates لتثق Ubuntu باتصالات HTTPS الداخلية.

أضف CA الخاص بك إلى مخزن الثقة في Ubuntu

لإضافة CA الخاص بك إلى مخزن الثقة في Ubuntu، انسخ شهادة الجذر إلى /usr/local/share/ca-certificates/ باستخدام اسم ينتهي بـ .crt، ثم شغّل sudo update-ca-certificates. ‏CA، أي جهة إصدار الشهادات، هو زوج مفاتيح تحتوي شهادته على صلاحية توقيع الشهادات الأخرى. بعد أن يثق الجهاز بجذرك، تُقبل كل شهادة وقّعها ذلك الجذر، ولذلك يتوقف فشل التحقق من HTTPS بين خدماتك الخاصة.

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

تأتي Ubuntu 24.04 مع OpenSSL 3 وحزمة ca-certificates في الصورة الافتراضية، لذلك لا تحتاج إلى تثبيت أي شيء أولاً (تم التحقق في أغسطس 2026).

متى ينبغي أن تدير CA الخاصة بك؟

تحتاج CA عامة مثل Let's Encrypt إلى اسم في DNS عام وخادم يمكنها الوصول إليه. لا تُعد الأسماء الداخلية مؤهلة لذلك. لا يمكن لقاعدة بيانات على شبكة خاصة أو لوحة إدارة مرتبطة بنفق الحصول على شهادة عامة، ولا ينبغي تعريض أي منهما للإنترنت لمجرد الحصول على شهادة.

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

التكلفة حقيقية. يمكن للمفتاح الجذري توقيع أي شيء تسمح به القيود، لذلك يستطيع أي شخص يقرأ ca.key إصدار شهادات ستقبلها أجهزتك. احمِه بالطريقة نفسها التي تحمي بها مفتاحاً خاصاً في إدارة مفاتيح SSH. إذا كانت لدى الخدمة تسمية DNS عامة، فتجاوز كل ذلك واستخدم CA عامة: يتطلب Certbot مع nginx وLet's Encrypt جهداً أقل ولا يحتاج إلى تثبيت أي شيء على جانب العميل.

إنشاء مفتاح CA والشهادة الجذرية

اعمل في دليل لا يستطيع فتحه إلا حسابك. يجب ألا يغادر المفتاح الجذري هذا الدليل.

install -d -m 700 ~/ca
cd ~/ca
openssl genrsa -aes256 -out ca.key 4096
chmod 600 ca.key

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

أنشئ الآن الشهادة الجذرية التي يوقّعها مفتاح CA لنفسه.

openssl req -x509 -new -key ca.key -sha256 -days 3650 \
  -subj "/O=Example Internal/CN=Example Internal Root CA" \
  -addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
  -addext "keyUsage=critical,keyCertSign,cRLSign" \
  -addext "subjectKeyIdentifier=hash" \
  -addext "nameConstraints=critical,permitted;DNS:internal.example" \
  -out ca.crt

استبدل internal.example باللاحقة التي تستخدمها فعلياً، واقرأ القسم التالي قبل الإبقاء على تلك الإضافة الأخيرة.

تؤدي كل إضافة وظيفة واحدة.

  • تجعل basicConstraints مع CA:TRUE هذه الشهادة شهادة CA. من دونها، يرفض العميل أي شهادة يوقّعها هذا المفتاح، حتى عندما يكون التوقيع نفسه صحيحاً.
  • تحدد pathlen:0 أن CA يمكنه توقيع شهادات الكيانات النهائية، ولا يمكنه إنشاء CAs إضافية تحته.
  • تقيّد keyUsage استخدام المفتاح بتوقيع الشهادات وقوائم الإبطال، ولذلك لا يمكن استخدام المفتاح نفسه عن طريق الخطأ كمفتاح خادم TLS.
  • تمنح subjectKeyIdentifier الجذر معرّفاً تشير إليه شهادات الكيانات النهائية، وبهذا يعثر العميل على المُصدِر الصحيح داخل مخزن يحتوي على بضع مئات من الشهادات.
  • تقيّد nameConstraints أسماء النطاقات التي يُسمح لـCA بإصدار شهادات لها.

اعرض ما أنشأته بدلاً من افتراض أن الأمر نفّذ ما قصدته.

openssl x509 -noout -subject -issuer -serial -dates -in ca.crt
openssl x509 -noout -text -in ca.crt

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

حدِّد ما يُسمح لـ CA بإصداره

تكون شهادة root في مخزن النظام موثوقة لكل اسم على الإنترنت ما لم تحدد خلاف ذلك. وهذه صلاحية واسعة في ملف واحد على خادم واحد. يحدّ nameConstraints منها. عند تضمين permitted;DNS:internal.example في root، تُرفض سلسلة صادرة عن CA هذه لاسم خارج internal.example، حتى إذا كانت التوقيعات صحيحة.

اختبر ذلك بدلاً من الوثوق بها.

openssl req -new -newkey rsa:2048 -nodes -keyout /tmp/outside.key -out /tmp/outside.csr \
  -subj "/CN=www.example.com"
openssl x509 -req -in /tmp/outside.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -days 30 -sha256 \
  -extfile <(printf 'subjectAltName=DNS:www.example.com\n') -out /tmp/outside.crt
openssl verify -CAfile ca.crt /tmp/outside.crt
echo $?

تُصدر الشهادة، لأن CA يوقّع كل ما تطلب منه توقيعه. يحدث الفشل أثناء التحقق: تكون حالة الخروج غير صفرية، ويذكر OpenSSL القيد الذي اصطدم به. هذه هي فائدة الامتداد. حتى إذا سُرقت مفتاح CA، فلن يمكن استخدامه لإنتاج شهادة صالحة لاسم خارج الشجرة الفرعية. احذف الملفات المتبقية باستخدام rm /tmp/outside.* عند الانتهاء.

هناك أربعة أمور يجب معرفتها قبل اعتماد القيد. يُوسَم هذا القيد بـ critical، لذلك يجب على العميل الذي لا يفهم الامتداد رفض السلسلة بدلاً من تجاهله. هذا هو السلوك الآمن، لكنه قد يفاجئ مكتبة TLS قديمة. لا تقيّد الشجرة الفرعية المسموح بها لأسماء DNS عناوين IP في SAN، لأن نوع الاسم الذي لا تُدرج له شجرة فرعية يبقى غير مقيّد. لذلك أضف permitted;IP:10.0.0.0/255.255.0.0 في الامتداد نفسه إذا كانت شهاداتك تتضمن عناوين IP. يجب أن تغطي الشجرة الفرعية كل اسم ستصدر له شهادة مستقبلاً، بما في ذلك أسماء المضيفين المختصرة. لذلك ستفشل شهادة للاسم الأساسي app عند التحقق مقابل المثال أعلاه. ويُدمج القيد في root، لذا فإن تغيير القرار يتطلب شهادة root جديدة وتثبيتها من جديد على كل عميل.

إصدار شهادة طرفية موقَّعة من CA

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

openssl req -new -newkey rsa:2048 -nodes \
  -keyout app.key -out app.csr \
  -subj "/CN=app.internal.example"
chmod 600 app.key

تُوضع الأسماء المهمة في ملف امتداد، وليس في CSR. يطابق العملاء اسم المضيف مع subjectAltName (SAN) ويتجاهلون الاسم الشائع تماماً، لذلك تفشل عملية التحقق من اسم المضيف لدى كل عميل حالي إذا احتوت الشهادة على CN من دون SAN، بصرف النظر عما يقوله CN.

basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:app.internal.example, DNS:api.internal.example
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always

احفظ ذلك باسم app.ext، ثم وقّع الطلب باستخدام CA.

openssl x509 -req -in app.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -days 397 -sha256 -extfile app.ext -out app.crt

يكتب -CAcreateserial الملف ca.srl بجانب CA، ويحتوي على الرقم التسلسلي التالي حتى لا تشترك شهادتان صادرتان من CA هذه في الرقم نفسه. احتفظ بهذا الملف في دليل CA. إنّ -days 397 خيار، وليس حداً تفرضه الأداة. وتهم مدد الصلاحية القصيرة هنا أكثر مما تهم مع CA عامة، لأن CA الخاصة لا تملك بنية أساسية لإبطال الشهادات: لا توجد CRL ولا مستجيب OCSP ما لم تنشئ واحداً، لذلك يظل مفتاح شهادة طرفية متسرّباً قابلاً للاستخدام حتى تنتهي صلاحية الشهادة.

تحقق من النتيجة قبل أن تلمس مخزن الثقة.

openssl x509 -noout -subject -issuer -serial -dates -in app.crt
openssl x509 -noout -ext subjectAltName -in app.crt

يسمّي سطر الجهة المُصدرة CA الآن بدلاً من الشهادة الطرفية نفسها. ويسرد سطر SAN الأسماء التي تكون هذه الشهادة صالحة لها، ويطابق العميل الاسم مع هذه القائمة ولا شيء آخر.

تحقّق باستخدام -CAfile صراحةً قبل تثبيت أي شيء

openssl verify -CAfile ca.crt app.crt
echo $?

يطرح هذا سؤالاً محدداً: هل ترتبط app.crt بسلسلة الشهادة الموجودة في ca.crt؟ لا يوضح ذلك أي شيء عمّا يثق به هذا الجهاز، لأنك مرّرت شهادة الجذر إلى OpenSSL في سطر الأوامر. يعني الفشل هنا وجود مشكلة في الشهادات نفسها، لذا أصلحها قبل المتابعة.

اطلب الآن من الجهاز إجراء التحقق.

openssl verify app.crt
echo $?

من دون -CAfile، يعود OpenSSL إلى دليل الشهادات المضمّن في النظام. يعرض openssl version -d الدليل الأساسي الذي يستخدمه الإصدار المبني لديك، وفي Ubuntu يحيل دليل certs الموجود تحته إلى /etc/ssl/certs. شهادة الجذر ليست موجودة هناك بعد، لذلك يفشل التحقق: تصل السلسلة إلى جهة إصدار لا يحتوي عليها مخزن الشهادات، ولا يبقى مكان آخر للبحث. لاحظ حالة الخروج. هذه هي القيمة التي ستتغير بعد خطوتين.

يُعد عميل حقيقي اختباراً أفضل من openssl verify، لأنه يتحقق من اسم المضيف ومن السلسلة أيضاً. قدّم الشهادة واسترجعها.

openssl s_server -accept 8443 -cert app.crt -key app.key -www &
curl --resolve app.internal.example:8443:127.0.0.1 https://app.internal.example:8443/

يوجّه --resolve الاتصال إلى 127.0.0.1 مع الاستمرار في طلب app.internal.example، لذلك تتطابق SAN ويصبح السؤال الوحيد هو الثقة. يفشل curl ويطبع سبب تعذّر التحقق من السلسلة. أضف -v لعرض مزيد من التفاصيل. اترك خادم الاختبار قيد التشغيل.

ثبّت الشهادة الجذرية في /usr/local/share/ca-certificates

sudo cp ca.crt /usr/local/share/ca-certificates/example-internal-root.crt
sudo chmod 644 /usr/local/share/ca-certificates/example-internal-root.crt
sudo update-ca-certificates

التفاصيل التالية هي التي تحدد نجاح العملية:

  • يجب أن ينتهي اسم الملف بالامتداد .crt. توضّح صفحة الدليل update-ca-certificates أن الشهادات ذات الامتداد .crt الموجودة أسفل /usr/local/share/ca-certificates تُضمَّن وتُوثَق بها ضمنياً. أما الملف الذي يحمل الاسم root.pem أو root.cer فيُتخطّى دون إصدار أي رسالة.
  • يجب أن يكون المحتوى بتنسيق PEM، أي كتلة base64 محاطة بسطرَي BEGIN CERTIFICATE وEND CERTIFICATE. إعادة تسمية ملف DER إلى .crt لا تغيّر كونه ملفاً ثنائياً، ولذلك لا تتم قراءته. حوّله باستخدام openssl x509 -inform DER -in ca.der -out ca.crt.
  • ضع الشهادة الجذرية فقط هنا. لا مكان للمفتاح الخاص بـCA أو لشهادة leaf في مخزن الثقة.

يطبع update-ca-certificates عدد الشهادات التي أضافها وأزالها. إذا لم يضف أي شهادة، فالسبب هو الامتداد أو تنسيق الملف.

تأكّد من التغيير من جهة النظام، لا من تلك الرسالة.

ls -l /etc/ssl/certs/$(openssl x509 -noout -subject_hash -in /usr/local/share/ca-certificates/example-internal-root.crt).0
grep -c 'BEGIN CERTIFICATE' /etc/ssl/certs/ca-certificates.crt

يبني الأمر الأول اسماً للملف من قيمة subject hash الخاصة بشهادتك، ثم يعرضه. أنشأ update-ca-certificates هذا الرابط الرمزي، وهو يشير إلى الملف الذي ثبّتَّه. يحسب الأمر الثاني عدد الشهادات في الحزمة ذات الملف الواحد. شغّله قبل التثبيت أيضاً، ويمكنك عندئذٍ مراقبة زيادة العدد بمقدار واحد.

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

تحقّق مرة أخرى باستخدام مخزن النظام

openssl verify app.crt
echo $?
curl --resolve app.internal.example:8443:127.0.0.1 https://app.internal.example:8443/

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

أوقف خادم الاختبار باستخدام kill %1.

لماذا لا تضع ملفك في ‎/etc/ssl/certs

/etc/ssl/certs ناتج مُولَّد. يملؤه update-ca-certificates بروابط رمزية تشير إلى ملفات الشهادات الفعلية، ويكتب حزمة الشهادات المجمّعة /etc/ssl/certs/ca-certificates.crt بجانبها.

لا يعثر أي مكوّن على شهادة تنسخها يدوياً إلى ذلك الدليل. لا يفتح بحث OpenSSL في الدليل إلا الملفات التي تحمل اسم تجزئة subject للشهادة، لذلك يكون الملف المسمّى myca.crt غير مرئي له. يقرأ curl في Ubuntu ملف الحزمة، وتُعاد بناء الحزمة من المصادر المسجّلة، لذلك لا تكون نسختك ضمن ذلك المسار أيضاً. عند تشغيل update-ca-certificates --fresh، تُزال الروابط الرمزية في الدليل وتُعاد إنشاؤها، ما يؤدي إلى إزالة أي رابط أُنشئ يدوياً معها.

الجزء الآخر من هذا التقسيم هو /usr/share/ca-certificates، الذي ينتمي إلى الحزمة ca-certificates والمدرج في /etc/ca-certificates.conf. تعيد تحديثات الحزمة كتابة هذا الملف. أما /usr/local/share/ca-certificates فهو الدليل المخصّص لمسؤول النظام المحلي، لذلك تبقى سلطة الشهادات الخاصة بك بعد كل ترقية للحزمة التي تدير بقية الشهادات.

ما البرامج التي تتجاهل مخزن الثقة الخاص بالنظام

يؤدي تثبيت الشهادة الجذرية إلى إصلاح كل برنامج يستدعي OpenSSL أو يقرأ /etc/ssl/certs. ويشمل ذلك curl وwget وgit ووحدة ssl القياسية في Python وبرامج Go، التي تقرأ ملفات النظام في Linux. أما بيئات التشغيل التي تأتي بقائمة شهادات خاصة بها فلا تتأثر، وهذا هو سبب معظم الالتباس بعد نجاح التثبيت.

  • يستخدم Node.js قائمة مضمّنة وقت التجميع. وجّه Node.js إلى شهادتك الجذرية باستخدام NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/example-internal-root.crt، واضبطه في البيئة قبل بدء العملية، لأن Node يقرأ المتغير مرة واحدة عند بدء التشغيل. تحتوي إصدارات Node الحالية أيضاً على خيار لقراءة مخزن النظام؛ شغّل node --help | grep -i system-ca لمعرفة ما إذا كان إصدارك يدعم ذلك.
  • تستخدم مكتبة requests في Python حزمة certifi. اضبط REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt لهذه العملية، أو مرّر verify="/etc/ssl/certs/ca-certificates.crt" إلى الاستدعاء. ويأخذ pip القيمة --cert للسبب نفسه.
  • يقرأ Java مخزناً للشهادات. في Ubuntu، تثبّت حزمة ca-certificates-java خطافاً ضمن /etc/ca-certificates/update.d/، لذلك يحدّث update-ca-certificates مخزن شهادات Java أيضاً عند وجود هذه الحزمة. ومن دونها، استورد الشهادة الجذرية باستخدام keytool -importcert.
  • يحتفظ Firefox بمخزن خاص به ولا يقرأ /etc/ssl/certs مطلقاً. استورد الشهادة من إعدادات الشهادات فيه. أما Chromium على Linux فيقرأ قاعدة بيانات NSS لكل مستخدم، ويمكنك تعديلها باستخدام certutil من حزمة libnss3-tools.
  • للحاويات نظام ملفات خاص بها، لذلك لا يفيد مخزن المضيف داخلها. انسخ الشهادة الجذرية إلى الصورة وشغّل update-ca-certificates أثناء البناء. خطط لذلك إذا كانت خدماتك تعمل باستخدام Docker Compose على VPS.

عندما يظل برنامج يرفض الشهادة بعد تثبيت سليم، حدّد الملفات التي يفتحها قبل تغيير أي شيء آخر. الأداة strace -f -e trace=openat <command> 2>&1 | grep -i cert مباشرة، وتجيب عن هذا السؤال في تشغيل واحد.

الحفاظ على قابلية استخدام CA بمرور الوقت

إعادة إصدار شهادة leaf تعني تنفيذ خطوة CSR وخطوة التوقيع مرة أخرى، باستخدام ملف app.ext نفسه. لا يحتاج العملاء إلى اتخاذ أي إجراء، لأن root الموثوق به لديهم لم يتغير. احتفظ بملف ca.srl وكل ملفات .ext في دليل CA، حتى تكون عملية الإصدار التالية إعادة تنفيذ لأمر سبق أن نجح، لا إعادة بناء اعتماداً على الذاكرة.

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

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

إزالة CA من مخزن الثقة

sudo rm /usr/local/share/ca-certificates/example-internal-root.crt
sudo update-ca-certificates --fresh

يزيل --fresh الروابط الرمزية الموجودة في /etc/ssl/certs، ثم يعيد إنشاءها من المصادر التي ما زالت موجودة. لذلك يزيل الجذر المحذوف من الدليل ومن الحزمة معاً. أثبت نجاح الإزالة بالطريقة نفسها التي أثبت بها نجاح التثبيت.

openssl verify app.crt
echo $?
grep -c 'BEGIN CERTIFICATE' /etc/ssl/certs/ca-certificates.crt
ls -l /etc/ssl/certs/$(openssl x509 -noout -subject_hash -in ~/ca/ca.crt).0

يفشل التحقق مرة أخرى، ويعود عدد الشهادات إلى القيمة التي بدأ بها، ويختفي الرابط الرمزي الخاص بالتجزئة.

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

FAQ

أين أضع شهادة CA في Ubuntu؟

ضعها في /usr/local/share/ca-certificates/، على أن ينتهي اسم الملف بـ .crt وأن يكون المحتوى بتنسيق PEM، ثم شغّل sudo update-ca-certificates. هذا الدليل مخصّص للمسؤول المحلي، لذلك تتركه تحديثات الحزم دون تغيير. أما /usr/share/ca-certificates فتتبع الحزمة ca-certificates، ويُنشأ /etc/ssl/certs من كليهما، لذلك يُستبدل أي ملف تضعه في أحد هذين المكانين أو يُتجاهل.

لماذا يستمر curl في رفض الشهادة بعد تشغيل update-ca-certificates؟

تحقق من الأسباب بالترتيب. قد لا ينتهي اسم الملف بـ .crt، أو قد تكون الشهادة بتنسيق DER بدلاً من PEM. في هذه الحالة يتجاوزها update-ca-certificates ولا يضيف شيئاً. وقد لا تحتوي الشهادة على subjectAltName يطابق اسم المضيف. هذا فشل في اسم المضيف وليس فشلاً في الثقة؛ تحقّق باستخدام openssl x509 -noout -ext subjectAltName -in app.crt. وقد يرسل الخادم شهادة الورقة فقط، بينما يحتاج العميل أيضاً إلى شهادة وسيطة. وربما يكون curl مضبوطاً على استخدام حزمة شهادات مختلفة عبر CURL_CA_BUNDLE أو --cacert. كما تحتاج الخدمة التي تعمل مدة طويلة إلى إعادة تشغيل، لأن معظم البرامج تقرأ مخزن الثقة مرة واحدة عند بدء التشغيل.

هل يغطي مخزن الثقة في النظام Firefox وChrome وNode وJava؟

لا. يقرأ curl وwget وgit ووحدة ssl القياسية في Python وبرامج Go ملفات النظام، لذلك تعمل هذه البرامج فور تشغيل update-ca-certificates. يحتفظ Firefox بمخزن خاص به. ويستخدم Chromium على Linux قاعدة بيانات NSS لكل مستخدم، وتُعدَّل باستخدام certutil من الحزمة libnss3-tools. يحتاج Node.js إلى NODE_EXTRA_CA_CERTS يشير إلى ملف الجذر لديك. أما Java فتقرأ مخزن مفاتيح، ولا يحدّثه update-ca-certificates إلا عند تثبيت الحزمة ca-certificates-java. وتستخدم requests في Python certifi، وتحتاج إلى REQUESTS_CA_BUNDLE.

كيف أزيل CA من مخزن الثقة في Ubuntu؟

احذف الملف من /usr/local/share/ca-certificates/ ثم شغّل sudo update-ca-certificates --fresh. يمسح الخيار --fresh الروابط الرمزية في /etc/ssl/certs ويعيد إنشاءها، لذلك تُزال الشهادة من روابط التجزئة ومن حزمة ca-certificates.crt في الوقت نفسه. أكّد ذلك بتشغيل openssl verify على شهادة وقّعتها CA تلك، ثم اقرأ حالة الخروج. كرر الإزالة في كل مخزن آخر أضفت الشهادة إليه، لأن هذا الأمر لا يلمس أيّاً من تلك المخازن.

هل يمكنني استخدام CA خاصة بدلاً من Let's Encrypt لموقع عام؟

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

#tls#certificates#openssl#ubuntu#أمان#pki