Kegagalan Jabat Tangan SSL - Sertifikat Klien Buruk

Anda sedang melihat dokumentasi Apigee Edge.
Buka dokumentasi Apigee X.
info

Gejala

Aplikasi klien menerima kode status HTTP 503 dengan pesan "Service memperkirakan" sebagai respons terhadap permintaan API. Dalam rekaman aktivitas UI, Anda akan mengamati bahwa error.cause adalah Received fatal alert: bad_certificate dalam Alur Permintaan Target untuk permintaan API yang gagal.

Jika memiliki akses ke log Message Processor, Anda akan melihat pesan error sebagai Received fatal alert: bad_certificate untuk permintaan API yang gagal. Error ini teramati selama proses handshake SSL antara Message Processor dan server backend dalam penyiapan TLS 2 arah.

Pesan Error

Aplikasi Klien mendapatkan kode respons berikut:

HTTP/1.1 503 Service Unavailable

Selain itu, Anda mungkin melihat pesan error berikut:

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

Pengguna Private Cloud akan melihat error berikut untuk permintaan API tertentu di log 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

Kemungkinan Penyebab

Kemungkinan penyebab masalah ini adalah sebagai berikut:

Cause Deskripsi Petunjuk Pemecahan Masalah Berlaku Untuk
Tidak Ada Sertifikat Klien Keystore yang digunakan pada Target Endpoint Server Target tidak memiliki Sertifikat Klien. Pengguna Cloud Pribadi dan Publik Edge
Ketidakcocokan Certificate Authority Certificate Authority dari leaf certificate (Sertifikat pertama dalam rantai Sertifikat) di Keystore Pemroses Pesan tidak cocok dengan Certificate Authority mana pun yang diterima oleh server backend. Pengguna Cloud Pribadi dan Publik Edge

Langkah Diagnosis Umum

  1. Aktifkan rekaman aktivitas di UI Edge, lakukan panggilan API, dan rekonstruksi masalah.
  2. Pada hasil rekaman aktivitas UI, lihat setiap Fase dan tentukan tempat terjadinya error. Error ini akan terjadi di Alur Permintaan Target.
  3. Periksa Flow yang menampilkan error, Anda harus mengamati error seperti yang ditunjukkan dalam contoh rekaman aktivitas di bawah ini:

    alt_text

  4. Seperti yang Anda lihat pada screenshot di atas, error.cause adalah error.cause .
  5. Jika Anda adalah pengguna Private Cloud, ikuti petunjuk di bawah ini:
    1. Anda bisa mendapatkan ID pesan untuk permintaan API yang gagal dengan menentukan nilai Header Error "X-Apigee.Message-ID" dalam Fase yang ditunjukkan oleh AX dalam rekaman aktivitas.
    2. Telusuri ID pesan ini dalam log Message Processor /opt/apigee/var/log/edge-message-processor/system.log dan tentukan apakah Anda dapat menemukan informasi lebih lanjut terkait error tersebut:
      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]
      

      Log Message Processor memiliki pelacakan tumpukan untuk error Received fatal alert: bad_certificate, tetapi tidak memiliki informasi lebih lanjut yang menunjukkan penyebab masalah ini.

  6. Untuk menyelidiki masalah ini lebih lanjut, Anda perlu mengambil paket TCP/IP menggunakan alat tcpdump.
    1. Jika Anda adalah pengguna Private Cloud, Anda dapat merekam paket TCP/IP di server backend atau Pemroses Pesan. Sebaiknya, ambil data di server backend karena paket didekripsi di server backend.
    2. Jika Anda adalah pengguna Cloud Publik, rekam paket TCP/IP di server backend.
    3. Setelah menentukan tempat untuk merekam paket TCP/IP, gunakan perintah tcpdump di bawah ini untuk merekam paket TCP/IP.
    4. tcpdump -i any -s 0 host <IP address> -w <File name>

      Jika Anda mengambil paket TCP/IP di Pemroses Pesan, gunakan alamat IP publik server backend dalam perintah tcpdump.

      Jika ada beberapa alamat IP untuk server backend/Prosesor Pesan, Anda harus menggunakan perintah tcpdump yang berbeda. Lihat tcpdump untuk mengetahui informasi selengkapnya tentang alat ini dan varian lain dari perintah ini.

  7. Analisis paket TCP/IP menggunakan alat Wireshark atau alat serupa yang Anda ketahui.

Berikut adalah analisis sampel data paket TCP/IP menggunakan alat Wireshark:

