SSL Handshake Failures - Bad Client Certificate

شما در حال مشاهده اسناد Apigee Edge هستید.
به مستندات Apigee X بروید .
اطلاعات

علامت

برنامه سرویس گیرنده یک کد وضعیت HTTP 503 را با پیام "سرویس در دسترس نیست" به عنوان پاسخ به یک درخواست API دریافت می کند. در ردیابی UI، مشاهده خواهید کرد که error.cause Received fatal alert: bad_certificate در جریان درخواست هدف برای درخواست API ناموفق است.

اگر به گزارش‌های پردازشگر پیام دسترسی دارید، متوجه پیام خطای Received fatal alert: bad_certificate برای درخواست API ناموفق. این خطا در طی فرآیند دست دادن SSL بین پردازشگر پیام و سرور باطن در راه اندازی TLS دو طرفه مشاهده می شود.

پیغام خطا

برنامه Client کد پاسخ زیر را دریافت می کند:

HTTP/1.1 503 Service Unavailable

علاوه بر این، ممکن است پیغام خطای زیر را مشاهده کنید:

{
 "fault": {
    "faultstring":"The Service is temporarily unavailable",
    "detail":{
        "errorcode":"messaging.adaptors.http.flow.ServiceUnavailable"
    }
 }
}

کاربران خصوصی Cloud خطای زیر را برای درخواست API خاص در گزارش‌های پردازشگر پیام /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 مورد استفاده در Target Endpoint Server Target هیچ گواهی مشتری ندارد. کاربران ابر خصوصی و عمومی Edge
عدم تطابق مرجع صدور گواهی مرجع صدور گواهینامه برگ (اولین گواهی در زنجیره گواهی) در فروشگاه کلید پردازشگر پیام با هیچ یک از مقامات گواهی پذیرفته شده توسط سرور باطن مطابقت ندارد. کاربران ابر خصوصی و عمومی Edge

مراحل تشخیص رایج

  1. Trace را در رابط کاربری Edge فعال کنید، تماس API را برقرار کنید و مشکل را تکرار کنید.
  2. در نتایج ردیابی UI، در هر فاز پیمایش کنید و مشخص کنید که خطا کجا رخ داده است. خطا در جریان درخواست هدف رخ داده است.
  3. جریانی را که خطا را نشان می دهد بررسی کنید، باید خطا را همانطور که در ردیابی مثال زیر نشان داده شده است مشاهده کنید:

    alt_text

  4. همانطور که در تصویر بالا مشاهده می کنید، error.cause عبارت است از "Received fatal alert: bad_certificate" .
  5. اگر کاربر Private Cloud هستید، دستورالعمل‌های زیر را دنبال کنید:
    1. شما می توانید شناسه پیام درخواست API ناموفق را با تعیین مقدار سرصفحه خطا " X-Apigee.Message-ID " در فازی که با AX در ردیابی نشان داده شده است، دریافت کنید.
    2. این شناسه پیام را در گزارش پردازشگر پیام /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 ، اما اطلاعات بیشتری که دلیل این مشکل را نشان دهد ندارد.

  6. برای بررسی بیشتر این موضوع، باید بسته های TCP/IP را با استفاده از ابزار tcpdump ضبط کنید.
    1. اگر کاربر Private Cloud هستید، می‌توانید بسته‌های TCP/IP را در سرور پشتیبان یا پردازشگر پیام ضبط کنید. ترجیحاً آنها را در سرور باطن ضبط کنید زیرا بسته ها در سرور باطن رمزگشایی می شوند.
    2. اگر کاربر Public Cloud هستید، بسته‌های TCP/IP را در سرور باطن ضبط کنید.
    3. هنگامی که تصمیم گرفتید کجا می خواهید بسته های TCP/IP را ضبط کنید، از دستور tcpdump زیر برای گرفتن بسته های TCP/IP استفاده کنید.
    4. tcpdump -i any -s 0 host <IP address> -w <File name>

      اگر بسته‌های TCP/IP را روی پردازشگر پیام می‌گیرید، از آدرس IP عمومی سرور backend در دستور tcpdump استفاده کنید.

      اگر چندین آدرس IP برای سرور پشتیبان/پردازنده پیام وجود دارد، باید از دستور tcpdump دیگری استفاده کنید. برای اطلاعات بیشتر در مورد این ابزار و سایر انواع این دستور به tcpdump مراجعه کنید.

  7. بسته های TCP/IP را با استفاده از ابزار Wireshark یا ابزار مشابهی که با آن آشنایی دارید، تجزیه و تحلیل کنید.

در اینجا تجزیه و تحلیل داده های بسته های TCP/IP نمونه با استفاده از ابزار Wireshark آمده است:

