如何對需要相互 TLS 的 API Gateway 自訂網域名稱中的 HTTP 403 禁止錯誤進行疑難排解?
啟用相互 Transport Layer Security (TLS) 驗證的 Amazon API Gateway 自訂網域名稱會傳回 HTTP 403 禁止錯誤。我不知道為什麼會發生這種情況。
簡短描述
**注意:**由於各種原因,API Gateway 會傳回 403 禁止錯誤。本文討論僅與相互 TLS 相關的 403 禁止錯誤。如需有關對其他 403 禁止錯誤類型進行疑難排解的資訊,請參閱如何對 API Gateway 的 HTTP 403 錯誤進行疑難排解?
若要使用需要相互 TLS 的自訂網域名稱調用 API Gateway API,用戶端必須在 API 請求中顯示受信任的憑證。當用戶端調用 API 時,API Gateway 會在您的信任存放區中尋找用戶端憑證的發行者。
下列情況造成 API Gateway 無法連線至 TLS,並傳回 403 狀態代碼:
- API Gateway 無法在信任存放區中找到用戶端憑證的發行者。
- 用戶端憑證使用了不安全的簽署演算法。
- 用戶端憑證為自簽。
當您的 API 啟用 Amazon CloudWatch 日誌記錄後,則指出錯誤原因的錯誤訊息會顯示在執行日誌中。
**重要事項:**如果 API 請求在啟動日誌記錄後沒有產生任何 CloudWatch 日誌,則 403 禁止錯誤與相互 TLS 無關。
若為 REST API
如果您設定 REST API 的 Amazon CloudWatch 日誌記錄,則下列其中一則錯誤訊息也會出現在執行日誌中:
- 存取遭拒。原因: 找不到憑證發行者
- 存取遭拒。原因: 使用不安全的簽署演算法的用戶端憑證
- 存取遭拒。原因:自簽憑證
若為 HTTP API 操作
HTTP API 不支援執行日誌記錄。若要對由需要相互 TLS 並調用 HTTP API 的自訂網域名稱傳回的 403 禁用錯誤進行疑難排解,您必須執行下列動作:
- 為您的自訂網域名稱建立新的 API 映射,以調用僅供測試用途的 REST API。
**注意:**如果您沒有要測試的 REST API,則請使用 PetStore REST API 範例。然後,將範例 API 部署到新階段,並建立使用自訂網域名稱的新 API 映射。 - 遵循本文解決方法區段中的指示,使用您建立到 REST API 的新 API 映射。
- 將自訂網域名稱的 API 映射重新路由回您的 HTTP API。
解決方法
請確認錯誤原因
- 為 REST API 開啟 CloudWatch 日誌記錄。
- 設定執行和存取日誌記錄。
注意: 當您為此使用案例設定存取日誌記錄時,最佳實務是使用下列 $context 變數:
當需要相互 TLS 的自訂網域名稱傳回 403 錯誤時,這些變數會告知 API Gateway 產生 CloudWatch 日誌。它們還可以更輕鬆地識別嘗試調用您的 API 操作的呼叫者。{ "accountId":"$context.accountId", "apiId":"$context.apiId", "domainName":"$context.domainName", "domainPrefix":"$context.domainPrefix", "error.message":"$context.error.message", "error.responseType":"$context.error.responseType", "extendedRequestId":"$context.extendedRequestId", "httpMethod":"$context.httpMethod", "identity.sourceIp":"$context.identity.sourceIp", "identity.clientCert.clientCertPem":"$context.identity.clientCert.clientCertPem", "identity.clientCert.subjectDN":"$context.identity.clientCert.subjectDN", "identity.clientCert.issuerDN":"$context.identity.clientCert.issuerDN", "identity.clientCert.serialNumber":"$context.identity.clientCert.serialNumber", "identity.clientCert.validity.notBefore":"$context.identity.clientCert.validity.notBefore", "identity.clientCert.validity.notAfter":"$context.identity.clientCert.validity.notAfter", "identity.userAgent":"$context.identity.userAgent", "path":"$context.path", "protocol":"$context.protocol", "requestId":"$context.requestId", "requestTime":"$context.requestTime", "requestTimeEpoch":"$context.requestTimeEpoch", "resourceId":"$context.resourceId", "resourcePath":"$context.resourcePath", "stage":"$context.stage", "responseLatency":"$context.responseLatency", "responseLength":"$context.responseLength", "status":"$context.status" }
- 在 CloudWatch 中檢視 REST API 的執行日誌,以識別錯誤原因。如果記錄了與相互 TLS 相關的 403 禁止錯誤,則您會收到類似於下列內容的錯誤訊息:
Extended Request Id: {extendedRequestId} Access denied. Reason: {reason} ForbiddenException Forbidden: {requestId}
解決「存取遭拒。原因: 找不到憑證的發行者」錯誤
驗證 API 請求中用戶端憑證的發行者是否包含在自訂網域名稱的信任存放區中
API 請求中用戶端憑證的發行者 (client.pem) 必須包含在自訂網域名稱的信任存放區中。發行者也必須包含在 Amazon Simple Storage Service (Amazon S3) 中憑證組合 (bundle.pem) 的一部分。
若要驗證用戶端憑證的發行者是否包含在所需的信任存放區中,請執行下列 OpenSSL 命令:
$ openssl verify -CAfile bundle.pem client.pem
-或-
如果憑證組合包含中介憑證認證機構,則請執行下列 OpenSSL 命令:
$ openssl verify -CAfile rootCA.pem -untrusted intCA.pem client.pem
如果 API 請求中用戶端憑證的發行者包含在所需的信任存放區中,則該命令會傳回 OK 回應。
如果用戶端憑證的發行者未包含在所需的信任存放區中,則命令會傳回下列錯誤:「Y 深度查找時的錯誤 X:無法取得本機發行者憑證」
驗證自訂網域名稱的信任存放區中的所有用戶端憑證是否皆為有效
如果您自訂網域名稱的信任存放區中的其中一個用戶端憑證無效,則某些用戶端可能無法存取您的 API。若要確認信任存放區中的用戶端憑證是否有效,請執行下列動作:
-
開啟 API Gateway 主控台。
-
在左側導覽窗格中,選擇自訂網域名稱。然後,選擇需要相互 TLS 的自訂網域名稱。
-
在詳細資訊區段中,檢查下列錯誤訊息: 您的信任存放區組合中有一項無效的憑證。
-
如果看到錯誤訊息,則請解碼信任存放區中的憑證,以識別哪項憑證產生警告。
**注意:**下列 OpenSSL 命令會顯示憑證的主題和內容:$ openssl x509 -in certificate.crt -text -noout
-
更新或移除產生警告的憑證。然後,將新的信任存放區上傳到 Amazon S3。
如需詳細資訊,請參閱對憑證警告進行疑難排解。
**注意:**如果保留其憑證鏈,則 API Gateway 會接受由主要憑證認證機構或任何其他中介憑證認證機構直接簽署的用戶端憑證。若要驗證僅由最後一個中介憑證認證機構簽署的用戶端憑證,請使用請求參數型 AWS Lambda Authorizer。您可以在 Lambda 函數層級使用自訂驗證演算法。若要執行此動作,請接受用戶端憑證作為 API 請求的輸入。
解決「存取遭拒。原因: 使用不安全簽署演算法的用戶端憑證」錯誤
驗證您的信任存放區文字檔是否使用支援的雜湊演算法。 API Gateway 會在信任存放區中支援下列雜湊演算法:
- SHA-256 或更高版本
- RSA-2048 或更高版本
- ECDSA-256 或更高版本
若要確認信任存放區文字檔使用支援的雜湊演算法,請執行下列 OpenSSL 命令:
$ openssl x509 -in client.crt -text -noout | grep 'Signature Algorithm'
命令回應會傳回信任存放區的簽署演算法。
如需詳細資訊,請參閱設定您的信任存放區。
解決「存取遭拒。原因:自簽憑證」錯誤
驗證 API 請求中的自我簽署用戶端憑證是否沒有變更或損壞。 用戶端憑證簽署請求 (my\ _client.csr)、用戶端憑證私密金鑰 (my\ _client.key) 和用戶端憑證公開金鑰 (my\ _client.pem) 必須相符。
若要比較模量,請執行這些 OpenSSL 命令:
$ openssl rsa -noout -modulus -in my_client.csr $ openssl x509 -noout -modulus -in my_client.key $ openssl x509 -noout -modulus -in my_client.pem
**注意:**若要產生較短的雜湊值以便於比較,請使用輸出模量上的管道。請參閱下列 openssl sha1 範例:
$ openssl [operation] -noout -modulus -in [data] | openssl sha1
有效的輸出範例看起來類似於下列內容:
2143831a73a8bb28467860df18550c696c03fbcb2143831a73a8bb28467860df18550c696c03fbcb 2143831a73a8bb28467860df18550c696c03fbcb
若要確認資料完整性,請驗證內容層級是否沒有任何資料修改。執行下列 diff 命令:
$ diff client.crt bundle.crt
如需詳細資訊,請參閱設定您的信任存放區。
相關內容
- 已提問 1 年前lg...
- 已提問 9 個月前lg...
- 已提問 14 天前lg...
- AWS 官方已更新 2 年前
- AWS 官方已更新 2 年前
- AWS 官方已更新 2 年前