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 khách nhận được mã trạng thái HTTP 503 kèm theo thông báo "Service Available" (Dịch vụ không khả dụng) dưới dạng phản hồi cho yêu cầu API. Trong dấu vết giao diện người dùng, bạn sẽ thấy rằng lỗi error.cause Received fatal alert: bad_certificate trong Luồng yêu cầu mục tiêu cho yêu cầu API không thành công.

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

Thông báo Lỗi

Ứng dụng khách 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 Cloud riêng tư sẽ thấy lỗi sau đối với 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

Sau đây là những nguyên nhân có thể gây ra vấn đề này:

Nguyên nhân Nội dung mô tả Hướng dẫn khắc phục sự cố áp dụng cho
Không có chứng chỉ ứng dụng Kho khoá dùng trong Điểm cuối mục tiêu của Máy chủ mục tiêu không có Chứng chỉ ứng dụng khách nào. Người dùng Edge riêng tư và công khai trên đám mây công khai
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 leaf certificate (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 tư và công khai trên đám mây công khai

Các bước chẩn đoán thường gặp

  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 hiện sự cố.
  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 có thể đã xảy ra trong Luồng yêu cầu mục tiêu.
  3. Kiểm tra Luồng hiển thị lỗi, bạn sẽ quan sát lỗi như minh hoạ trong dấu vết mẫu dưới đây:

    alt_text

  4. Như bạn thấy trong ảnh chụp màn hình ở trên, lỗi error.cause "Đã nhận được cảnh báo nghiêm trọng: Bad_certificate".
  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ã nhận dạng 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 được biểu thị bằng AX trong dấu vết.
    2. Tìm kiếm mã nhận dạng thư này trong nhật ký Trình xử lý thư /opt/apigee/var/log/edge-message-processor/system.log rồi xác định nếu bạn có thể tìm thêm thông tin về lỗi:
      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ư có dấu vết ngăn xếp cho lỗi Received fatal alert: bad_certificate, nhưng không có thêm bất kỳ thông tin nào chỉ ra 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 bắt các gói TCP/IP bằng cách sử dụng tcpdump (tcpdump).
    1. Nếu là người dùng Đám mây riêng tư, bạn có thể nắm bắt Gói TCP/IP trên máy chủ phụ trợ hoặc Bộ xử lý thông báo. Bạn nên thu thập những gói dữ liệu này trên máy chủ phụ trợ khi gói được giải mã máy chủ phụ trợ.
    2. Nếu bạn là người dùng Đám mây công cộng, hãy thu thập TCP/IP các gói trên máy chủ phụ trợ.
    3. Sau khi đã quyết định được vị trí bạn muốn bắt gói TCP/IP, hãy sử dụng thấp hơn tcpdump để bắt các gói TCP/IP.
    4. tcpdump -i any -s 0 host <IP address> -w <File name>

      Nếu bạn nhận gói TCP/IP trên Trình 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ợ/Trình xử lý thư, thì bạn cần dùng một lệnh tcpdump khác. Tham khảo tcpdump để biết thêm thông tin về công cụ này và 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 thuộc.

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

alt_text

  1. Thông báo số 4 trong tcpdump ở trên cho biết rằng Trình xử lý thư (nguồn) đã gửi thông báo "Xin chào ứng dụng" đế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 Hello Hello (Xin chào ứng dụng) từ Trình xử lý tin nhắn.
  3. Máy chủ phụ trợ gửi "Server Hello" (Xin chào máy chủ) cùng với Chứng chỉ, rồi yêu cầu Ứng dụng khách gửi Chứng chỉ của nó trong Thông báo số 7.
  4. Đơn vị 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 số 8.
  5. Bộ xử lý thư gửi Chứng chỉ tới máy chủ phụ trợ trong Thông báo số 9.
  6. Máy chủ phụ trợ xác nhận việc nhận Chứng chỉ trong Thông báo số 11.
  7. Tuy nhiên, dịch vụ này 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ý tin nhắn (Tin nhắn số 12). Điều này cho biết rằng Chứng chỉ được gửi bởi Trình xử lý thư không hoạt động tốt nên quy trình Xác minh chứng chỉ không thành công máy chủ phụ trợ. Do đó, giao thức bắt tay SSL không thành công và kết nối sẽ bị đóng.


    alt_text

  8. Bây giờ hãy cùng xem Thông báo số 9 để kiểm tra nội dung của chứng chỉ do Trình 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 Chứng chỉ nào từ Ứng dụng (Độ dài chứng chỉ: 0). Do đó, máy chủ phụ trợ sẽ gửi Cảnh báo nghiêm trọng: Chứng chỉ không hợp lệ.
  10. Thông thường, điều 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ó 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 nó không tìm thấy Chứng chỉ do một trong các Tổ chức phát hành chứng chỉ được chấp nhận của Máy chủ phụ trợ cấp. Có nghĩa là, nếu Tổ chức phát hành chứng chỉ về Chứng chỉ lá 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 thì Trình xử lý thông báo sẽ không gửi chứng chỉ.

Hãy cùng xem xét riêng 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ỉ nào trong Kho khoá được chỉ định ở phần Thông tin SSL Điểm cuối mục tiêu hoặc máy chủ mục tiêu được dùng trong Điểm cuối mục tiêu, thì đó 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 hay không:

  1. Xác định Kho khoá đang 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 dưới đây:
    1. Lấy tên tham chiếu Kho khoá từ phần tử Kho khoá trong phần SSLInfo trong Đ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 một 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 Proxy -> Cấu hình môi trường.

      Chọn thẻ Tham chiếu rồi tìm tên tham chiếu Kho khoá. Ghi lại tên này trong cột Reference (Tham chiếu) cho tệp tham chiếu cụ thể của 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 có tham chiếu vào "myKeystore". Do đó, tên Kho khoá là myKeystore.
  2. Kiểm tra xem Kho khoá này có chứa Chứng chỉ hay không bằng cách sử dụng giao diện người dùng Edge hoặc Liệt kê các chứng chỉ cho API kho khoá.
  3. Nếu Kho khoá không 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 tại sao Chứng chỉ ứng dụng khách không phải do Trình xử lý thư gửi.

Độ phân giải

  1. Đảm bảo chuỗi Chứng chỉ ứng dụng phù hợp và hoàn chỉnh được tải lên Kho khoá cụ thể trong Trình 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ỉ của nó, cho biết nhóm 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 leaf certificate (tức là chứng chỉ trong chuỗi chứng chỉ) 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ỉ nào được máy chủ phụ trợ chấp nhận, thì Trình xử lý thông báo (là một 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 đây có phải là trường hợp của bạn không:

  1. Liệt kê các chứng chỉ cho API kho khoá.
  2. Lấy thông tin chi tiết về từng Chứng chỉ có đượ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 leaf Certificate (tức là Chứng chỉ đầu tiên trong chuỗi chứng chỉ) được lưu trữ trong Kho khoá.

    Chứng chỉ lá mẫu

    {
      "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 cách sử dụng một trong các kỹ thuật sau:

    Kỹ thuật 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 đề "Tên tổ chức phát hành chứng chỉ ứng dụng được chấp nhận" trong kết quả của lệnh này như sau:

    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, trong đó máy chủ phụ trợ yêu cầu Ứng dụng gửi chứng chỉ của nó:

    Trong các gói TCP/IP mẫu được trình bày ở trên, Certificate Request gói tin là thông báo số 7. Tham khảo phần "Tên phân biệt", chứa các 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 hay không Nhà phát hành chứng chỉ hoặc Tổ chức phát hành chứng chỉ được chấp nhận của máy chủ phụ trợ đã có được ở bước 4. 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 khách đến máy chủ phụ trợ.

    Trong ví dụ trên, bạn có thể nhận thấy rằng cơ quan cấp Chứng chỉ lá xanh của Khách hà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. Do đó, Trình xử lý thư không gửi Chứng chỉ ứng dụng khách đến máy chủ phụ trợ. Điều 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 "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 nhau cơ quan cấp/Tổ chức phát hành chứng chỉ của Chứng chỉ lá của ứng dụng khách (chứng chỉ đầu tiên trong chuỗi) được lưu trữ trong Truststore của máy chủ phụ trợ.
  2. Trong ví dụ được mô tả trong Cẩm nang này, Chứng chỉ với người cấp "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ày.

Nếu vấn đề vẫn tiếp diễn, hãy chuyển đến phần 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 sự cố vẫn tiếp diễn ngay cả sau khi đã làm theo các 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 Hỗ trợ Apigee Edge:

  1. Nếu bạn là người dùng Đám mây công cộng, 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 lại trên máy chủ phụ trợ hoặc Bộ xử lý thông báo.
    6. Kết quả về Nhận 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à bất kỳ để giúp chúng tôi giải quyết vấn đề này nhanh chóng hơn.