alt_text

  1. پیام شماره 4 در tcpdump بالا نشان می دهد که پردازشگر پیام (منبع) یک پیام "Client Hello" را به سرور پشتیبان (مقصد) ارسال کرده است.
  2. پیام شماره 5 نشان می دهد که سرور باطن پیام Client Hello را از پردازشگر پیام تأیید می کند.
  3. سرور باطن پیام "Server Hello" را همراه با گواهی خود ارسال می کند و سپس از مشتری درخواست می کند تا گواهی خود را در پیام شماره 7 ارسال کند.
  4. پردازشگر پیام تأیید گواهی را تکمیل می کند و پیام ServerHello سرور باطن را در پیام شماره 8 تأیید می کند.
  5. پردازشگر پیام گواهینامه خود را به سرور پشتیبان در پیام شماره 9 ارسال می کند.
  6. سرور باطن دریافت گواهی پردازشگر پیام را در پیام شماره 11 تأیید می کند.
  7. با این حال، بلافاصله یک هشدار مرگبار: گواهی بد به پردازشگر پیام ارسال می کند (پیام شماره 12). این نشان می دهد که گواهی ارسال شده توسط پردازشگر پیام بد بود و از این رو تأیید گواهی در سرور باطن ناموفق بود. در نتیجه، SSL Handshake ناموفق بوده و اتصال بسته خواهد شد.


    alt_text

  8. بیایید اکنون به پیام شماره 9 نگاه کنیم تا محتوای گواهی ارسال شده توسط پردازشگر پیام را بررسی کنیم:


    alt_text

  9. همانطور که متوجه شدید، سرور باطن هیچ گواهی از مشتری دریافت نکرد ( طول گواهی: 0) . از این رو، سرور باطن، Fatal Alert: Bad Certificate را ارسال می کند.
  10. معمولاً این اتفاق زمانی می‌افتد که Client، یعنی پردازشگر پیام (فرایند مبتنی بر جاوا):
    1. هیچ گواهی مشتری در KeyStore خود ندارد، یا
    2. قادر به ارسال گواهی مشتری نیست. اگر نتواند گواهی صادر شده توسط یکی از مراجع صدور گواهی قابل قبول سرور Backend را پیدا کند، این اتفاق می افتد. به این معنی که اگر مرجع صدور گواهینامه برگ مشتری (یعنی اولین گواهی در زنجیره) با هیچ یک از مقامات گواهی قابل قبول سرور باطن مطابقت نداشته باشد، پردازشگر پیام گواهی را ارسال نخواهد کرد.

اجازه دهید هر یک از این علل را به صورت جداگانه بررسی کنیم.

علت: نداشتن گواهی مشتری

تشخیص

اگر هیچ گواهی در Keystore مشخص شده در بخش SSL Info در Target Endpoint یا سرور هدف مورد استفاده در Target Endpoint وجود ندارد، دلیل این خطا همین است.

مراحل زیر را دنبال کنید تا تشخیص دهید که آیا این علت است یا خیر:

  1. با استفاده از مراحل زیر، Keystore مورد استفاده در Target Endpoint یا Target Server برای پروکسی API خاص را تعیین کنید:
    1. نام مرجع Keystore را از عنصر Keystore در بخش SSLInfo در Target Endpoint یا Target Server دریافت کنید.

      بیایید به یک بخش نمونه SSLInfo در پیکربندی نقطه پایانی هدف نگاه کنیم:

      <SSLInfo>
        <Enabled>true</Enabled>
        <ClientAuthEnabled>true</ClientAuthEnabled>
        <KeyStore>ref://myKeystoreRef</KeyStore>
        <KeyAlias>myKey</KeyAlias>
        <TrustStore>ref://myTrustStoreRef</TrustStore>
      </SSLInfo>
    2. در مثال بالا، نام مرجع Keystore " myKeystoreRef" است.
    3. به Edge UI بروید و API Proxies -> Environment Configurations را انتخاب کنید.

      برگه References را انتخاب کرده و نام مرجع Keystore را جستجو کنید. نام را در ستون Reference برای مرجع خاص Keystore یادداشت کنید. این نام Keystore شما خواهد بود.


      alt_text

    4. در مثال بالا، می توانید متوجه شوید که myKeystoreRef ارجاع به "myKeystore" دارد. بنابراین، نام Keystore myKeystore است.
  2. بررسی کنید که آیا این Keystore حاوی گواهی است یا با استفاده از رابط کاربری Edge یا گواهی‌های List for keystore API .
  3. اگر فروشگاه کلید حاوی گواهی(های) باشد، به Cause: Certificate Authority Mismatch بروید.
  4. اگر Keystore حاوی هیچ گواهی نیست، پس دلیل ارسال نشدن گواهی مشتری توسط پردازشگر پیام است.

