O blog da AWS
Automatizando a configuração de TLS Mútuo (mTLS) no Amazon API Gateway
Por Pankaj Agrawal, Arquiteto de Soluções AWS Noruega
Em setembro de 2020, o Amazon API Gateway anunciou o suporte à autenticação usando TLS Mútuo (mTLS). Este é um novo método para autenticação entre cliente-servidor que pode ser utilizado com as opções atuais de autenticação do Amazon API Gateway. TLS mútuo (mTLS) é uma extensão da Camada de Segurança de Transporte (do inglês, Transport Layer Security – TLS), que requer que ambos o servidor e o cliente verifiquem seus certificados.
TLS Mútuo é usado de forma comum para aplicações Business-to-Business (B2B). Também é utilizado em padrões como Open Banking que habilita a integração segura de APIs abertas para instituições financeiras. É também comum vê-lo sendo utilizado para aplicações de Internet das Coisas (IoT) para autenticar dispositivos através de certificados digitais.
Este artigo explica como automatizar a configuração do mTLS no Amazon API Gateway para APIs do tipo HTTP, mas os mesmos passos podem ser utilizados para APIs do tipo REST. O código fonte deste passo-a-passo pode ser obtido neste repositório GitHub.
Visão geral da solução
Para habilitar o TLS mútuo você precisa criar uma API com um nome de domínio customizado válido. TLS Mútuo está disponível tanto para APIs REST regionais como para as novas APIs do tipo HTTP. Para configurar o TLS Mútuo com o Amazon API Gateway você precisa fazer o upload da chave pública do certificado da autoridade de certificados (CA) para o Amazon S3. Isto é chamado de um truststore e é utilizado para validar os certificados de cliente.
O AWS Certificate Manager Private Certificate Authority (ACM Private CA) é um serviço de CA privado altamente disponível. Estou usando o ACM Private CA como uma autoridade de certificados para configurar as APIs HTTP e para distribuir os certificados para os clientes.
Implementando a solução
Para implementar a aplicação vamos usar o AWS Serverless Application Model (AWS SAM). O AWS SAM fornece uma sintaxe curta para definir funções, APIs, banco de dados, e mapeamento de eventos. Como um pré-requisito você deve ter o AWS SAM CLI e o Java 8 instalados. Você também precisa ter o AWS CLI configurado adequadamente.
Para implementar a solução:
- Clone o repositório GitHub e construa a aplicação com o AWS SAM CLI. Execute os seguintes comandos em um terminal:
git clone https://github.com/aws-samples/api-gateway-auth.git
cd api-gateway-auth
sam build
- Implemente a aplicação:
sam deploy --guided
Forneça o nome para o modelo da solução e a região de preferência para o processo de implementação. O modelo precisa de três parâmetros:
- HostedZoneId: o modelo usa o Zona Hospedada Pública do Amazon Route 53 para configurar um nome de domínio customizado. Forneça o ID da zona hospedada aonde a entrada deve ser criada.
- DomainName: O nome de domínio customizado para a API HTTP do Amazon API Gateway.
- TruststoreKey: o nome do arquivo da truststore que vai ser armazenado no Amazon S3, e que vai ser utilizado pelo API Gateway para o TLS Mútuo. Por padrão este arquivo é o pem.
Depois da implementação, o modelo fornece as informações de ARN de um certificado de cliente para teste (ClientOneCertArn). Este será utilizado para validar a configuração depois. O endpoint para a API HTTP do API Gateway também é fornecido como saída da criação do modelo.
Você acabou de criar um endpoint para API HTTP do API Gateway com mTLS.
Configurando o ACM Private CA
O modelo do AWS SAM inicia com a configuração do ACM Private CA. Isto permite que você crie uma hierarquia de autoridades de certificados (CA) com até cinco (5) níveis. Uma hierarquia bem definida de CA oferece benefícios como granularidade dos controles de segurança e divisão de tarefas administrativas. Para aprender mais sobre a hierarquia de CA, visite a página Desenhando Uma Hierarquia de CA. O ACM Private CA é utilizado para configurar as APIs HTTP e para distribuir os certificados para os clientes.
Primeiro, o CA raiz é criado e ativado seguido da criação de um CA subordinado, conforme as melhores práticas. O CA subordinado é utilizado para configurar o mTLS para as APIs e distribuir os certificados de clientes.
PrivateCA:
Type: AWS::ACMPCA::CertificateAuthority
Properties:
KeyAlgorithm: RSA_2048
SigningAlgorithm: SHA256WITHRSA
Subject:
CommonName: !Sub "${AWS::StackName}-rootca"
Type: ROOT
PrivateCACertificate:
Type: AWS::ACMPCA::Certificate
Properties:
CertificateAuthorityArn: !Ref PrivateCA
CertificateSigningRequest: !GetAtt PrivateCA.CertificateSigningRequest
SigningAlgorithm: SHA256WITHRSA
TemplateArn: 'arn:aws:acm-pca:::template/RootCACertificate/V1'
Validity:
Type: YEARS
Value: 10
PrivateCAActivation:
Type: AWS::ACMPCA::CertificateAuthorityActivation
Properties:
Certificate: !GetAtt
- PrivateCACertificate
- Certificate
CertificateAuthorityArn: !Ref PrivateCA
Status: ACTIVE
MtlsCA:
Type: AWS::ACMPCA::CertificateAuthority
Properties:
Type: SUBORDINATE
KeyAlgorithm: RSA_2048
SigningAlgorithm: SHA256WITHRSA
Subject:
CommonName: !Sub "${AWS::StackName}-mtlsca"
MtlsCertificate:
DependsOn: PrivateCAActivation
Type: AWS::ACMPCA::Certificate
Properties:
CertificateAuthorityArn: !Ref PrivateCA
CertificateSigningRequest: !GetAtt
- MtlsCA
- CertificateSigningRequest
SigningAlgorithm: SHA256WITHRSA
TemplateArn: 'arn:aws:acm-pca:::template/SubordinateCACertificate_PathLen3/V1'
Validity:
Type: YEARS
Value: 3
MtlsActivation:
Type: AWS::ACMPCA::CertificateAuthorityActivation
Properties:
CertificateAuthorityArn: !Ref MtlsCA
Certificate: !GetAtt
- MtlsCertificate
- Certificate
CertificateChain: !GetAtt
- PrivateCAActivation
- CompleteCertificateChain
Status: ACTIVE
Emitindo um certificado de cliente a partir do ACM Private CA
Crie um certificado de cliente, que será usado como um certificado de teste para validar a configuração do mTLS:
ClientOneCert:
DependsOn: MtlsActivation
Type: AWS::CertificateManager::Certificate
Properties:
CertificateAuthorityArn: !Ref MtlsCA
CertificateTransparencyLoggingPreference: ENABLED
DomainName: !Ref DomainName
Tags:
- Key: Name
Value: ClientOneCert
Configure um truststore no Amazon S3
O ACM Private CA está protno para configurar o mTLS nas APIs. A configuração utiliza um objeto do Amazon S3 como a sua truststore para validar certificados de clientes. Para automatizar esta parte, um recurso customizado utilizando a AWS Lambda copia a cadeia de certificados públicos do ACM Private CA para o armazenamento no Amazon S3:
TrustStoreBucket:
Type: AWS::S3::Bucket
Properties:
VersioningConfiguration:
Status: Enabled
TrustedStoreCustomResourceFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: TrustedStoreCustomResourceFunction
Handler: com.auth.TrustedStoreCustomResourceHandler::handleRequest
Timeout: 120
Policies:
- S3CrudPolicy:
BucketName: !Ref TrustStoreBucket
O recurso customizado de exemplo está escrito em Java mas poderia ser escrito em qualquer outra linguagem de programação suportada pelo AWS Lambda. O recurso customizado é invocado com os detalhes do certificado público da raiz do CA privado, do CA subordinado, e o local de armazenamento no Amazon S3. A função Lambda então concatena a cadeia de certificados e armazena o objeto no Amazon S3.
TrustedStoreCustomResource:
Type: Custom::TrustedStore
Properties:
ServiceToken: !GetAtt TrustedStoreCustomResourceFunction.Arn
TrustStoreBucket: !Ref TrustStoreBucket
TrustStoreKey: !Ref TruststoreKey
Certs:
- !GetAtt MtlsCertificate.Certificate
- !GetAtt PrivateCACertificate.Certificate
Você pode visualizar e baixar o código de execução para o recurso customizado que utiliza o AWS Lambda no repositório deste projeto.
Configurando as APIs HTTP do Amazon API Gateway com o mTLS
Com um objeto de truststore devidamente armazenado no Amazon S3, você pode configurar as API. Um nome de domínio customizado deve estar configurado para que o Amazon API Gateway possa habilitar o mTLS. O código a seguir cria e configura um domínio customizado para a API HTTP. Veja o arquivo template.yaml para o exemplo completo.
CustomDomainCert:
Type: AWS::CertificateManager::Certificate
Properties:
CertificateTransparencyLoggingPreference: ENABLED
DomainName: !Ref DomainName
DomainValidationOptions:
- DomainName: !Ref DomainName
HostedZoneId: !Ref HostedZoneId
ValidationMethod: DNS
SampleHttpApi:
Type: AWS::Serverless::HttpApi
DependsOn: TrustedStoreCustomResource
Properties:
CorsConfiguration:
AllowMethods:
- GET
AllowOrigins:
- http://localhost:8080
Domain:
CertificateArn: !Ref CustomDomainCert
DomainName: !Ref DomainName
EndpointConfiguration: REGIONAL
SecurityPolicy: TLS_1_2
MutualTlsAuthentication:
TruststoreUri: !GetAtt TrustedStoreCustomResource.TrustStoreUri
TruststoreVersion: !GetAtt TrustedStoreCustomResource.ObjectVersion
Route53:
EvaluateTargetHealth: False
HostedZoneId: !Ref HostedZoneId
DisableExecuteApiEndpoint: true
Uma zona pública hospedada do Amazon Route 53 é utilizada para configurar o domínio customizado. É necessário que isto esteja configurado previamente em sua conta AWS e você precisa fornecer o ID da zona hospedada como um parâmetro para o modelo.
Como o endpoint padrão do API Gateway não força o uso de TLS mútuo, este deve ser desabilitado através da chamada de API DisableExecuteApiEndpoint. Desta forma garantimos que a autenticação com mTLS é obrigatória para todo o tráfego da API.
A API de exemplo invoca uma função Lambda e retorna o payload de resposta.
Testando e validando a configuração
Para validar a configuração, primeiro exportamos o certificado de cliente criado anteriormente. Você pode exportar o certificado utilizando a console de gerência AWS ou a AWS CLI. Neste exemplo, usaremos a AWS CLI para exportar o certificado. Para aprender como exportar via a console de gerência, veja a documentação exportando um certificado privado usando a console.
- Exporte o certificado codificado-PEM de base64 para um arquivo local, pem.
aws acm export-certificate --certificate-arn <<Certificat ARN from stack output>> --passphrase $(echo -n 'your paraphrase' | base64) --region us-east-2 | jq -r '"\(.Certificate)"' > client.pem
- Exporte a chave privada criptografada associada com a chave pública do certificado e salve-a em um arquivo local encrypted.key. Você deve fornecer uma frase-chave para associar com a chave privada criptografada. Esta será utilizada para descriptografar a chave privada exportada.
aws acm export-certificate --certificate-arn <<Certificat ARN from stack output>> --passphrase $(echo -n 'your paraphrase' | base64) --region us-east-2| jq -r '"\(.PrivateKey)"' > client.encrypted.key
- Descriptografe a chave privada exportada usando a frase-chave e a biblioteca OpenSSL.
openssl rsa -in client.encrypted.key -out client.decrypted.key
- Acesse a API usando o TLS Mútuo.
curl -v --cert client.pem --key client.decrypted.key https://demo-api.example.com
Adicionando uma lista de revogação de certificados
O AWS Certificate Manager Private Certificate Authority (ACM Private CA) pode ser configurado nativamente com uma lista de revogação de certificados (CRL).
CRL é uma forma da autoridade de certificados (CA) entender que um ou mais de seus certificados digitais não é mais confiável. Quando clientes revogam certificados, estes são invalidados antes de sua data de expiração. A autoridade de certificados pode revogar um certificado emitido por inúmeras razões, sendo a mais comum quando a chave privada de um certificado é comprometida.
A configuração de mTLS de API HTTP do Amazon API Gateway pode ser utilizada com todas as opções de autenticação do API Gateway. Você pode, inclusive, extender a validação para autorizadores customizados AWS Lambda que podem ser configurados para validar os certificados de cliente através de uma lista de revogação de certificados (CRL). Por exemplo:
Para arquiteturas de exemplo usando a autenticação via Lambda, veja o aws-apigateway-lambda-authorizer-blueprints.
Conclusão
TLS Mútuo (mTLS) para o API Gateway está disponível sem custo adicional. Este artigo demonstra como automatizar a configuração de mTLS no Amazon API Gateway para API HTTP usando o AWS Certificate Manager Private Certificate Authority como um CA privado. Usando Infraestrutura como Código (IaC) possibilitamos que você desenvolva, implemente, e escale aplicações em nuvem com grande velocidade, menos riscos, e custo reduzido.
Para baixar o exemplo funcional completo para implementar o mTLS com o API Gateway use este repositório GitHub. Para aprender mais sobre o Amazon API Gateway, visite a documentação API Gateway Developer Guide.
Para saber mais sobre os recursos serverless, visite o site Serverless Land.
Este artigo foi traduzido do Blog da AWS em Inglês.
Sobre o autor
Pankaj Agrawal é Arquiteto de Soluções na AWS Noruega.
Revisor
Paulo Aragão é um Arquiteto de Soluções Sênior que trabalha há mais de 20 anos com clientes Enterprise. Ampla experiência em Computação de Alta Performance (HPC), atualmente dedica seus dias a ajudar clientes a inovarem através do uso de serviços de IA e ML na nuvem AWS. Apaixonado por música e mergulho, você pode encontra-lo em vídeos de covers musicais no Youtube ou no fundo do mar. No seu tempo livre, gosta de ler livros, jogar World of Warcraft, e cozinhar para os amigos.