إدارة الأسرار والبنية التحتية للمفاتيح

أساسيات البنية التحتية للمفاتيح العامة (PKI)

18 دقيقة الدرس 7 من 28

أساسيات البنية التحتية للمفاتيح العامة (PKI)

كل اتصال TLS أجريته على الإطلاق — سواء إلى GitHub أو إلى لوحة تحكم السحابة أو بين الخدمات المصغرة — يعتمد على بنية تحتية للثقة تُسمى البنية التحتية للمفاتيح العامة (PKI). لا تقتصر PKI على ملف شهادة يجلس على خادم؛ إنها سلسلة من الإثباتات التشفيرية تربط شهادتك وصولاً إلى جهة جذر موثوقة يثق بها العميل مسبقاً. يجب على مهندسي DevOps الكبار أن يفهموا هذه السلسلة بعمق، لأن الأخطاء في أي حلقة تُسبب إخفاقات إنتاجية متسلسلة: ترفض المتصفحات الاتصالات، وتنهار مصادقة mTLS المتبادلة، وتفشل الدورة التلقائية بصمت.

جهات إصدار الشهادات وسلسلة الثقة

جهة إصدار الشهادات (CA) هي كيان مهمته توقيع الشهادات — أي ربط المفتاح العام بهوية محددة بصورة تشفيرية. توجد ثلاثة مستويات في PKI الإنتاجية:

  • CA الجذر (Root CA) — مرساة الثقة المطلقة. شهادتها موقّعة ذاتياً. يشحن مورّدو أنظمة التشغيل والمتصفحات قائمة منتقاة من شهادات CA الجذر الموثوقة (مخزن الثقة). يُحفظ المفتاح الخاص لـ CA الجذر في وضع غير متصل بالإنترنت تماماً (في HSM داخل منشأة مؤمنة ماديّاً). يوقّع فقط على شهادات CA الوسيطة، ولا شيء آخر.
  • CA الوسيطة (Intermediate CA) — جهة CA متصلة بالإنترنت، شهادتها موقّعة من CA الجذر. كل عمليات إصدار الشهادات اليومية تجري هنا. إن اختُرقت الوسيطة، يمكن سحبها دون المساس بالجذر.
  • شهادة الطرف النهائي (Leaf Certificate) — الشهادة المثبّتة على خادم أو جهاز أو مستخدم. موقّعة من الوسيطة. هذا ما يراه openssl s_client عند الاتصال بخدمتك.

عندما يتحقق عميل (متصفح، curl، عميل gRPC) من شهادة، يسير عبر هذه السلسلة: الطرف النهائي ← الوسيطة ← الجذر. إن استطاع بناء سلسلة غير منقطعة تصل إلى جذر يثق به، نجح مصافحة TLS. تُسمى هذه العملية بناء السلسلة أو التحقق من المسار. يتحقق العميل من ثلاثة أشياء في كل خطوة: صحة التوقيع، وعدم انتهاء صلاحية الشهادة، وعدم سحبها.

PKI Chain of Trust Root CA Self-signed · Offline HSM Intermediate CA Online · Signs leaf certs api.example.com Leaf cert · 90 days svc-mesh.internal mTLS leaf · 24 hours *.internal.corp Wildcard leaf · 1 year signs Client Trust Store Contains Root CA cert
سلسلة الثقة في PKI ذات ثلاثة مستويات: CA الجذر (غير متصل) يوقّع على CA الوسيطة (متصل)، التي توقّع على الشهادات النهائية المستخدمة في الخدمات.

الأسماء البديلة للموضوع (SANs)

اعتُمد حقل Common Name (CN) القديم وحده للتحديد بما تغطيه الشهادة. أما المتصفحات الحديثة وRFC 6125 فتشترط استخدام الأسماء البديلة للموضوع (SANs) بدلاً عنه. يمكن أن يحتوي امتداد SAN على:

  • إدخالات DNS: — أسماء مضيفين محددة مثل api.example.com أو حرف بدل مثل *.example.com
  • إدخالات IP: — تُستخدم في mTLS بين الحاويات حيث تكون عناوين IP هي الهوية
  • إدخالات URI: — تستخدمها SPIFFE، مثل spiffe://cluster.local/ns/default/sa/payment-svc
  • إدخالات Email: — لشهادات عميل S/MIME
