🌐 Detecting your location…

كيفية إصلاح “مشكلة شهادة SSL: غير قادر على الحصول على شهادة المُصدر المحلي”

⏱️3 min read  ·  547 words

SSL certificate problem: unable to get local issuer certificateيعني أن عميلك لم يتمكن من بناء سلسلة ثقة من شهادة الخادم إلى مرجع مصدق يثق به. الإغراء هو تعطيل التحقق. لا تفعل ذلك، فهذا يزيل الحماية ضد الاعتراض تمامًا. عادة ما يكون الإصلاح الحقيقي واضحًا ومباشرًا.

ماذا يعني الخطأ

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

تشخيص ذلك عن طريق فحص السلسلة.

openssl s_client -connect example.com:443 -showcerts </dev/null

# Look for the verification result at the end:
#   Verify return code: 0 (ok)
#   Verify return code: 20 (unable to get local issuer certificate)
#   Verify return code: 21 (unable to verify the first certificate)

كود الإرجاع21 بشكل عام يعني أن الخادم مخطئ، فهو لم يرسل شهادته المتوسطة. كود الإرجاع20 يعني عمومًا أن متجر الثقة المحلي الخاص بك هو المشكلة.

السبب الأول: الخادم لا يرسل الوسطاء

خطأ شائع في تكوين الخادم. غالبًا ما تخفيه المتصفحات لأنها تقوم بتخزين الوسائط الوسيطة من الزيارات السابقة، وبالتالي فإن الموقع “يعمل في Chrome” أثناء فشل عملية التجعيد وخط أنابيب CI الخاص بك.

# Count the certificates the server sends
openssl s_client -connect example.com:443 -showcerts </dev/null 2>/dev/null \
  | grep -c "BEGIN CERTIFICATE"
# 1 means only the leaf — the intermediate is missing

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

# Correct order: leaf first, then intermediates
cat leaf.crt intermediate.crt > fullchain.crt
server {
    # Use the full chain, not just the leaf certificate
    ssl_certificate     /etc/ssl/certs/fullchain.crt;
    ssl_certificate_key /etc/ssl/private/privkey.key;
}

سيرتبوتfullchain.pem يحتوي بالفعل على السلسلة – يشير nginx إلىcert.pem بدلاً من ذلك هو السبب الوحيد الأكثر شيوعًا لهذا الخطأ على مواقع Let’s Encrypt.

السبب 2: حزمة CA قديمة أو مفقودة

إذا اكتملت سلسلة الخادم، فهذا يعني أن مخزن الثقة المحلي الخاص بك أصبح قديمًا.

# Debian / Ubuntu
sudo apt update && sudo apt install --reinstall ca-certificates
sudo update-ca-certificates

# RHEL / Fedora
sudo dnf reinstall ca-certificates
sudo update-ca-trust

# Alpine (very common in Docker images)
apk add --no-cache ca-certificates
update-ca-certificates

# macOS
brew install ca-certificates
# or update curl, which bundles its own
brew install curl

تعد صور Minimal Docker مصدرًا متكررًا لهذا الخطأ لأنها يتم شحنها بدون أي حزمة CA على الإطلاق. اضافةca-certificates للصورة عادة ما يحلها في سطر واحد.

السبب 3: اعتراض TLS للشركات

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

الحل هو إضافة المرجع المصدق الجذري للشركة إلى المتجر الموثوق به – وليس تعطيل التحقق.

# Capture the certificate the proxy is presenting
openssl s_client -showcerts -connect example.com:443 </dev/null \
  | openssl x509 -outform PEM > corp-ca.crt

# Inspect it to confirm what it is
openssl x509 -in corp-ca.crt -noout -subject -issuer -dates

# Install system-wide (Debian/Ubuntu)
sudo cp corp-ca.crt /usr/local/share/ca-certificates/corp-ca.crt
sudo update-ca-certificates

اطلب من قسم تكنولوجيا المعلومات لديك الحصول على ملف CA الجذري الرسمي بدلاً من استخراجه بنفسك حيثما أمكن ذلك – يفترض الاستخراج من اتصال مباشر أن الاتصال لم يتم اختراقه بالفعل.

إصلاحات لكل أداة

حليقة

# Point at a specific bundle
curl --cacert /path/to/ca-bundle.crt https://example.com

# Or set it for the session
export CURL_CA_BUNDLE=/path/to/ca-bundle.crt

جيت

# Correct fix: point Git at a valid bundle
git config --global http.sslCAInfo /path/to/ca-bundle.crt

# Scope it to one host if only that host is affected
git config --global http."https://internal.company.com/".sslCAInfo /path/to/corp-ca.crt

