Como soluciono problemas de erros HTTP 403 Forbidden de um nome de domínio personalizado do API Gateway que requer TLS mútuo?

Data da última atualização: 8/12/2021

Meu nome de domínio personalizado do Amazon API Gateway que utiliza autenticação Transport Layer Security (TLS) mútua ativada retorna erros HTTP 403 Forbidden. Por que isso está acontecendo, e como posso solucionar o problema?

Descrição breve

Observação: o API Gateway pode retornar erros 403 Forbidden por vários motivos. Este artigo aborda somente erros 403 Forbidden relacionados ao TLS mútuo. Para obter informações sobre como solucionar problemas de outros tipos de erros 403 Forbidden, consulte Como solucionar problemas de erros HTTP 403 Forbidden do API Gateway?

Para invocar uma API do API Gateway usando um nome de domínio personalizado que requer TLS mútuo, os clientes devem apresentar um certificado confiável na solicitação da API. Quando um cliente tenta invocar a API, o API Gateway procura o emissor do certificado do cliente em sua truststore.

Se alguma das seguintes condições ocorrer, o API Gateway falhará na conexão TLS e retornará um código de status 403:

  • O API Gateway não consegue encontrar o emissor do certificado do cliente em sua truststore.
  • O certificado do cliente está usando um algoritmo de assinatura inseguro.
  • O certificado do cliente é autoassinado.

Se o log do Amazon CloudWatch estiver ativado para sua API, uma mensagem de erro indicando a causa do erro será exibida nos logs de execução.

Importante: se a solicitação da API não produzir CloudWatch Logs depois que o log for ativado, o erro 403 Forbidden não estará relacionado ao TLS mútuo.

Para APIs REST

Se você configurar o log do Amazon CloudWatch para a API REST, uma das seguintes mensagens de erro também será exibida nos logs de execução:

  • Acesso negado. Motivo: não foi possível encontrar o emissor para o certificado
  • Acesso negado. Motivo: o certificado do cliente usa um algoritmo de assinatura inseguro
  • Acesso negado. Motivo: certificado autoassinado

Para APIs HTTP

As APIs HTTP não oferecem suporte a logs de execução. Para solucionar problemas de erros 403 Forbidden retornados por um nome de domínio personalizado que requer TLS mútuo e invoca uma API HTTP, é necessário fazer o seguinte:

1.    Crie um novo mapeamento de API para seu nome de domínio personalizado que invoca uma API REST apenas para fins de teste.
Observação: se você não tiver uma API REST disponível para teste, use a API REST PetStore de exemplo. Em seguida, implante a API de exemplo em um novo estágio e crie um novo mapeamento de API para ela que use seu nome de domínio personalizado.

2.    Siga as instruções na seção Resolução deste artigo usando o novo mapeamento de API que você criou para a API REST.

3.    Depois que o erro for identificado e resolvido, redirecione o mapeamento da API do seu nome de domínio personalizado de volta para a API HTTP.

Resolução

Confirme a causa do erro

1.    Se ainda não o fez, ative o log do CloudWatch para sua API REST. Certifique-se de configurar o log de execução e acesso.

Observação: ao configurar o log de acesso para esse caso de uso, é uma prática recomendada usar as seguintes variáveis $context. Essas variáveis têm duas funções:

  • Informar ao API Gateway para gerar CloudWatch Logs quando o nome de domínio personalizado que requer TLS mútuo retorna um erro 403 Forbidden.
  • Facilitar a identificação do chamador que tentou invocar sua API quando você revisar o CloudWatch Logs.

Variáveis $context recomendadas para o log de acesso do CloudWatch que permitirão ao API Gateway gerar logs de execução e acesso

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

2.    Identifique o que está causando os erros 403 Forbidden visualizando os logs de execução da API REST no CloudWatch. Se um erro 403 Forbidden relacionado ao TLS mútuo for registrado, uma mensagem de erro semelhante ao exemplo a seguir será exibida.

Exemplo de mensagem de erro do CloudWatch Logs quando um nome de domínio personalizado que requer TLS mútuo retorna um erro 403 Forbidden

Extended Request Id: {extendedRequestId} 
Access denied. Reason: {reason} 
ForbiddenException Forbidden: {requestId}

Para resolver erros "Acesso negado. Motivo: não foi possível encontrar o emissor do certificado"

Verifique se o emissor do certificado do cliente na solicitação da API está incluído na truststore do nome de domínio personalizado

O emissor do certificado do cliente (client.pem) na solicitação da API deve ser incluído na truststore do seu nome de domínio personalizado. O emissor também deve ser incluído como parte do pacote de certificados (bundle.pem) no Amazon Simple Storage Service (Amazon S3).