عناوين URI لـ SPIFFE داخل SANs هي الطريقة التي ينفّذ بها Istio وEnvoy نظام mTLS بدون ثقة افتراضية. تحصل كل حاوية على شهادة تحتوي على URI لـ SPIFFE يشفّر حساب خدمة Kubernetes الخاص بها. تتحقق الـ sidecar من هذه العناوين على كل اتصال — لا كلمات مرور، لا قوائم تحكم بالوصول على مستوى الشبكة.

لفحص SANs على أي شهادة من سطر الأوامر:

# فحص SANs لشهادة نشطة openssl s_client -connect api.example.com:443 -servername api.example.com < /dev/null 2>&1 \ | openssl x509 -noout -text \ | grep -A5 "Subject Alternative Name" # فحص ملف شهادة محلي openssl x509 -in server.crt -noout -text | grep -A5 "Subject Alternative Name" # أمر مختصر: عرض SANs وتاريخ الانتهاء والجهة المُصدِرة openssl x509 -in server.crt -noout -subject -issuer -dates -ext subjectAltName

دورة حياة الشهادة

لكل شهادة تاريخ انتهاء صلاحية صارم. مراحل دورة الحياة هي:

  1. الإنشاء — إنشاء مفتاح خاص وطلب توقيع الشهادة (CSR). يحتوي CSR على مفتاحك العام وادعاءات الهوية (CN، SANs). المفتاح الخاص لا يغادر نظامك أبداً.
  2. الإصدار — تتحقق CA من CSR (عبر تحدي DNS-01 أو HTTP-01 لـ CA العامة، أو السياسة الداخلية لـ CA الخاصة)، توقّعه، وتُعيد الشهادة. فترة الصلاحية تُحدَّد هنا.
  3. النشر — تُحمَّل الشهادة والمفتاح الخاص على الخادم (Nginx، Kubernetes Secret، محرك PKI في Vault). يجب تقديم ملف السلسلة (الوسيطة + الجذر) إلى جانب الشهادة النهائية.
  4. التجديد — ابدأ التجديد عند نحو ثلثَي فترة الصلاحية. لشهادات Let's Encrypt لمدة 90 يوماً، يعني ذلك اليوم 60. لشهادات mTLS التي يصدرها Vault خلال 24 ساعة، يجب أن يتولى أتمتتك التدوير كل ساعة.
  5. السحب — إن اختُرق مفتاح خاص، تُسحب الشهادة عبر CRL (قائمة سحب الشهادات) أو OCSP. السحب غير موثوق في المتصفحات؛ الشهادات قصيرة الأمد هي الإجابة الأفضل.
تتجه الصناعة نحو شهادات قصيرة الأمد (24 ساعة أو أقل) بدلاً من السحب. إن انتهت صلاحية الشهادة خلال 24 ساعة وكان التدوير آلياً، يصبح المفتاح المخترق عديم الفائدة خلال يوم. هذا هو النموذج الذي يستخدمه محرك PKI في Vault، وIstio Citadel، ونظام Munger الداخلي لـ Google. يزيل تعقيدات ومشاكل موثوقية CRL/OCSP كلياً.

إنشاء CSR وشهادة موقّعة ذاتياً

للخدمات الداخلية أو الاختبار، غالباً ما تحتاج إلى إنشاء CA خاصة وإصدار شهادات منها. إليك سير العمل الكامل باستخدام openssl:

# 1. توليد مفتاح CA الجذر وشهادة موقّعة ذاتياً (مرة واحدة فقط، احتفظ بالمفتاح بدون اتصال) openssl genrsa -aes256 -out root-ca.key 4096 openssl req -new -x509 -days 3650 -key root-ca.key \ -subj "/C=US/O=Acme Corp/CN=Acme Root CA" \ -out root-ca.crt # 2. توليد مفتاح CA الوسيطة وCSR openssl genrsa -out intermediate-ca.key 4096 openssl req -new -key intermediate-ca.key \ -subj "/C=US/O=Acme Corp/CN=Acme Intermediate CA" \ -out intermediate-ca.csr # 3. توقيع CA الوسيطة بواسطة CA الجذر openssl x509 -req -days 1825 -in intermediate-ca.csr \ -CA root-ca.crt -CAkey root-ca.key -CAcreateserial \ -extensions v3_ca \ -extfile <(printf "[v3_ca]\nbasicConstraints=critical,CA:TRUE\nkeyUsage=critical,keyCertSign,cRLSign") \ -out intermediate-ca.crt # 4. توليد مفتاح الطرف النهائي وCSR مع SANs openssl genrsa -out server.key 2048 openssl req -new -key server.key \ -subj "/C=US/O=Acme Corp/CN=api.example.com" \ -out server.csr # 5. توقيع الشهادة النهائية بواسطة CA الوسيطة (مع SANs) openssl x509 -req -days 90 -in server.csr \ -CA intermediate-ca.crt -CAkey intermediate-ca.key -CAcreateserial \ -extfile <(printf "[ext]\nsubjectAltName=DNS:api.example.com,DNS:www.example.com,IP:10.0.1.5") \ -extensions ext \ -out server.crt # 6. بناء ملف السلسلة (الوسيطة + الجذر) — قدّمه إلى جانب server.crt cat intermediate-ca.crt root-ca.crt > chain.crt # 7. التحقق من السلسلة openssl verify -CAfile root-ca.crt -untrusted intermediate-ca.crt server.crt