git config --global http.sslVerify false يظهر في كل نتيجة بحث لهذا الخطأ. يقوم بتعطيل التحقق من الشهادة لكل مضيف قمت بالاستنساخ منه بشكل دائم. لا تستخدمه.

نود.جي إس

# Add a CA to Node's trust store for this process
export NODE_EXTRA_CA_CERTS=/path/to/corp-ca.crt
node app.js
// Or per-request, which is more precise
import https from 'node:https';
import fs from 'node:fs';

const agent = new https.Agent({
  ca: fs.readFileSync('/path/to/corp-ca.crt'),
});

await fetch('https://internal.example.com', { agent });

NODE_TLS_REJECT_UNAUTHORIZED=0 يعطل عملية التحقق على مستوى العملية وتطبع Node تحذيرًا يوضح ذلك بالضبط. إنه مقبول في اختبار محلي سريع وليس في أي مكان آخر.

بايثون

import certifi, requests

# Use certifi's bundle explicitly
requests.get('https://example.com', verify=certifi.where())

# Or a corporate CA
requests.get('https://internal.example.com', verify='/path/to/corp-ca.crt')
# Environment variables respected by requests and urllib3
export REQUESTS_CA_BUNDLE=/path/to/ca-bundle.crt
export SSL_CERT_FILE=/path/to/ca-bundle.crt

# Keep certifi current
pip install --upgrade certifi

عامل الميناء

FROM node:22-alpine

# Alpine ships without a CA bundle
RUN apk add --no-cache ca-certificates

# Add a corporate CA if you are behind interception
COPY corp-ca.crt /usr/local/share/ca-certificates/
RUN update-ca-certificates

ENV NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt

السبب 4: انتهت صلاحية الشهادة

تحقق قبل افتراض وجود مشكلة في المتجر الموثوق.

echo | openssl s_client -connect example.com:443 2>/dev/null \
  | openssl x509 -noout -dates
# notBefore=...
# notAfter=...

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

date
timedatectl status    # Linux

التسلسل التشخيصي

  1. openssl s_client -connect host:443 -showcerts – اقرأ رمز التحقق من الإرجاع
  2. عد الشهادات المرسلة. واحد يعني وسيط مفقود على الخادم.
  3. تحقق من تواريخ انتهاء الصلاحية وساعة النظام المحلي.
  4. قارنه بجهاز أو شبكة أخرى — إذا كان يعمل هناك، فستكون المشكلة محلية.
  5. تحقق مما إذا كان المُصدر هو CA الخاص بشركتك، مما يشير إلى الاعتراض.
  6. تحديثca-certificates وأي حزمة خاصة باللغة.

لماذا لا يتم تعطيل التحقق فقط

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

فالخطر الواقعي ليس نظريا. سوف يقوم خط أنابيب CI مع تعطيل التحقق بتثبيت حزمة من سجل منتحل بكل سرور. الإصلاح يستغرق دقائق. يمكن أن تكون نتيجة تخطيه بنية معرضة للخطر.

الأسئلة المتداولة

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

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

س: أين توجد حزمة CA على نظامي؟
ج: عادة/etc/ssl/certs/ca-certificates.crt على دبيان وأوبونتو،/etc/pki/tls/certs/ca-bundle.crt على RHEL. في بايثون،python -m certifi يطبع المسار الذي تستخدمه الشهادة.

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

س: يعمل CI الخاص بي ولكن فشل الإنتاج. لماذا؟
ج: دائمًا ما يكون هناك اختلاف في الصورة الأساسية. كثيرًا ما يتم حذف الصور النحيفة وجبال الألبca-certificates تماما.

الخلاصة

يعني هذا الخطأ أن سلسلة الثقة مقطوعة، وهناك أسباب قليلة فقط:لا يرسل الخادم شهاداته المتوسطة، أو أن حزمة CA المحلية الخاصة بك مفقودة أو قديمة، أو أن وكيل الشركة يعترض TLS باستخدام CA الخاص به، أو انتهت صلاحية الشهادة. التشخيص بـopenssl s_client ورمز التحقق من الإرجاع، ثم قم بإصلاح السبب الفعلي — قم بتثبيت المرجع المصدق (CA)، وقم بالتحديثca-certificatesأو يخدم السلسلة كاملة. لا تقم مطلقًا بتعطيل التحقق خارج نطاق الاختبار المحلي المهمل، لأن ذلك يزيل الحماية التي كان الخطأ موجودًا لتوفيرها.

MD Rafikul Islam

Written by

MD Rafikul Islam is a software developer and the editor of TechPulse. He writes about developer tooling, hardware, and the practical decisions that come up in day-to-day engineering work — which laptop to buy, which framework to commit to, why a build broke at 2am. He tests the tools he writes about and says plainly when something is not worth the money. Corrections and corrections requests are welcome at rony.yf25@gmail.com.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা