أنت الآن بصدد الاطّلاع على مستندات Apigee Edge.
انتقِل إلى
مستندات Apigee X. info
المشكلة
يتلقّى تطبيق العميل رمز حالة HTTP 503 مع الرسالة "الخدمة غير متوفرة" كاستجابة لطلب بيانات من واجهة برمجة التطبيقات.
في تتبُّع واجهة المستخدم، ستلاحظ أنّ error.cause
هو Received fatal alert: bad_certificate في "مسار الطلب المستهدَف"
لطلب البيانات غير الناجح من واجهة برمجة التطبيقات.
إذا كان بإمكانك الوصول إلى سجلّات Message Processor،
ستلاحظ رسالة الخطأ Received fatal alert: bad_certificate
لطلب بيانات من واجهة برمجة التطبيقات غير الناجح. يحدث هذا الخطأ أثناء عملية تبادل بيانات بروتوكول أمان طبقة النقل (SSL) بين "معالج الرسائل" وخادم الخلفية في إعداد بروتوكول أمان طبقة النقل (TLS) ثنائي الاتجاه.
رسالة الخطأ
يتلقّى تطبيق "العميل" رمز الاستجابة التالي:
HTTP/1.1 503 Service Unavailable
بالإضافة إلى ذلك، قد تظهر لك رسالة الخطأ التالية:
{
"fault": {
"faultstring":"The Service is temporarily unavailable",
"detail":{
"errorcode":"messaging.adaptors.http.flow.ServiceUnavailable"
}
}
}سيظهر لمستخدمي Private Cloud الخطأ التالي في طلب بيانات من واجهة برمجة التطبيقات المحدّد
في سجلات "معالج الرسائل" /opt/apigee/var/log/edge-message-processor/system.log:
2017-10-23 05:28:57,813 org:org-name env:env-name api:apiproxy-name
rev:revision-number messageid:message_id NIOThread@0 ERROR HTTP.CLIENT - HTTPClient$Context.handshakeFailed() :
SSLClientChannel[C:IP address:port # Remote host:IP address:port #]@65461
useCount=1 bytesRead=0 bytesWritten=0 age=529ms lastIO=529ms handshake failed,
message: Received fatal alert: bad_certificate
الأسباب المحتملة
في ما يلي الأسباب المحتملة لهذه المشكلة:
| السبب | الوصف | تعليمات تحديد المشاكل وحلّها التي تنطبق على |
| لا توجد شهادة عميل | لا يحتوي Keystore المستخدَم في نقطة النهاية المستهدَفة للخادم المستهدَف على أي شهادة عميل. | مستخدمو Edge Private Cloud وPublic Cloud |
| عدم تطابق هيئة إصدار الشهادات | لا تتطابق هيئة إصدار الشهادات الخاصة بشهادة العنصر الأخير (الشهادة الأولى في سلسلة الشهادات) في ملف تخزين المفاتيح الخاص بـ "معالج الرسائل" مع أي من هيئات إصدار الشهادات التي يقبلها خادم الخلفية. | مستخدمو Edge Private Cloud وPublic Cloud |
خطوات التشخيص الشائعة
- فعِّل التتبُّع في واجهة مستخدم Edge، ونفِّذ طلب البيانات من واجهة برمجة التطبيقات، وأعِد إظهار المشكلة.
- في نتائج تتبُّع واجهة المستخدم، تنقَّل بين كل مرحلة وحدِّد مكان حدوث الخطأ. كان من المفترض أن يحدث الخطأ في مسار طلب الاستهداف.
- افحص التدفق الذي يعرض الخطأ، وستلاحظ الخطأ كما هو موضّح في مثال التتبُّع أدناه:

- كما يظهر في لقطة الشاشة أعلاه، فإنّ error.cause هو "Received fatal alert: bad_certificate".
- إذا كنت مستخدمًا في Private Cloud، اتّبِع التعليمات التالية:
- يمكنك الحصول على معرّف الرسالة لطلب البيانات غير الناجح من واجهة برمجة التطبيقات من خلال تحديد قيمة عنوان الخطأ
X-Apigee.Message-IDفي المرحلة التي يشير إليها AX في التتبُّع. - ابحث عن معرّف الرسالة هذا في سجلّ "معالج الرسائل" (Message Processor)
/opt/apigee/var/log/edge-message-processor/system.logوحدِّد ما إذا كان بإمكانك العثور على أي معلومات إضافية حول الخطأ:2017-10-23 05:28:57,813 org:org-name env:env-name api:apiproxy-name rev:revision-number messageid:message_id NIOThread@0 ERROR HTTP.CLIENT - HTTPClient$Context.handshakeFailed() : SSLClientChannel[C:IP address:port # Remote host:IP address:port #]@65461 useCount=1 bytesRead=0 bytesWritten=0 age=529ms lastIO=529ms handshake failed, message: Received fatal alert: bad_certificate 2017-10-23 05:28:57,813 org:org-name env:env-name api:apiproxy-name rev:revision-number messageid:message_id NIOThread@0 ERROR HTTP.CLIENT - HTTPClient$Context.handshakeFailed() : SSLInfo: KeyStore:java.security.KeyStore@52de60d9 KeyAlias:KeyAlias TrustStore:java.security.KeyStore@6ec45759 2017-10-23 05:28:57,814 org:org-name env:env-name api:apiproxy-name rev:revision-number messageid:message_id NIOThread@0 ERROR ADAPTORS.HTTP.FLOW - RequestWriteListener.onException() : RequestWriteListener.onException(HTTPRequest@6071a73d) javax.net.ssl.SSLException: Received fatal alert: bad_certificate at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) ~[na:1.8.0_101] at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1666) ~[na:1.8.0_101] at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1634) ~[na:1.8.0_101] at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1800) ~[na:1.8.0_101] at com.apigee.nio.NIOSelector$SelectedIterator.findNext(NIOSelector.java:496) [nio-1.0.0.jar:na] at com.apigee.nio.util.NonNullIterator.computeNext(NonNullIterator.java:21) [nio-1.0.0.jar:na] at com.apigee.nio.util.AbstractIterator.hasNext(AbstractIterator.java:47) [nio-1.0.0.jar:na] at com.apigee.nio.NIOSelector$2.findNext(NIOSelector.java:312) [nio-1.0.0.jar:na] at com.apigee.nio.NIOSelector$2.findNext(NIOSelector.java:302) [nio-1.0.0.jar:na] at com.apigee.nio.util.NonNullIterator.computeNext(NonNullIterator.java:21) [nio-1.0.0.jar:na] at com.apigee.nio.util.AbstractIterator.hasNext(AbstractIterator.java:47) [nio-1.0.0.jar:na] at com.apigee.nio.handlers.NIOThread.run(NIOThread.java:59) [nio-1.0.0.jar:na]
تضمّن سجلّ "معالج الرسائل" عمليات مخزَّنة خاصة بتتبُّع تسلسل استدعاء الدوال البرمجية للخطأ
Received fatal alert: bad_certificate، ولكنّه لا يتضمّن أي معلومات أخرى تشير إلى سبب حدوث هذه المشكلة.
- يمكنك الحصول على معرّف الرسالة لطلب البيانات غير الناجح من واجهة برمجة التطبيقات من خلال تحديد قيمة عنوان الخطأ
- للتحقيق في هذه المشكلة بشكل أكبر، عليك التقاط حِزم TCP/IP باستخدام أداة tcpdump.
- إذا كنت مستخدمًا في Private Cloud، يمكنك تسجيل حِزم TCP/IP على خادم الخلفية أو "معالج الرسائل". يُفضّل التقاطها على خادم الخلفية لأنّه يتم فك تشفير الحِزم على خادم الخلفية.
- إذا كنت مستخدمًا في السحابة العامة، سجِّل حِزم TCP/IP على خادم الخلفية.
- بعد تحديد المكان الذي تريد التقاط حِزم TCP/IP فيه، استخدِم الأمر tcpdump أدناه لالتقاط حِزم TCP/IP.
tcpdump -i any -s 0 host <IP address> -w <File name>
إذا كنت تستخدم حِزم TCP/IP على "معالج الرسائل"، استخدِم عنوان IP المتاح للجميع الخاص بخادم الخلفية في الأمر
tcpdump.إذا كانت هناك عناوين IP متعددة لخادم الخلفية/معالج الرسائل، عليك استخدام أمر tcpdump مختلف. يُرجى الرجوع إلى tcpdump للحصول على مزيد من المعلومات حول هذه الأداة وغيرها من صيغ هذا الأمر.
- حلِّل حِزم TCP/IP باستخدام أداة Wireshark أو أداة مشابهة تعرفها.
في ما يلي تحليل لبيانات عيّنات حِزم TCP/IP باستخدام أداة Wireshark:

- تعرض الرسالة رقم 4 في tcpdump أعلاه أنّ"معالج الرسائل" (المصدر) أرسل رسالة Client Hello إلى خادم الخلفية (الوجهة).
- تعرض الرسالة رقم 5 أنّ خادم الخلفية يقرّ باستلام رسالة Client Hello من "معالج الرسائل".
- يرسل خادم الخلفية الرسالة "Server Hello" مع الشهادة، ثم يطلب من العميل إرسال الشهادة في الرسالة رقم 7.
- يُكمل "معالج الرسائل" عملية التحقّق من الشهادة ويقرّ باستلام رسالة ServerHello من خادم الخلفية في الرسالة رقم 8.
- يرسل "معالج الرسائل" شهادته إلى خادم الخلفية في الرسالة رقم 9.
- يقرّ خادم الخلفية باستلام شهادة معالج الرسائل في الرسالة رقم 11.
ومع ذلك، يرسل على الفور تنبيهًا خطيرًا: شهادة غير صالحة إلى معالج الرسائل (الرسالة رقم 12). يشير ذلك إلى أنّ الشهادة التي أرسلها معالج الرسائل كانت غير صالحة، وبالتالي تعذّر التحقّق من الشهادة على خادم الخلفية. نتيجةً لذلك، تعذّر تأكيد الاتصال عبر طبقة المقابس الآمنة (SSL) وسيتم إغلاق الاتصال.

لنلقِ نظرة الآن على الرسالة رقم 9 للتحقّق من محتوى الشهادة التي أرسلها معالج الرسائل:

- كما تلاحظ، لم يتلقَّ خادم الخلفية أي شهادة من العميل (Certificate Length: 0). وبالتالي، يرسل خادم الخلفية التنبيه Fatal Alert: Bad Certificate.
- يحدث ذلك عادةً عندما يكون "العميل"، أي "معالج الرسائل" (عملية مستندة إلى Java):
- ليس لديه أي شهادة عميل في KeyStore، أو
- يتعذّر إرسال شهادة عميل. يمكن أن يحدث ذلك إذا لم يتم العثور على شهادة صادرة عن أحد مراجع التصديق المقبولة في خادم الخلفية. وهذا يعني أنّه إذا لم يتطابق مرجع التصديق الخاص بشهادة العميل الطرفية (أي الشهادة الأولى في السلسلة) مع أي من مراجع التصديق المقبولة لخادم الخلفية، لن يرسل "معالج الرسائل" الشهادة.
لنلقِ نظرة على كل سبب من هذه الأسباب بشكل منفصل على النحو التالي.
السبب: عدم توفّر شهادة عميل
التشخيص
إذا لم تكن هناك شهادة في ملف تخزين المفاتيح المحدّد في قسم "معلومات SSL" في نقطة النهاية المستهدَفة أو الخادم المستهدَف المستخدَم في نقطة النهاية المستهدَفة، سيكون ذلك هو سبب هذا الخطأ.
اتّبِع الخطوات التالية لتحديد ما إذا كان هذا هو السبب:
- حدِّد ملف Keystore المستخدَم في نقطة النهاية المستهدَفة أو الخادم المستهدَف
لخادم وكيل API معيّن باتّباع الخطوات التالية:
- احصل على اسم مرجع Keystore من العنصر Keystore
في القسم SSLInfo في نقطة النهاية المستهدَفة أو الخادم المستهدَف.
لنلقِ نظرة على نموذج قسم SSLInfo في إعداد نقطة نهاية مستهدَفة:
<SSLInfo> <Enabled>true</Enabled> <ClientAuthEnabled>true</ClientAuthEnabled> <KeyStore>ref://myKeystoreRef</KeyStore> <KeyAlias>myKey</KeyAlias> <TrustStore>ref://myTrustStoreRef</TrustStore> </SSLInfo>
- في المثال أعلاه، اسم مرجع ملف تخزين المفاتيح هو "myKeystoreRef".
- انتقِل إلى واجهة مستخدم Edge واختَر خوادم وكيلة لواجهة برمجة التطبيقات -> إعدادات البيئة.
اختَر علامة التبويب المراجع وابحث عن اسم مرجع ملف تخزين المفاتيح. دوِّن الاسم في عمود المرجع لمرجع Keystore المحدّد. سيكون هذا هو اسم ملف تخزين المفاتيح.

- في المثال أعلاه، يمكنك ملاحظة أنّ myKeystoreRef يتضمّن مرجعًا إلى "myKeystore". وبالتالي، يكون اسم ملف Keystore هو myKeystore.
- احصل على اسم مرجع Keystore من العنصر Keystore
في القسم SSLInfo في نقطة النهاية المستهدَفة أو الخادم المستهدَف.
- تحقَّق مما إذا كان ملف تخزين المفاتيح هذا يحتوي على الشهادة باستخدام واجهة مستخدم Edge أو واجهة برمجة التطبيقات الخاصة بإدراج الشهادات لملف تخزين المفاتيح.
- إذا كان ملف Keystore يحتوي على شهادات، انتقِل إلى السبب: عدم تطابق مرجع التصديق.
- إذا لم يكن Keystore يحتوي على أي شهادة، فهذا هو السبب في عدم إرسال "شهادة العميل" من خلال "معالج الرسائل".
الدقة
- تأكَّد من تحميل سلسلة شهادات العميل المناسبة والكاملة إلى ملف تخزين المفاتيح المحدّد في "معالج الرسائل".
السبب: عدم تطابق هيئة إصدار الشهادات
بشكل عام، عندما يطلب الخادم من العميل إرسال شهادته، يشير إلى مجموعة جهات الإصدار أو مراجع التصديق المقبولة. إذا لم يتطابق جهة الإصدار/مرجع التصديق لشهادة العنصر الأخير (أي الشهادة الأولى في سلسلة الشهادات) في مخزن المفاتيح الخاص بـ "معالج الرسائل" مع أي من مراجع التصديق المقبولة من خادم الخلفية، لن يرسل "معالج الرسائل" (وهو عملية مستندة إلى Java) الشهادة إلى خادم الخلفية.
اتّبِع الخطوات التالية للتأكّد من ذلك:
- قائمة الشهادات لواجهة برمجة التطبيقات Keystore
- احصل على تفاصيل كل شهادة تم الحصول عليها في الخطوة 1 أعلاه باستخدام Get cert for keystore API.
- دوِّن جهة إصدار شهادة العنصر الأخير (أي الشهادة الأولى في سلسلة الشهادات) المخزَّنة في ملف تخزين المفاتيح.
نموذج شهادة Leaf
{ "certInfo" : [ { "basicConstraints" : "CA:FALSE", "expiryDate" : 1578889324000, "isValid" : "Yes", "issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com", "publicKey" : "RSA Public Key, 2048 bits", "serialNumber" : "65:00:00:00:d2:3e:12:d8:56:fa:e2:a9:69:00:06:00:00:00:d2", "sigAlgName" : "SHA256withRSA", "subject" : "CN=nonprod-api.mycompany.com, OU=ITS, O=MyCompany, L=MELBOURNE, ST=VIC, C=AU", "subjectAlternativeNames" : [ ], "validFrom" : 1484281324000, "version" : 3 } ], "certName" : "nonprod-api.mycompany.com.key.pem-cert" }في المثال أعلاه، الجهة المصدرة/هيئة إصدار الشهادات هي
"CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com" - حدِّد قائمة الجهات المصدرة أو هيئات إصدار الشهادات المقبولة لخادم الخلفية باستخدام إحدى الطرق التالية:
الأسلوب رقم 1: استخدام أمر openssl أدناه:
openssl s_client -host <backend server host name> -port <Backend port#> -cert <Client Certificate> -key <Client Private Key>
راجِع القسم بعنوان "أسماء هيئة إصدار شهادات العميل المقبولة" في ناتج هذا الأمر كما هو موضّح أدناه:
Acceptable client certificate CA names /C=AU/ST=VIC/L=MELBOURNE/O=MyCompany/OU=ITS/CN=nonprod-api.mycompany.com /C=AU/ST=VIC/L=MELBOURNE/O=MyCompany/OU=ITS/CN=nonprod-api.mycompany.com
الطريقة 2: التحقّق من حزمة
Certificate Requestفي حِزم TCP/IP، حيث يطلب خادم الخلفية من العميل إرسال شهادته:في حِزم TCP/IP النموذجية الموضّحة أعلاه، الحزمة
Certificate Requestهي الرسالة رقم 7. راجِع القسم "الأسماء المميزة"، الذي يتضمّن هيئات إصدار الشهادات المقبولة لخادم الخلفية.
تحقَّق مما إذا كانت هيئة إصدار الشهادات التي تم الحصول عليها في الخطوة 3 تتطابق مع قائمة جهات الإصدار أو هيئات إصدار الشهادات المقبولة من خادم الخلفية التي تم الحصول عليها في الخطوة 4. في حال عدم التطابق، لن يرسل "معالج الرسائل" شهادة العميل إلى خادم الخلفية.
في المثال أعلاه، يمكنك ملاحظة أنّ جهة إصدار شهادة العميل الطرفية في مخزن مفاتيح "معالج الرسائل" لا تتطابق مع أي من جهات إصدار الشهادات المقبولة في خادم الخلفية. وبالتالي، لا يرسل "معالج الرسائل" شهادة العميل إلى خادم الخلفية. يؤدي ذلك إلى تعذُّر عملية تأكيد الاتصال عبر SSL وإرسال الخادم الخلفي للرسالة "
Fatal alert: bad_certificate".
الدقة
- تأكَّد من تخزين الشهادة التي تتضمّن جهة الإصدار/هيئة إصدار الشهادات التي تتطابق مع جهة الإصدار/هيئة إصدار الشهادات الخاصة بشهادة العميل الطرفية (الشهادة الأولى في السلسلة) في Truststore لخادم الخلفية.
- في المثال الموضّح في دليل التشغيل هذا، تمّت إضافة الشهادة التي تحمل اسم الجهة المصدرة
"issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com"إلى ملف تخزين شهادات الأنظمة الخارجية الموثوقة في خادم الخلفية لحلّ المشكلة.
إذا استمرت المشكلة، انتقِل إلى Must Gather Diagnostic Information.
يجب جمع معلومات التشخيص
إذا استمرت المشكلة حتى بعد اتّباع التعليمات أعلاه، يُرجى جمع معلومات التشخيص التالية. يُرجى التواصل مع فريق دعم Apigee Edge ومشاركة ما يلي:
- إذا كنت من مستخدمي "السحابة العامة"، يُرجى تقديم المعلومات التالية:
- اسم المؤسسة
- اسم البيئة
- اسم خادم وكيل لواجهة برمجة التطبيقات
- أكمِل أمر curl لإعادة إظهار الخطأ
- ملف التتبُّع الذي يعرض الخطأ
- حِزم بروتوكول TCP/IP التي تم التقاطها على خادم الخلفية
- إذا كنت من مستخدمي Private Cloud، يُرجى تقديم المعلومات التالية:
- رسالة الخطأ الكاملة التي ظهرت
- حزمة خادم وكيل لواجهة برمجة التطبيقات
- ملف التتبُّع الذي يعرض الخطأ
- سجلّات "معالج الرسائل"
/opt/apigee/var/log/edge-message-processor/logs/system.log - حِزم بروتوكول TCP/IP التي تم التقاطها على خادم الخلفية أو "معالج الرسائل"
- ناتج Get cert for keystore API
- تفاصيل حول الأقسام التي جرّبتها في "دليل التشغيل" وأي إحصاءات أخرى تساعدنا في تسريع حلّ هذه المشكلة