Para verificar se o emissor do certificado do cliente está incluído no truststore necessário, execute o seguinte comando OpenSSL:

$ openssl verify -CAfile bundle.pem client.pem

- ou -

Se o pacote de certificados contiver autoridades de certificação intermediárias, execute o seguinte comando OpenSSL:

$ openssl verify -CAfile rootCA.pem -untrusted intCA.pem client.pem

O comando retornará uma resposta OK se o emissor do certificado do cliente na solicitação da API estiver incluído no truststore necessário.

O comando retornará o seguinte erro se o emissor do certificado do cliente não estiver incluído no truststore necessário: "erro X na pesquisa naprofundidade Y: não é possível obter o certificado do emissor local"

Verifique se todos os certificados de cliente no truststore do seu nome de domínio personalizado são válidos

Se um dos certificados de cliente no truststore do seu nome de domínio personalizado não for válido, alguns clientes talvez não consigam acessar sua API.

Para verificar se todos os certificados de cliente em seu truststore são válidos, faça o seguinte:

1.    Abra o console do API Gateway.

2.    No painel de navegação esquerdo, escolha Nomes de domínio personalizados. Em seguida, escolha seu nome de domínio personalizado que requer TLS mútuo.

3.    Na seção Detalhes, verifique se a seguinte mensagem de erro é exibida: Há um certificado inválido no seu pacote de truststore.

4.    Se a mensagem de erro estiver presente, você deverá decodificar os certificados em seu armazenamento confiável para identificar qual certificado produziu o aviso.
Observação: o seguinte comando OpenSSL exibe o conteúdo de um certificado, incluindo o assunto:

$ openssl x509 -in certificate.crt -text -noout

5.    Atualize ou remova os certificados que produziram o aviso. Em seguida, carregue um novo truststore para o Amazon S3.

Para obter mais informações, consulte Solução de problemas de avisos de certificados.

Observação: o API Gateway aceitará certificados de cliente assinados diretamente pela autoridade de certificação raiz ou qualquer outro intermediário se a cadeia de certificados for preservada. Para validar certificados de cliente assinados apenas pela última autoridade de certificação intermediária, use um autorizador do AWS Lambda baseado em parâmetros de solicitação. Você pode usar seu algoritmo de validação personalizado no nível da função do Lambda aceitando o certificado do cliente como entrada da solicitação da API.

Para resolver erros "Acesso negado. Motivo: o certificado do cliente usa um algoritmo de assinatura inseguro

Verifique se o arquivo de texto do truststore usa um algoritmo de hash compatível

O API Gateway é compatível com os seguintes algoritmos de hash no truststorel:

  • SHA-256 ou mais forte
  • RSA-2048 ou mais forte
  • ECDSA-256 ou mais forte

Para verificar se o arquivo de texto do truststore usa um algoritmo de hash compatível ou não, execute o seguinte comando OpenSSL:

$ openssl x509 -in client.crt -text -noout | grep 'Signature Algorithm'

A resposta do comando retorna o algoritmo de assinatura do seu truststore.

Para obter mais informações, consulte Configuração do truststore.

Para resolver erros "Acesso negado. Motivo: certificado autoassinado"

Verifique se o certificado de cliente autoassinado na solicitação da API não foi alterado nem está corrompido

Os seguintes itens devem corresponder exatamente:

  • O módulo da chave privada (private.key) usado para assinar o certificado autoassinado no armazenamento confiável no S3 (bundle.crt ou bundle.pem).
  • O módulo do certificado do cliente passado na solicitação da API (client.crt).

Para comparar os dois módulos, execute os seguintes comandos OpenSSL:

$ openssl rsa -noout -modulus -in private.key
$ openssl x509 -noout -modulus -in bundle.crt
$ openssl x509 -noout -modulus -in client.crt

Observação: para produzir um valor de hash mais curto a fim de facilitar a comparação, você pode fazer o PIPE do módulo de saída em uma função de hash criptográfica. Por exemplo: openssl sha1.

$ openssl [operation] -noout -modulus -in [data] | openssl sha1

Exemplo de saídas de comando válidas

2143831a73a8bb28467860df18550c696c03fbcb
2143831a73a8bb28467860df18550c696c03fbcb
2143831a73a8bb28467860df18550c696c03fbcb

Para confirmar a integridade dos dados, verifique se não houve nenhuma modificação de dados no nível do conteúdo executando o seguinte comando diff:

$ diff client.crt bundle.crt

Para obter mais informações, consulte Configuração do truststore.


Este artigo ajudou?


Precisa de ajuda com faturamento ou suporte técnico?