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 "Layanan Tidak Tersedia" sebagai respons terhadap permintaan API. Di rekaman aktivitas UI, Anda akan melihat bahwa error.cause adalah Received fatal alert: bad_certificate dalam Alur Permintaan Target untuk permintaan API yang gagal.

Jika Anda memiliki akses ke log Message Processor, Anda akan melihat pesan error sebagai Received fatal alert: bad_certificate untuk permintaan API yang gagal. Error ini diamati 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 yang Berlaku Untuk
Tidak Ada Sertifikat Klien Keystore yang digunakan di Target Endpoint Target Server tidak memiliki Sertifikat Klien. Pengguna Edge Private dan Public Cloud
Ketidakcocokan Certificate Authority Certificate Authority sertifikat leaf (Sertifikat pertama dalam rantai Sertifikat) di Keystore Message Processor tidak cocok dengan Certificate Authority yang diterima oleh server backend. Pengguna Edge Private dan Public Cloud

Langkah-Langkah Diagnosis Umum

  1. Aktifkan rekaman aktivitas di UI Edge, lakukan panggilan API, dan reproduksi masalah.
  2. Di hasil rekaman aktivitas UI, buka setiap Fase dan tentukan tempat terjadinya error. Error akan terjadi di Alur Permintaan Target.
  3. Periksa Alur yang menunjukkan error, Anda akan melihat error seperti yang ditunjukkan dalam contoh rekaman aktivitas di bawah:

    alt_text

  4. Seperti yang Anda lihat pada screenshot di atas, error.cause adalah "Received fatal alert: bad_certificate".
  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 di log Message Processor /opt/apigee/var/log/edge-message-processor/system.log dan tentukan apakah Anda dapat menemukan informasi lebih lanjut tentang 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 stack trace 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 merekam paket TCP/IP menggunakan alat tcpdump.
    1. Jika Anda adalah pengguna Private Cloud, Anda dapat merekam paket TCP/IP di server backend atau Message Processor. Sebaiknya, ambil di server backend saat paket didekripsi di server backend.
    2. Jika Anda adalah pengguna Cloud Publik, ambil paket TCP/IP di server backend.
    3. Setelah Anda memutuskan tempat untuk merekam paket TCP/IP, gunakan perintah tcpdump di bawah untuk merekam paket TCP/IP.
    4. tcpdump -i any -s 0 host <IP address> -w <File name>

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

      Jika ada beberapa alamat IP untuk server backend/Message Processor, 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 kuasai.

Berikut analisis data paket TCP/IP contoh menggunakan alat Wireshark:

alt_text

  1. Pesan #4 di tcpdump di atas menunjukkan bahwa Message Processor (sumber) mengirim pesan "Client Hello" ke server backend (tujuan).
  2. Pesan #5 menunjukkan bahwa server backend mengonfirmasi pesan Client Hello dari Message Processor.
  3. Server backend mengirimkan pesan "Server Hello" beserta Sertifikatnya, lalu meminta Klien untuk mengirimkan Sertifikatnya dalam Pesan #7.
  4. Prosesor Pesan menyelesaikan verifikasi Sertifikat dan mengonfirmasi pesan ServerHello server backend di Pesan #8.
  5. Prosesor Pesan mengirimkan Sertifikatnya ke server backend dalam Pesan #9.
  6. Server backend mengonfirmasi penerimaan Sertifikat Proses Pesan dalam Pesan #11.
  7. Namun, segera mengirimkan Fatal Alert: Bad Certificate ke Message Processor (Message #12). Hal ini menunjukkan bahwa Sertifikat yang dikirim oleh Message Processor tidak valid sehingga Verifikasi Sertifikat gagal di server backend. Akibatnya, Handshake SSL gagal dan koneksi akan ditutup.


    alt_text

  8. Sekarang, mari kita lihat Message #9 untuk memeriksa konten sertifikat yang dikirim oleh Message Processor:


    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 Fatal Alert: Bad Certificate.
  10. Biasanya hal ini terjadi saat Klien, yaitu Pemroses Pesan (proses berbasis Java):
    1. Tidak memiliki Sertifikat Klien apa pun di KeyStore-nya, atau;
    2. Tidak dapat mengirim Sertifikat Klien. Hal ini dapat terjadi jika tidak dapat menemukan Sertifikat yang diterbitkan oleh salah satu Otoritas Sertifikat yang dapat diterima oleh Server Backend. Artinya, jika Certificate Authority dari Sertifikat Leaf Klien (yaitu, Sertifikat pertama dalam rantai) tidak cocok dengan Certificate Authority server backend yang dapat diterima, maka Message Processor tidak akan mengirim sertifikat.

Mari kita lihat setiap penyebab ini secara terpisah sebagai berikut.

Penyebab: Tidak Ada Sertifikat Klien

Diagnosis

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

Ikuti langkah-langkah di bawah untuk menentukan apakah ini penyebabnya:

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

      Mari kita lihat contoh bagian SSLInfo dalam Konfigurasi Endpoint Target:

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

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


      alt_text

    4. Dalam 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 Edge UI atau List certs for keystore API.
  3. Jika Keystore berisi Sertifikat, lanjutkan ke Penyebab: Ketidakcocokan Certificate Authority.
  4. Jika Keystore tidak berisi Sertifikat apa pun, itulah alasan mengapa Sertifikat Klien tidak dikirim oleh Pemroses Pesan.

Resolusi

  1. Pastikan rantai Sertifikat Klien yang tepat dan lengkap diupload ke Keystore tertentu di Message Processor.

Penyebab: Ketidakcocokan Certificate Authority

Biasanya saat Server meminta Klien untuk mengirimkan Sertifikatnya, Server menunjukkan kumpulan Penerbit atau Otoritas Sertifikat yang diterima. Jika Penerbit/Certificate Authority sertifikat leaf (yaitu, Sertifikat pertama dalam rantai Sertifikat) di Keystore Message Processor tidak cocok dengan Certificate Authority yang diterima oleh server backend, maka Message Processor (yang merupakan proses berbasis Java) tidak akan mengirimkan Sertifikat ke server backend.

Ikuti langkah-langkah di bawah untuk mengonfirmasi apakah hal ini terjadi:

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

    Contoh Sertifikat Daun

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

    Dalam contoh di atas, penerbit/Otoritas Sertifikat adalah "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com"

  4. Tentukan daftar Penerbit atau Otoritas Sertifikat 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 berjudul "Acceptable Client Certificate CA names" dalam output perintah ini seperti yang ditunjukkan di bawah:

    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 TCP/IP Packets, tempat server backend meminta Klien untuk mengirimkan sertifikatnya:

    Dalam paket TCP/IP contoh yang ditunjukkan di atas, paket Certificate Request adalah pesan #7. Lihat bagian "Nama Pembeda", yang berisi Otoritas Sertifikat yang Dapat Diterima dari server backend.

    alt_text

  5. Verifikasi apakah Otoritas Sertifikat yang diperoleh pada langkah #3 cocok dengan daftar Penerbit atau Otoritas Sertifikat yang diterima server backend yang diperoleh pada langkah #4. Jika ada ketidakcocokan, Pemroses Pesan tidak akan mengirim Sertifikat Klien ke server backend.

    Dalam contoh di atas, Anda dapat melihat bahwa penerbit Sertifikat Leaf Klien di Keystore Message Processor tidak cocok dengan Otoritas Sertifikat yang Diterima 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 dengan penerbit/Certificate Authority yang cocok dengan penerbit/Certificate Authority Sertifikat Leaf 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 mengatasi masalah.

Jika masalah masih berlanjut, buka Must Gather Diagnostic Information.

Mengumpulkan Informasi Diagnostik yang Wajib

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

  1. Jika Anda adalah pengguna Public Cloud, berikan informasi berikut:
    1. Nama Organisasi
    2. Nama Lingkungan
    3. Nama Proxy API
    4. Perintah curl lengkap untuk mereproduksi error
    5. File Detail Migrasi yang menampilkan error
    6. Paket TCP/IP yang diambil 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 Detail Migrasi yang menampilkan error
    4. Log Message Processor /opt/apigee/var/log/edge-message-processor/logs/system.log
    5. Paket TCP/IP yang diambil di server backend atau Message Processor.
    6. Output Get cert for keystore API.
  3. Detail tentang bagian mana dalam Playbook ini yang telah Anda coba dan insight lainnya yang akan membantu kami mempercepat penyelesaian masalah ini.