Lỗi giao tiếp SSL - Chứng chỉ ứng dụng khách không hợp lệ

Bạn đang xem tài liệu về Apigee Edge.
Chuyển đến tài liệu về Apigee X.
thông tin

Triệu chứng

Ứng dụng sẽ nhận được mã trạng thái HTTP 503 với thông báo "Service availability" (Dịch vụ không hoạt động) dưới dạng phản hồi cho một yêu cầu API. Trong dấu vết giao diện người dùng, bạn sẽ quan sát thấy rằng error.cause Received fatal alert: bad_certificate trong Luồng yêu cầu mục tiêu đối với yêu cầu API không thành công.

Nếu có quyền truy cập vào nhật ký Trình xử lý thông báo, bạn sẽ thấy thông báo lỗi với nội dung Received fatal alert: bad_certificate cho yêu cầu API không thành công. Lỗi này xảy ra trong quá trình bắt tay SSL giữa Bộ xử lý thông báo và máy chủ phụ trợ trong quá trình thiết lập TLS 2 chiều.

Thông báo lỗi

Ứng dụng nhận được mã phản hồi sau đây:

HTTP/1.1 503 Service Unavailable

Ngoài ra, bạn có thể nhận thấy thông báo lỗi sau:

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

Người dùng Đám mây riêng tư sẽ thấy lỗi sau đây đối với một yêu cầu API cụ thể trong nhật ký Trình xử lý thư /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

Nguyên nhân có thể xảy ra

Các nguyên nhân có thể dẫn đến vấn đề này như sau:

Nguyên nhân Mô tả Hướng dẫn khắc phục sự cố có thể áp dụng cho
Không có chứng chỉ ứng dụng khách Kho khoá được dùng trong Điểm cuối mục tiêu của Máy chủ đích không có bất kỳ Chứng chỉ ứng dụng nào. Người dùng Edge riêng và công khai trên đám mây
Tổ chức phát hành chứng chỉ không khớp Tổ chức phát hành chứng chỉ của chứng chỉ lá (Chứng chỉ đầu tiên trong chuỗi Chứng chỉ) trong Kho khoá của Trình xử lý thông báo không khớp với bất kỳ Tổ chức phát hành chứng chỉ nào được máy chủ phụ trợ chấp nhận. Người dùng Edge riêng và công khai trên đám mây

Các bước chẩn đoán thông thường

  1. Bật tính năng theo dõi trong giao diện người dùng Edge, thực hiện lệnh gọi API và tái tạo vấn đề.
  2. Trong kết quả theo dõi giao diện người dùng, hãy di chuyển qua từng Giai đoạn và xác định vị trí xảy ra lỗi. Lỗi đã xảy ra trong Luồng yêu cầu mục tiêu.
  3. Kiểm tra Flow cho thấy lỗi, bạn sẽ quan sát thấy lỗi như được thể hiện trong dấu vết ví dụ bên dưới:

    alt_text

  4. Như bạn thấy trong ảnh chụp màn hình ở trên, error.cause error.cause .
  5. Nếu bạn là người dùng Đám mây riêng tư, hãy làm theo hướng dẫn bên dưới:
    1. Bạn có thể lấy mã thông báo của yêu cầu API không thành công bằng cách xác định giá trị của Tiêu đề lỗi "X-Apigee.Message-ID" trong Giai đoạn mà AX biểu thị trong dấu vết.
    2. Tìm mã nhận dạng của thông báo này trong nhật ký Trình xử lý thông báo /opt/apigee/var/log/edge-message-processor/system.log rồi xác định xem bạn có thể tìm thêm thông tin về lỗi này hay không:
      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]
      

      Nhật ký Trình xử lý thông báo có dấu vết ngăn xếp cho lỗi Received fatal alert: bad_certificate, nhưng không có thêm thông tin nào cho biết nguyên nhân của sự cố này.

  6. Để điều tra thêm về vấn đề này, bạn cần ghi lại các gói TCP/IP bằng công cụ tcpdump.
    1. Nếu là người dùng Đám mây riêng tư, bạn có thể thu thập các gói TCP/IP trên máy chủ phụ trợ hoặc Trình xử lý thông báo. Bạn nên ghi lại chúng trên máy chủ phụ trợ vì các gói đã được giải mã trên máy chủ phụ trợ.
    2. Nếu bạn là người dùng Cloud công cộng, hãy thu thập các gói TCP/IP trên máy chủ phụ trợ.
    3. Sau khi quyết định vị trí bạn muốn thu thập các gói TCP/IP, hãy sử dụng lệnh tcpdump dưới đây để thu thập các gói TCP/IP.
    4. tcpdump -i any -s 0 host <IP address> -w <File name>

      Nếu bạn đang lấy các gói TCP/IP trên Bộ xử lý thông báo, hãy sử dụng địa chỉ IP công khai của máy chủ phụ trợ trong lệnh tcpdump.

      Nếu có nhiều địa chỉ IP cho máy chủ phụ trợ/Bộ xử lý thư, thì bạn cần dùng một lệnh tcpdump khác. Hãy tham khảo tcpdump để biết thêm thông tin về công cụ này và để biết các biến thể khác của lệnh này.

  7. Phân tích các gói TCP/IP bằng công cụ Wireshark hoặc công cụ tương tự mà bạn quen dùng.