أنماط الإخفاق الإنتاجية الشائعة

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

  • سلسلة ناقصة يقدّمها الخادم — يرسل الخادم الشهادة النهائية فقط دون الوسيطة. المتصفحات على سطح المكتب تخزّن الوسيطات مؤقتاً وتبدو بخير؛ لكن متصفحات الموبايل وcurl والعملاء بين الخدمات يفشلون مع رسالة unable to get local issuer certificate. دائماً اجمع الشهادة النهائية مع الوسيطة في الحزمة التي تقدّمها. استخدم openssl s_client -connect host:443 -showcerts للتحقق من إرسال السلسلة الكاملة.
  • عدم تطابق SAN — شهادة لـ api.example.com نُشرت خلف وكيل عكسي يُعيد التوجيه بصفته api-internal.example.com. يفشل التحقق من TLS. دائماً أدرج جميع الأسماء — الأسماء المستعارة الداخلية، وأسماء موازن التحميل، وأسماء DNS للحاويات — في قائمة SAN وقت الإصدار.
  • انحراف الساعة — شهادة صُدرت في 14:00:00 UTC ونُشرت على خادم ساعته 13:59:50 UTC ستُرفض كـ "not yet valid". مزامنة NTP شرط أساسي لـ PKI.
  • مفاجأة انتهاء الصلاحية — تنتهي صلاحية الشهادات في 03:00 صباحاً ولا أحد يلاحظ حتى ينخفض الحركة وتُطلق مكالمة الطوارئ في 03:05. الحل: مراقبة ssl_certificate_expiry_seconds (Prometheus blackbox_exporter، تنبيه عند 30 يوماً وأخرى عند 7 أيام).
  • الجذر غير موجود في مخزن الثقة — لم يُوزَّع جذر CA الخاص الداخلي على جميع الخدمات وصور Docker الأساسية. تفشل الخدمات الجديدة في mTLS. أدر توزيع مخزن الثقة عبر إدارة التهيئة (Ansible، Chef) أو اجعله مدمجاً في صورة Docker الأساسية.
لا تستخدم شهادة wildcard أبداً لحركة المرور الداخلية بين الخدمات. تمنح الـ wildcards تغطية واسعة لكنها تجعل من المستحيل التعرف على الخدمات الفردية في السجلات ومسارات التدقيق. لـ mTLS بين الخدمات المصغرة، أصدر شهادات لكل خدمة على حدة مع عناوين URI لـ SPIFFE — عندها يستطيع شبكة الخدمات تطبيق سياسات تفويض بالتطابق الدقيق.

مراقبة انتهاء صلاحية الشهادات في الإنتاج

# تهيئة كشط Prometheus blackbox_exporter (prometheus.yml) scrape_configs: - job_name: 'tls_expiry' metrics_path: /probe params: module: [tcp_connect] static_configs: - targets: - api.example.com:443 - internal-gateway.prod.svc:8443 relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: blackbox-exporter:9115 # قاعدة تنبيه (alert.rules.yml) groups: - name: tls rules: - alert: CertExpiryWarning expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 30 for: 1h labels: severity: warning annotations: summary: "TLS cert expiring soon on {{ $labels.instance }}" - alert: CertExpiryCritical expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 7 for: 5m labels: severity: critical

إتقان PKI يفتح كل شيء في الدروس القادمة: يمكن لمحرك PKI في Vault أن يستبدل سير عمل openssl الثابت بالكامل، ليُصدر الشهادات برمجياً بصلاحيات تصل إلى ساعة واحدة، ويسحبها تلقائياً عند إيقاف خدمة ما. المفاهيم الأساسية من هذا الدرس — التسلسل الهرمي الثلاثي، دلالات SAN، مراحل دورة الحياة، وبناء السلسلة — هي الأساس الذي تحتاجه لتهيئة ذلك النظام بصورة صحيحة.