قطعنامه

  1. اطمینان حاصل کنید که زنجیره مناسب و کامل Client Certificate در Keystore خاص در پردازشگر پیام آپلود شده است.

علت: عدم تطابق مرجع صدور گواهی

به طور کلی هنگامی که سرور از مشتری درخواست می کند تا گواهینامه خود را ارسال کند، مجموعه ای از صادرکنندگان یا مقامات گواهی پذیرفته شده را نشان می دهد. اگر مرجع صادرکننده/گواهینامه گواهی برگ (یعنی اولین گواهی در زنجیره گواهی) در فروشگاه کلید پردازشگر پیام با هیچ یک از مقامات گواهی پذیرفته شده توسط سرور باطن مطابقت نداشته باشد، پردازشگر پیام (که یک فرآیند مبتنی بر جاوا است). ) گواهی را به سرور باطن ارسال نمی کند.

برای تأیید اینکه آیا این مورد است، از مراحل زیر استفاده کنید:

  1. لیست گواهی ها برای keystore API .
  2. با استفاده از Get Cert for Keystore API، جزئیات هر گواهی را که در مرحله شماره 1 در بالا به دست آمده است، دریافت کنید.
  3. صادرکننده برگ گواهی (یعنی اولین گواهی در زنجیره گواهی) ذخیره شده در Keystore را یادداشت کنید.

    نمونه برگ گواهی

    {
      "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" است.

  4. با استفاده از یکی از تکنیک های زیر، فهرست پذیرفته شده صادرکنندگان یا مراجع صدور گواهی سرور باطن را تعیین کنید:

    تکنیک شماره 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» مراجعه کنید:

    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 است. به بخش "نام های متمایز" که حاوی مقامات گواهی قابل قبول سرور باطن است مراجعه کنید.

    alt_text

  5. بررسی کنید که آیا مرجع صدور گواهی که در مرحله شماره 3 به دست آمده است، با لیست صادرکنندگان پذیرفته شده سرور یا مراجع صدور گواهی که در مرحله 4 به دست آمده است مطابقت دارد یا خیر. اگر عدم تطابق وجود داشته باشد، پردازشگر پیام گواهی مشتری را به سرور باطن ارسال نخواهد کرد.

    در مثال بالا، می توانید متوجه شوید که صادرکننده گواهی برگ مشتری در فروشگاه کلید پردازشگر پیام با هیچ یک از مقامات گواهی پذیرفته شده سرور باطن مطابقت ندارد. از این رو، پردازشگر پیام، گواهی مشتری را به سرور پشتیبان ارسال نمی کند. این باعث می شود که SSL handshake از کار بیفتد و سرور باطن پیام " Fatal alert: bad_certificate " را ارسال کند.

قطعنامه

  1. اطمینان حاصل کنید که گواهی با صادرکننده/مرجع صدور گواهی مطابق با صادرکننده/مرجع صدور گواهی گواهی برگ مشتری (اولین گواهی در زنجیره) در Truststore سرور پشتیبان ذخیره شده است.
  2. در مثالی که در این کتاب توضیح داده شده است، گواهی با "issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com" به باطن اضافه شد Truststore سرور برای حل مشکل.

اگر مشکل همچنان ادامه داشت، به «اطلاعات تشخیصی باید جمع‌آوری شود» بروید.

باید اطلاعات تشخیصی را جمع آوری کرد

اگر حتی پس از پیروی از دستورالعمل‌های بالا، مشکل همچنان ادامه داشت، لطفاً اطلاعات تشخیصی زیر را جمع‌آوری کنید. تماس بگیرید و آنها را با پشتیبانی Apigee Edge به اشتراک بگذارید:

  1. اگر کاربر Public Cloud هستید، اطلاعات زیر را ارائه دهید:
    1. نام سازمان
    2. نام محیطی
    3. نام پروکسی API
    4. برای بازتولید خطا، دستور curl را کامل کنید
    5. فایل ردیابی خطا را نشان می دهد
    6. بسته های TCP/IP که در سرور باطن ضبط شده اند
  2. اگر کاربر Private Cloud هستید، اطلاعات زیر را ارائه دهید:
    1. پیام خطای کامل مشاهده شد
    2. بسته پروکسی API
    3. فایل ردیابی خطا را نشان می دهد
    4. گزارش‌های پردازشگر پیام /opt/apigee/var/log/edge-message-processor/logs/system.log
    5. بسته های TCP/IP که در سرور باطن یا پردازشگر پیام ضبط شده اند.
    6. خروجی Get cert for keystore API .
  3. جزئیات مربوط به بخش‌هایی که در این کتاب راهنما امتحان کرده‌اید و هر بینش دیگری که به ما در حل سریع این مشکل کمک می‌کند.