Gerenciar CRLs com Acesso Restrito: Um Desafio de Segurança Moderno
Certificados digitais formam a base de qualquer infraestrutura de segurança robusta. A AWS Private Certificate Authority é um serviço de autoridade certificadora altamente disponível que permite criar hierarquias de certificados privados, proteger aplicações e dispositivos com certificados não públicos e gerenciar seus ciclos de vida de forma centralizada.
Uma Lista de Revogação de Certificados (CRL) é um arquivo com a lista assinada de certificados que foram revogados antes de sua data de expiração prevista. Certificados podem ser revogados por diversos motivos: exposição acidental de chaves privadas, descontinuação de serviços ou mudanças de política de segurança.
Por padrão, a AWS Private CA escreve as CRLs em um bucket do Amazon S3 especificado. O desafio surge quando sua organização precisa manter essas CRLs acessíveis apenas internamente, sem exposição à internet pública. Muitos padrões de segurança corporativos exigem que todos os buckets S3 tenham ativado o bloqueio de acesso público, restringindo acessos apenas a contas AWS autorizadas.
Porém, clientes PKI tradicionais recuperam CRLs pela internet pública, criando um conflito entre conformidade de segurança e funcionalidade. A solução recomendada é usar o Amazon CloudFront, conforme destacado na documentação oficial. Mas há cenários onde CloudFront não é viável ou onde as consultas de CRL não devem atravessar a internet pública.
Apresentamos aqui duas abordagens práticas para resolver esse dilema, mantendo a segurança e conformidade da sua infraestrutura.
Opção 1: Relocar CRLs Para um Local Acessível Internamente
Esta solução consiste em mover o arquivo CRL de seu local padrão em S3 para um destino interno, acessível apenas aos clientes TLS da sua organização, mas não pela internet pública. Um servidor local ou on-premises pode servir como ponto de distribuição final.
Entendendo o Ponto de Distribuição de CRL
Um ponto de distribuição de CRL (CDP) é uma referência que indica onde os certificados revogados podem ser consultados. Normalmente, quando a AWS Certificate Manager (ACM) gera certificados privados, o CDP apontará por padrão para o bucket S3 especificado.
A primeira solução utiliza um CNAME customizado no CDP. Ao gerar o certificado, você especifica um nome de domínio interno que será o local final de distribuição da CRL, em vez de apontar diretamente para o bucket S3.
Arquitetura e Fluxo da Solução
O fluxo funciona em três etapas principais:
- A AWS Private CA escreve a CRL no bucket S3 configurado;
- Um evento de criação da CRL dispara uma função AWS Lambda;
- A função Lambda copia o arquivo CRL para o local interno especificado;
- Uma notificação via Amazon SNS confirma sucesso ou falha da operação.
Pré-requisitos para Implementação
Antes de começar, você precisará ter:
- Uma conta AWS com permissões apropriadas em AWS Identity and Access Management (IAM), S3, ACM Private CA, Amazon EventBridge e Lambda;
- Uma CA raiz e uma CA subordinada já configuradas na mesma região AWS;
- Um bucket S3 com política que permita à AWS Private CA realizar operações como PutObject, PutObjectAcl, GetBucketAcl e GetBucketLocation;
- AWS Command Line Interface (AWS CLI) configurada localmente.
Implementação Passo a Passo
Configurar a distribuição de CRL:
Acesse o console da AWS Private Certificate Authority, selecione sua CA subordinada e navegue até a aba "Revocation configuration". Clique em "Edit" no canto superior direito. Ative a opção "Activate CRL distribution" e selecione o bucket S3 que você criou.
Em seguida, expanda as configurações de CRL e no campo "Custom CRL Name" insira a URL interna onde a CRL será transferida — este deve ser um local acessível apenas internamente, não externamente. Se usar CRLs particionadas, ative também o particionamento. Salve as alterações.
Criar tópico SNS e função Lambda:
Navegue até o console do Amazon SNS e crie um novo tópico padrão, deixando as opções no padrão. Inscreva um email apropriado para receber notificações. Depois, acesse o console do Lambda e crie uma nova função em Python 3.12.
Certifique-se de que a função Lambda possui permissões IAM para: obter objetos do bucket S3 onde AWS Private CA coloca a CRL, copiar objetos entre buckets S3, e publicar mensagens no tópico SNS.
Código da Função Lambda:
import boto3
import json
def lambda_handler(event, context):
# Criar clientes S3 e SNS
s3 = boto3.client('s3')
sns = boto3.client('sns')
topicArn = ""
# Obter ID da CA a partir do evento CloudWatch
caID = event['resources'][0].split('/')[-1]
status = event['detail']['result']
if status == 'success':
source = ''
destination = ''
folder = 'crl/'
file = caID + '.crl'
key = folder + file
try:
copySource = {
'Bucket': source,
'Key': key
}
s3.copy_object(
CopySource=copySource,
Bucket=destination,
Key=file
)
response = sns.publish(
TopicArn=topicArn,
Message=f'Successfully moved {key} from {source} to {destination} in {caID}',
Subject="CRL Upload Success"
)
return {
'statusCode': 200,
'body': json.dumps(f'Successfully moved {key} from {source} to {destination} in {caID}')
}
except s3.exceptions.NoSuchKey:
response = sns.publish(
TopicArn=topicArn,
Message=f"Object {key} not found in {source}",
Subject='CRL Upload Failure'
)
return {
'statusCode': 404,
'body': json.dumps(f'Object {key} not found in {source}')
}
except Exception as e:
print(e)
response = sns.publish(
TopicArn=topicArn,
Message=f'Error moving object: {str(e)}',
Subject='Failure Uploading CRL'
)
return {
'statusCode': 500,
'body': json.dumps(f'Error moving object: {str(e)}')
}
else:
response = sns.publish(
TopicArn=topicArn,
Message=f'Certificate Authority {caID} CRL creation {status}',
Subject='CRL Upload Failure'
)
return {
'statusCode': 200,
'body': json.dumps(f'Certificate Authority {caID} CRL creation {status}')
}
Observação sobre caminhos de CRL: Por padrão, o caminho da CRL sem particionamento é . Se usou um caminho customizado, adapte conforme necessário. Com CRLs particionadas, o caminho muda para , exigindo loop sobre arquivos no diretório da CA.
Configurar EventBridge para disparo automático:
Acesse o console do Amazon EventBridge, selecione "Rules" e clique em "Create Rule". Dê um nome descritivo, selecione "Rule with an Event Pattern" e prossiga.
Na seção de eventos, escolha "AWS events", configure o padrão para usar a forma visual (Use pattern form), selecione "AWS services" como fonte e "ACM Private CA CRL Generation" como tipo de evento.
Na próxima etapa, selecione "AWS Service" como tipo de alvo e escolha a função Lambda criada anteriormente. Revise a configuração e finalize a regra.
Testando a Solução 1
Para validar que tudo está funcionando, crie e revogue um certificado de teste usando o AWS CLI. Primeiro, obtenha o número serial do certificado:
openssl x509 -in cert.pem -noout -serial
Depois, revogue o certificado:
aws acm-pca revoke-certificate --certificate-authority-arn \
--certificate-serial --revocation-reason "UNSPECIFIED"
Aguarde 5 a 30 minutos para que a CRL seja gerada. Verifique no CloudTrail se RevokeCertificate foi chamado e monitore os logs da função Lambda no CloudWatch. Você também deve receber uma notificação do tópico SNS confirmando o sucesso ou indicando qualquer erro.
Opção 2: Implementar Acesso Privado de CRL via Infraestrutura VPC
A segunda abordagem oferece acesso privado aos certificados CRL exclusivamente dentro de sua rede privada, sem necessidade de exposição à internet pública. A solução integra raiz e CAs subordinadas com CRL ativada em um bucket S3 dedicado, combinado com infraestrutura de rede privada usando VPC endpoints de gateway e sub-redes privadas.
Conceito da Solução VPC Privada
A segurança é garantida através de uma política de bucket S3 que cumpre três objetivos críticos: autorizar permissões essenciais da AWS Private CA, limitar acesso de CRL a um VPC endpoint específico de gateway, e bloquear explicitamente qualquer tentativa de acesso de outras origens.
A solução inclui configuração de zona DNS privada para resolução adequada de nomes e pode ser verificada através de testes de acesso que confirmam recuperação bem-sucedida de CRL a partir de instâncias privadas do VPC, enquanto garantem que requisições de instâncias públicas sejam rejeitadas.
Pré-requisitos para Implementação
Você precisará ter acesso a uma conta AWS com permissões apropriadas, AWS CLI e OpenSSL instalados localmente. Confirme acesso aos seguintes serviços: ACM, AWS Private CA, Amazon VPC, Amazon S3 e Amazon Route 53.
Implementação da Solução VPC
Criar CAs raiz e subordinada:
Acesse o console da AWS Private Certificate Authority e inicie a criação de uma nova CA privada. Selecione o modo "General-purpose" e tipo "Root". Preencha pelo menos um dos campos de nome distinto (Organization, Organization Unit, Country, State, Locality ou Common Name).
Escolha o algoritmo de chave (por exemplo, RSA 2048), ative "Activate CRL Distribution" e selecione ou crie um bucket S3 para armazenar as CRLs. Finalize a criação da CA raiz após confirmar as opções de preço.
Repita o processo para criar uma CA subordinada, selecionando "Subordinate CA" na etapa correspondente. Após conclusão, você verá tanto a CA raiz quanto a CA subordinada listadas no console de autoridades certificadoras privadas.
Criar VPC Endpoint de Gateway para S3:
Navegue até o console do Amazon VPC, selecione "Endpoints" no painel esquerdo e clique em "Create Endpoint". Configure as seguintes opções: atribua um nome descritivo (opcional), selecione "AWS services" como tipo, escolha com.amazonaws.[region].s3 como serviço, confirme que "Gateway" está selecionado, escolha sua VPC e selecione as tabelas de rotas associadas às sub-redes privadas que precisam acessar S3.
Para a política, você pode usar "Full Access" ou criar uma política customizada restringindo acesso a buckets ou ações específicas. Revise e crie o endpoint.
Configurar sub-redes e tabelas de rotas privadas:
No console do Amazon VPC, crie duas sub-redes privadas em diferentes Zonas de Disponibilidade dentro de sua VPC. Para cada uma, especifique nome, zona de disponibilidade e bloco CIDR.
Crie duas tabelas de rotas associadas a essas sub-redes privadas. Certifique-se de que cada tabela de rotas contém apenas rotas locais (CIDR da VPC) e remova qualquer rota para acesso à internet (0.0.0.0/0).
Implementar Política de Bucket S3 com Restrições:
Aplique uma política de bucket que garanta três controles de segurança fundamentais. Primeiro, conceda à AWS Private CA as permissões necessárias para gerenciamento de certificados. Segundo, restrinja acesso de CRL exclusivamente através do VPC endpoint de gateway especificado. Terceiro, negue explicitamente requisições GetObject que não originam do VPC endpoint designado.
A seguir está um exemplo de política S3 para acesso privado de CRL com restrições de VPC endpoint:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "acm-pca.amazonaws.com"
},
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetBucketAcl",
"s3:GetBucketLocation"
],
"Resource": [
"",
"/"
],
"Condition": {
"StringEquals": {
"aws:SourceArn": "",
"aws:SourceAccount": ""
}
}
},
{
"Sid": "Allow Access to CRL",
"Effect": "Allow",
"Principal": "",
"Action": "s3:GetObject",
"Resource": "",
"Condition": {
"StringEquals": {
"aws:SourceVpce": ""
}
}
},
{
"Sid": "Access-to-specific-VPCE-only",
"Effect": "Deny",
"Principal": "",
"Action": "s3:GetObject",
"Resource": [
"",
"/"
],
"Condition": {
"StringNotEquals": {
"aws:SourceVpce": ""
}
}
}
]
}
Configurar Zona Hospedada Privada no Route 53:
Acesse o console do Amazon Route 53, selecione "Hosted zones" no painel esquerdo e clique em "Create hosted zone". Insira s3.amazonaws.com como nome de domínio, deixe descrição opcional, selecione "Private hosted zone" como tipo, escolha sua região e VPC, e finalize a criação.
Dentro da zona recém-criada, crie um novo registro. Configure como política de roteamento "Simple", insira o nome do seu bucket S3 como "Record name", selecione "A – Routes traffic to an IPv4 address" como tipo, ative "Alias", escolha "Alias to S3 website endpoint", selecione sua região e endpoint S3 na lista, deixe TTL no padrão (300 segundos) e crie o registro.
Testando Acesso Privado e Verificando Segurança
Para validar a solução, execute um teste de acesso a partir de uma instância EC2 dentro de sua VPC privada. Use o seguinte comando para recuperar e validar a CRL:
curl -s https://.s3..amazonaws.com/crl/.crl | openssl crl -text -noout
Se bem-sucedido, o comando deve recuperar a CRL do Amazon S3, decodificá-la usando OpenSSL e exibir informações completas incluindo detalhes do emissor, timestamps de atualização, lista de certificados revogados, algoritmo de assinatura e outros metadados.
Para validar que os controles de segurança estão funcionando corretamente, tente acessar a mesma CRL a partir de uma instância EC2 pública usando o comando:
curl https://.s3..amazonaws.com/crl/.crl
Esta requisição deve falhar com um erro de acesso negado, confirmando que a CRL não pode ser acessada de fora da rede privada, mantendo sua infraestrutura PKI estritamente privada.
Conclusão
A AWS oferece duas caminhos práticos para manter suas Listas de Revogação de Certificados acessíveis exclusivamente para sua organização, sem exposição à internet pública. A primeira solução utiliza um CNAME customizado no ponto de distribuição de CRL com funções Lambda para copiar automaticamente cada nova CRL para um armazenamento privado. A segunda aproveita arquitetura VPC com VPC endpoints de gateway, políticas de bucket rigorosamente definidas e zonas DNS privadas no Route 53 para garantir que recuperação de CRL ocorra apenas dentro de sua rede privada.
Ambas as abordagens abordam os controles essenciais de IAM e políticas de bucket que seus clientes precisam para acessar CRLs de forma segura, alinhando-se com padrões corporativos de conformidade e segurança.
Fonte
How to update CRLs without public access using AWS Private CA (https://aws.amazon.com/blogs/security/how-to-update-crls-without-public-access-using-aws-private-ca/)