alt_text

  1. Pesan #4 dalam tcpdump di atas menunjukkan bahwa Message Processor (sumber) mengirim pesan "Client Hello" ke server backend (destination).
  2. Pesan #5 menunjukkan bahwa server backend mengonfirmasi pesan Client Hello dari Pemroses Pesan.
  3. Server backend mengirim pesan "Server Hello" bersama dengan Sertifikat-nya, lalu meminta Klien untuk mengirim Sertifikat-nya di Pesan #7.
  4. Pemroses Pesan menyelesaikan verifikasi Sertifikat dan mengonfirmasi pesan ServerHello server backend di Pesan #8.
  5. Pemroses Pesan mengirimkan Sertifikat-nya ke server backend di Pesan #9.
  6. Server backend mengonfirmasi penerimaan Sertifikat Pemroses Pesan di Pesan #11.
  7. Namun, layanan ini akan langsung mengirimkan Fatal Alert: Bad Certificate ke Pemroses Pesan (Pesan #12). Hal ini menunjukkan bahwa Sertifikat yang dikirim oleh Message Processor buruk sehingga Verifikasi Sertifikat gagal pada server backend. Akibatnya, SSL Handshake gagal dan koneksi akan ditutup.


    alt_text

  8. Sekarang, mari kita lihat Pesan #9 untuk memeriksa isi sertifikat yang dikirim oleh Pemroses Pesan:


    alt_text

  9. Seperti yang dapat Anda lihat, server backend tidak mendapatkan Sertifikat apa pun dari Klien (Panjang Sertifikat: 0). Oleh karena itu, server backend mengirimkan Peringatan Fatal: Sertifikat Buruk.
  10. Hal ini biasanya terjadi saat Klien, yaitu, Message Processor (proses berbasis Java):
    1. Tidak memiliki Sertifikat Klien di KeyStore-nya, atau;
    2. Tidak dapat mengirimkan Sertifikat Klien. Hal ini dapat terjadi jika Server tidak dapat menemukan Sertifikat yang diterbitkan oleh salah satu Certificate Authority Server Backend yang dapat diterima. Artinya, jika Certificate Authority untuk Leaf Certificate Klien (yaitu Sertifikat pertama dalam rantai) tidak cocok dengan Certificate Authority yang dapat diterima di server backend mana pun, Pemroses Pesan tidak akan mengirimkan sertifikat tersebut.

Mari kita lihat setiap penyebab tersebut secara terpisah sebagai berikut.

Penyebab: Tidak Ada Sertifikat Klien

Diagnosis

Jika tidak ada Sertifikat di Keystore yang ditentukan di bagian Info SSL pada Endpoint Target atau server target yang digunakan di Endpoint Target, maka itulah penyebab error ini.

Ikuti langkah-langkah di bawah untuk menentukan apakah hal tersebut merupakan penyebabnya:

  1. Tentukan Keystore yang digunakan di Endpoint Target atau Server Target untuk Proxy API tertentu menggunakan langkah-langkah berikut:
    1. Dapatkan nama referensi Keystore dari elemen Keystore di bagian SSLInfo pada Target Endpoint atau Server Target.

      Mari kita lihat contoh bagian SSLInfo di Konfigurasi Endpoint Target:

      <SSLInfo>
        <Enabled>true</Enabled>
        <ClientAuthEnabled>true</ClientAuthEnabled>
        <KeyStore>ref://myKeystoreRef</KeyStore>
        <KeyAlias>myKey</KeyAlias>
        <TrustStore>ref://myTrustStoreRef</TrustStore>
      </SSLInfo>
    2. Dalam contoh di atas, nama referensi Keystore adalah "myKeystoreRef".
    3. Buka Edge UI, lalu pilih API Proxies -> Environment Configurations.

      Pilih tab Referensi, lalu cari nama referensi Keystore. Catat nama di kolom Referensi untuk referensi Keystore tertentu. Ini akan menjadi nama Keystore Anda.


      alt_text

    4. Pada contoh di atas, Anda dapat melihat bahwa myKeystoreRef memiliki referensi ke "myKeystore". Oleh karena itu, nama Keystore adalah myKeystore.
  2. Periksa apakah Keystore ini berisi Sertifikat menggunakan UI Edge atau Daftar sertifikat untuk API keystore.
  3. Jika Keystore berisi Sertifikat, maka pindahkan ke Penyebab: Ketidakcocokan Certificate Authority.
  4. Jika Keystore tidak berisi Sertifikat apa pun, maka itulah alasan Sertifikat Klien tidak dikirim oleh Pemroses Pesan.

Resolusi

  1. Pastikan rantai Sertifikat Klien yang tepat dan lengkap diupload ke Keystore tertentu di Pemroses Pesan.

Penyebab: Ketidakcocokan Certificate Authority

Umumnya, saat Server meminta Klien untuk mengirim Sertifikat-nya, hal ini menunjukkan kumpulan Penerbit atau Certificate Authority yang diterima. Jika Penerbit/Certificate Authority dari leaf certificate (yaitu, Sertifikat pertama dalam rantai Sertifikat) di Keystore Pemroses Pesan tidak cocok dengan salah satu Certificate Authority yang diterima oleh server backend, Pemroses Pesan (yang merupakan proses berbasis Java) tidak akan mengirim Sertifikat ke server backend.

Gunakan langkah-langkah di bawah untuk mengonfirmasi apakah hal ini yang terjadi:

  1. Mencantumkan sertifikat untuk API keystore.
  2. Dapatkan Detail setiap Sertifikat yang diperoleh pada Langkah #1 di atas menggunakan Dapatkan sertifikat untuk keystore API.
  3. Catat penerbit Sertifikat leaf (yaitu, Sertifikat pertama dalam rantai sertifikat) yang disimpan di Keystore.

    Contoh Leaf Certificate

    {
      "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"
    }
    

    Pada contoh di atas, penerbit/Certificate Authority adalah "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com"

  4. Tentukan daftar Penerbit atau Certificate Authority yang diterima server backend menggunakan salah satu teknik berikut:

    Teknik #1: Gunakan perintah openssl di bawah:

    openssl s_client -host <backend server host name> -port <Backend port#> -cert <Client Certificate> -key <Client Private Key>
    

    Lihat bagian yang berjudul "Nama CA Sertifikat Klien yang Dapat Diterima" dalam output perintah ini seperti yang ditunjukkan di bawah ini:

    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
    

    Teknik #2: Periksa paket Certificate Request di Paket TCP/IP, tempat server backend meminta Klien untuk mengirimkan sertifikatnya:

    Dalam contoh paket TCP/IP yang ditampilkan di atas, paket Certificate Request adalah pesan #7. Lihat bagian "Nama yang Dibedakan", yang berisi Certificate Authority yang Dapat Diterima server backend.

    alt_text

  5. Verifikasi apakah Certificate Authority yang diperoleh di langkah 3 cocok dengan daftar Penerbit atau Certificate Authority yang diterima di server backend yang diperoleh di langkah #4. Jika terdapat ketidakcocokan, Message Processor tidak akan mengirim Sertifikat Klien ke server backend.

    Dalam contoh di atas, Anda dapat melihat bahwa penerbit Leaf Certificate Klien di Keystore Pemroses Pesan tidak cocok dengan Otoritas Sertifikat yang Diterima milik server backend. Oleh karena itu, Pemroses Pesan tidak mengirim Sertifikat Klien ke server backend. Hal ini menyebabkan handshake SSL gagal dan server backend mengirim pesan "Fatal alert: bad_certificate".

Resolusi

  1. Pastikan sertifikat dari penerbit/Certificate Authority yang cocok dengan penerbit/Certificate Authority dari Leaf Certificate Klien (sertifikat pertama dalam rantai) disimpan di Truststore server backend.
  2. Dalam contoh yang dijelaskan dalam Playbook ini, Sertifikat dengan penerbit "issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com" ditambahkan ke Truststore server backend untuk menyelesaikan masalah ini.

Jika masalah masih berlanjut, buka Harus Mengumpulkan Informasi Diagnostik.

Harus Mengumpulkan Informasi Diagnostik

Jika masalah terus berlanjut bahkan setelah mengikuti petunjuk di atas, kumpulkan informasi diagnostik berikut. Hubungi dan bagikan ke Dukungan Apigee Edge:

  1. Jika Anda adalah pengguna Cloud Publik, berikan informasi berikut:
    1. Nama Organisasi
    2. Nama Lingkungan
    3. Nama Proxy API
    4. Menyelesaikan perintah curl untuk mereproduksi error
    5. File Rekaman Aktivitas yang menunjukkan error
    6. Paket TCP/IP yang ditangkap di server backend
  2. Jika Anda adalah pengguna Private Cloud, berikan informasi berikut:
    1. Pesan Error Lengkap yang diamati
    2. Paket Proxy API
    3. File Rekaman Aktivitas yang menunjukkan error
    4. Log Pemroses Pesan /opt/apigee/var/log/edge-message-processor/logs/system.log
    5. Paket TCP/IP yang ditangkap di server backend atau Prosesor Pesan.
    6. Output Get cert for keystore API.
  3. Detail tentang bagian mana dalam Playbook ini yang telah Anda coba dan insight lain yang akan membantu kami menyelesaikan masalah ini dengan cepat.