Dưới đây là dữ liệu phân tích mẫu gói dữ liệu TCP/IP bằng công cụ Wireshark:

alt_text

  1. Thông báo số 4 trong tcpdump ở trên cho thấy Bộ xử lý thông báo (nguồn) đã gửi một thông báo "Client Hello" đến máy chủ phụ trợ (đích).
  2. Thông báo số 5 cho biết máy chủ phụ trợ xác nhận thông báo Xin chào của ứng dụng từ Trình xử lý thông báo.
  3. Máy chủ phụ trợ gửi thông báo "Server Hello" (Xin chào máy chủ) cùng với Chứng chỉ, sau đó yêu cầu Ứng dụng gửi Chứng chỉ trong Thông báo số 7.
  4. Bộ xử lý thông báo hoàn tất quy trình xác minh Chứng chỉ và xác nhận thông báo ServerHello của máy chủ phụ trợ trong Thông báo #8.
  5. Bộ xử lý thông báo gửi Chứng chỉ đến máy chủ phụ trợ trong Thông báo số 9.
  6. Máy chủ phụ trợ xác nhận đã nhận được Chứng chỉ của Trình xử lý thông báo trong Thông báo số 11.
  7. Tuy nhiên, ứng dụng sẽ ngay lập tức gửi một Cảnh báo nghiêm trọng: Chứng chỉ không hợp lệ đến Trình xử lý thông báo (Thông báo số 12). Việc này cho thấy Chứng chỉ do Trình xử lý thư gửi không hợp lệ. Do đó, quy trình Xác minh chứng chỉ không thành công trên máy chủ phụ trợ. Do đó, quá trình Giao tiếp SSL không thành công và kết nối sẽ bị đóng.


    alt_text

  8. Bây giờ, hãy xem Thông báo số 9 để kiểm tra nội dung của chứng chỉ do Bộ xử lý thông báo gửi:


    alt_text

  9. Như bạn có thể thấy, máy chủ phụ trợ không nhận được bất kỳ Chứng chỉ nào từ Ứng dụng (Độ dài chứng chỉ: 0). Do đó, máy chủ phụ trợ gửi Cảnh báo nghiêm trọng: Chứng chỉ không hợp lệ.
  10. Thông thường, trường hợp này xảy ra khi Ứng dụng, tức là Trình xử lý thư (một quy trình dựa trên Java):
    1. Không có bất kỳ Chứng chỉ ứng dụng khách nào trong Kho khoá hoặc;
    2. Không thể gửi Chứng chỉ ứng dụng khách. Điều này có thể xảy ra nếu không tìm thấy Chứng chỉ do một trong những tổ chức phát hành chứng chỉ được chấp nhận của Máy chủ phụ trợ cấp. Tức là nếu Tổ chức phát hành chứng chỉ cho Chứng chỉ Lá xanh của ứng dụng (tức là Chứng chỉ đầu tiên trong chuỗi) không khớp với bất kỳ Tổ chức phát hành chứng chỉ được chấp nhận nào của máy chủ phụ trợ, thì Trình xử lý thông báo sẽ không gửi chứng chỉ.

Hãy cùng xem xét từng nguyên nhân như sau.

Nguyên nhân: Không có chứng chỉ ứng dụng khách

Chẩn đoán

Nếu không có Chứng chỉ trong Kho khoá được chỉ định trong phần Thông tin SSL của Điểm cuối mục tiêu hoặc máy chủ đích được sử dụng trong Điểm cuối mục tiêu, thì đó chính là nguyên nhân gây ra lỗi này.

Hãy làm theo các bước dưới đây để xác định xem đây có phải là nguyên nhân không:

  1. Xác định Kho khoá đang được dùng trong Điểm cuối mục tiêu hoặc Máy chủ mục tiêu cho Proxy API cụ thể bằng cách làm theo các bước bên dưới:
    1. Lấy tên tham chiếu Kho khoá từ phần tử Kho khoá trong phần SSLInfo ở Điểm cuối mục tiêu hoặc Máy chủ mục tiêu.

      Hãy xem phần SSLInfo mẫu trong Cấu hình thiết bị đầu cuối mục tiêu:

      <SSLInfo>
        <Enabled>true</Enabled>
        <ClientAuthEnabled>true</ClientAuthEnabled>
        <KeyStore>ref://myKeystoreRef</KeyStore>
        <KeyAlias>myKey</KeyAlias>
        <TrustStore>ref://myTrustStoreRef</TrustStore>
      </SSLInfo>
    2. Trong ví dụ trên, tên tham chiếu Kho khoá là "myKeystoreRef".
    3. Chuyển đến Edge UI rồi chọn API Proxies -> Environment Configurations ( Proxy API -> Cấu hình môi trường).

      Chọn thẻ References (Tham chiếu) rồi tìm tên tham chiếu kho khoá. Hãy ghi lại tên trong cột Reference (Tham chiếu) để tham chiếu cụ thể về Kho khoá. Đây sẽ là tên Kho khoá của bạn.


      alt_text

    4. Trong ví dụ trên, bạn có thể nhận thấy rằng myKeystoreRef tham chiếu đến "myKeystore". Do đó, tên Kho khoá là myKeystore.
  2. Kiểm tra xem Kho khoá này có chứa Chứng chỉ bằng cách sử dụng giao diện người dùng Edge hoặc List Chứng chỉ cho API kho khoá hay không.
  3. Nếu Kho khoá có chứa(các) Chứng chỉ, hãy chuyển đến Nguyên nhân: Tổ chức phát hành chứng chỉ không khớp.
  4. Nếu Kho khoá không chứa Chứng chỉ nào, thì đó là lý do khiến Chứng chỉ ứng dụng khách không được Bộ xử lý thông báo gửi.

Độ phân giải

  1. Đảm bảo chuỗi Chứng chỉ ứng dụng khách hoàn chỉnh và phù hợp được tải lên Kho khoá cụ thể trong Bộ xử lý thông báo.

Nguyên nhân: Tổ chức phát hành chứng chỉ không khớp

Nói chung, khi Máy chủ yêu cầu Ứng dụng gửi Chứng chỉ, thì Máy chủ đó cho biết nhóm các Nhà phát hành hoặc Tổ chức phát hành chứng chỉ được chấp nhận. Nếu Tổ chức phát hành/Tổ chức phát hành chứng chỉ của chứng chỉ lá (tức là Chứng chỉ đầu tiên trong Chuỗi chứng chỉ) trong Kho khoá của Trình xử lý thông báo không khớp với bất kỳ Tổ chức phát hành chứng chỉ nào được máy chủ phụ trợ chấp nhận, thì Trình xử lý thông báo (là quy trình dựa trên Java) sẽ không gửi Chứng chỉ đến máy chủ phụ trợ.

Hãy làm theo các bước dưới đây để xác nhận xem bạn có gặp trường hợp này không:

  1. Liệt kê các chứng chỉ cho API kho khoá.
  2. Xem Thông tin chi tiết về từng Chứng chỉ nhận được trong Bước 1 ở trên bằng cách sử dụng Lấy chứng chỉ cho API kho khoá.
  3. Ghi lại đơn vị phát hành Chứng chỉ lá (tức là Chứng chỉ đầu tiên trong chuỗi chứng chỉ) được lưu trữ trong Kho khoá.

    Mẫu chứng chỉ Lá xanh

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

    Trong ví dụ trên, tổ chức phát hành/Tổ chức phát hành chứng chỉ là "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com"

  4. Xác định danh sách Nhà phát hành hoặc Tổ chức phát hành chứng chỉ được chấp nhận của máy chủ phụ trợ bằng một trong các kỹ thuật sau:

    Kỹ thuật số 1: Sử dụng lệnh openSSL dưới đây:

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

    Hãy tham khảo phần có tiêu đề " Báo cáo chứng chỉ ứng dụng khách được chấp nhận" trong đầu ra của lệnh này như được hiển thị bên dưới:

    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
    

    Kỹ thuật 2: Kiểm tra gói Certificate Request trong Gói TCP/IP, tại đó máy chủ phụ trợ yêu cầu Ứng dụng gửi chứng chỉ:

    Trong các gói TCP/IP mẫu nêu trên, gói Certificate Request là thông báo số 7. Tham khảo phần "Tên phân biệt", phần này chứa thông tin về Tổ chức phát hành chứng chỉ được chấp nhận của máy chủ phụ trợ.

    alt_text

  5. Xác minh xem Tổ chức phát hành chứng chỉ thu được ở bước #3 có khớp với danh sách Nhà phát hành được chấp nhận hoặc Tổ chức phát hành chứng chỉ được chấp nhận ở bước #4 hay không. Nếu thông tin không khớp thì Trình xử lý thông báo sẽ không gửi Chứng chỉ ứng dụng đến máy chủ phụ trợ.

    Trong ví dụ trên, bạn có thể nhận thấy nhà phát hành Chứng chỉ Lá xanh của ứng dụng trong Kho khoá của Trình xử lý thư không khớp với bất kỳ Tổ chức phát hành chứng chỉ được chấp nhận nào của máy chủ phụ trợ. Do đó, Trình xử lý thông báo không gửi Chứng chỉ ứng dụng đến máy chủ phụ trợ. Việc này khiến quá trình bắt tay SSL không thành công và máy chủ phụ trợ sẽ gửi thông báo "Fatal alert: bad_certificate".

Độ phân giải

  1. Đảm bảo chứng chỉ với tổ chức phát hành/Tổ chức phát hành chứng chỉ khớp với tổ chức phát hành/Tổ chức phát hành chứng chỉ cho Chứng chỉ Lá xanh của ứng dụng (chứng chỉ đầu tiên trong chuỗi) được lưu trữ trong Truststore của máy chủ phụ trợ.
  2. Ở ví dụ mô tả trong Cẩm nang này, Chứng chỉ của tổ chức phát hành "issuer" : "CN=MyCompany Test SHA2 CA G2, DC=testcore, DC=test, DC=dir, DC=mycompany, DC=com" đã được thêm vào Truststore của máy chủ phụ trợ để giải quyết vấn đề.

Nếu vấn đề vẫn tiếp diễn, hãy chuyển đến mục Phải thu thập thông tin chẩn đoán.

Phải thu thập thông tin chẩn đoán

Nếu vấn đề vẫn tiếp diễn sau khi làm theo hướng dẫn ở trên, vui lòng thu thập thông tin chẩn đoán sau đây. Hãy liên hệ và chia sẻ họ với Nhóm hỗ trợ Apigee:

  1. Nếu bạn là người dùng Public Cloud, hãy cung cấp những thông tin sau:
    1. Tên tổ chức
    2. Tên môi trường
    3. Tên proxy API
    4. Hoàn tất lệnh curl để tái hiện lỗi
    5. Tệp theo dõi cho thấy lỗi
    6. Gói TCP/IP được thu thập trên máy chủ phụ trợ
  2. Nếu bạn là người dùng Đám mây riêng tư, hãy cung cấp những thông tin sau:
    1. Đã phát hiện thấy Thông báo lỗi hoàn chỉnh
    2. Gói Proxy API
    3. Tệp theo dõi cho thấy lỗi
    4. Nhật ký Trình xử lý thư /opt/apigee/var/log/edge-message-processor/logs/system.log
    5. Gói TCP/IP được ghi trên máy chủ phụ trợ hoặc Bộ xử lý thông báo.
    6. Kết quả của Get Chứng chỉ cho API kho khoá.
  3. Thông tin chi tiết về những phần mà bạn đã thử trong Cẩm nang này và mọi thông tin chi tiết khác sẽ giúp chúng tôi nhanh chóng giải quyết vấn đề này.