O blog da AWS
Restrinja acesso via IP para seu AWS Amplify
Por Marcelo Oliveira, Arquiteto de Soluções, AWS Brasil Setor Público; Ernesto dos Santos (Tito), Arquiteto de Soluções Senior, AWS Brasil e Leticia Dornelas, Arquiteta de Soluções, AWS Brasil.
Em determinados cenários, organizações que utilizam o AWS Amplify para suas aplicações necessitam restringir o acesso dos usuários a determinados intervalos de IP, a fim de manterem controle sobre quem está autorizado a acessa-las.
O AWS Amplify é uma coleção de serviços de nuvem e bibliotecas para o desenvolvimento de aplicativos fullstack. O Amplify fornece: bibliotecas frontend, componentes de UI, construção de backend e hospedagem frontend para a construção de aplicativos fullstack na AWS.
Por meio da funcionalidade CloudFront Functions do serviço Amazon CloudFront, é possível realizar este controle de acesso de maneira eficiente.
Neste blog post você aprenderá a bloquear origens (IPs) indesejados utilizando o CloudFront Functions para restringir o acesso às suas aplicações no AWS Amplify.
Introdução
Para o cenário que detalharemos em nossas explicações, iremos considerar como ponto de partida que você já possui uma aplicação provisionada e em funcionamento através do AWS Amplify, conforme o exemplo da Figura 1:
Tome nota do identificador “App ID”, e do nome da branch de sua aplicação. Na Figura 2 há um exemplo de tela, onde as informações mencionadas podem ser localizadas.
Obs: Estas duas informações serão necessárias para a configuração do “Origin domain” da distribuição Amazon Cloudfront que você irá criar mais adiante.
Arquitetura Macro
Na Figura 3, temos um diagrama simplificado de como a integração do Amazon Cloudfront, Cloudfront Functions, e AWS Amplify acontecerá.
Configurando o “CloudFront Functions”
Iremos iniciar pela criação de uma nova função no Cloudfront Functions. Para isso, você deve selecionar a opção “Functions” no console do serviço Amazon Cloudfront, conforme indicado no exemplo da Figura 4:
Na tela da opção “Functions”, selecione o botão “Create function”, conforme indicado no exemplo da Figura 5:
Na tela de criação de uma nova “CloudFront Functions”, escolha um nome para a sua função (como por exemplo: “restrictip”). Opcionalmente, adicione uma descrição para a função. Por fim escolha o “runtime” a ser utilizado, neste caso utilize o “cloudfront-js-2.0”. Na Figura 6 temos um exemplo desta configuração.
Após criada a função, você deve adicionar o código. Para isso utilize a sessão “Function code” para adicionar o código abaixo na caixa de edição da aba “Development”. Substitua o “xx.xx.xx.xx”, e/ou o “yy.yy.yy.yy” pelo(s) IP(s) que você deseja que tenham acesso à sua aplicação.
function handler(event) {
const request = event.request;
const clientIP = event.viewer.ip;
// This will contain a list of all IPs we want to allow
const ALLOWLISTED_IP = [
'xx.xx.xx.xx',
'yy.yy.yy.yy'
];
const shouldAllowIP = ALLOWLISTED_IP.includes(clientIP);
if (shouldAllowIP) {
// Allow the original request to pass through
return request;
} else {
var response = {
statusCode: 403,
message: 'FORBIDDEN',
body: 'IP address not authorized'
}
// Send error message
return response;
}
}
Adicione o código à função recém criada, salvando a configuração selecionando o botão “Save changes”, conforme o exemplo da Figura 7.
Após gravar a função recém criada, a mesma estará pronta para ser publicada, situando-se no status de “Unpublished changes”, conforme você pode verificar no exemplo da Figura 8.
A partir deste momento, você poderá validar previamente o funcionamento da função, antes de publicá-la. Para isso você deve selecionar a aba “Test”, e com base no formulário apresentado, fornecer um IP que faça parte dos IPs pertencentes a lista de IPs previamente cadastrada no código da função. Selecione então o botão “Test function”. Nas Figuras 9a e 9b temos exemplos de uma função sendo testada.
Com a função validada, chega o momento de publicá-la. Para isso, selecione a aba “Publish”, e na sequencia selecione o botão “Publish function”, conforme podemos verificar no exemplo da Figura 10.
Configurando o “CloudFront Distribution”
Após você ter criado e publicado a “CloudFront Functions”, chega o momento de cria uma nova “CloudFront Distribution”. Para criar a distribuição de Amazon Cloudfront, acesse a console do serviço e selecione o botão “Create a CloudFront distribution”, o que pode ser verificado no exemplo da Figura 11.
Ao selecionar o botão “Create a CloudFront distribution”, você será levado a um formulário onde informará as propriedades da nova “CloudFront Distribution” a ser criada.
No início do formulário você encontrará a sessão “Origin”.
Para a propriedade “Origin domain” você precisará informar a URL de sua aplicação AWS Amplify, baseado-se nas duas informações que você tomou nota no início do blogpost: “App ID”, e “Branch name”.
O formato da URL informada deve seguir o seguinte padrão: “<<Branch name>>.<<AppID>>.amplifyapp.com”, onde você deve substituir o termo << Branch name>> pelo nome da branch anotado, e substituir o termo <<AppID>> pelo o ID da aplicação Amplify também anotado. Você pode conferir um exemplo de URL na Figura 12.
Ainda na sessão “Origin”, deixe a propriedade “Origin path” em branco.
Para a propriedade “Name”, adicione um nome para esta origem.
Deixe a propriedade “Add custom header” como está, ou seja, sem a adição de cabeçalhos adicionais.
Deixe a propriedade “Enable Origin Shield” com a seleção padrão, ou seja, “No”.
Também não há necessidade de modificar as informação em “Additional settings”.
Passe para a próxima sessão de configurações “Default cache behavior”.
Deixe as duas primeiras propriedades “Path pattern” e “Compress objects automatically” sem mudanças.
Ajuste a propriedade “Viewer protocol policy” para ao valor “Redirect HTTP to HTTPS”.
Ajuste a propriedade “Allowed HTTP methods” para o valor “GET, HEAD”.
Deixe as próximas propriedades desta sessão sem mudanças.
Você pode verificar um exemplo das mudanças indicadas na sessão “Default cache behavior” na Figura 13.
Na sessão “Function associations – optional”, altere a propriedade “Function type” da linha “Viewer request” para o valor “CloudFront Functions”, o que irá permitir a você que selecione através da propriedade “Function ARN / Name” a função recém criada (em nosso exemplo “restrictip”).
Deixe as 3 outras propriedades “Viewer response”, “Origin request”, e “Origin response” com os valores default, ou seja, “No association”.
Você pode verificar um exemplo desta ação de ajustes de propriedades na Figura 14.
Agora você passará para a sessão “Web Application Firewall (WAF)”.
Como neste blogpost não nos aprofundaremos nas configurações de proteção de perímetro, siga por não utilizar uma configuração de AWS WAF associada a “CloudFront distribution”. Para isso selecione “Do not enable security protection”.
Caso você deseje habilitar o uso do AWS WAF em sua distribuição de CloudFront, você pode utilizar-se desta referência para isso.
Você pode verificar um exemplo da sessão “Web Application Firewall (WAF)” na Figura 15.
Na sessão “Settings”, não modifique as propriedades, deixando-as com os valores default.
Para concluir a configuração da “CloudFront distribution”, selecione o botão “Create distribution”.
A partir deste ponto você já poderá testar a configuração realizada, utilizando-se da URL provisionada pela “CloudFront distribution” recém criada.
Para ter acesso à esta URL a partir da console do Amazon CloudFront, selecione a opção “Distributions” no menu à esquerda da tela. Na lista de distruições apresentada, encontre a linha com as informações da distribuição que você acabou de criar. Anote a URL presente na coluna “Domain name”, utilizando-a em um browser de sua preferência.
Você poderá verificar um exemplo de como obter a URL de sua “CloudFront distribution” na Figura 16.
Cleaning-up
Caso você tenha realizado o passo-a-passo compartilhado neste blogpost, mas decida não utilizar esta abordagem no futuro, afim de evitar a geração de custos relacionados, basta que você efetue a deleção dos recursos “CloudFront distribution” e “CloudFront function” recém criados.
Para isso, o primeiro passo será desabilitar a “CloudFront distribution” que você criou.
A partir da console do Amazon CloudFront, selecione no menu à esquerda a opção “Distributions”, localize a distribuição a ser desabilitada, selecione o “check-box” ao lado do ID referente a linha da distribuição que você deseja desabilitar, selecionando na sequencia o botão “Disable”. Você pode verificar um exemplo deste passo na Figura 17.
Após alguns segundos, a operação de “Disable” estará concluída. Com isso você poderá seguir para a ação de deleção da “CloudFront distribution”. Na console do “Amazon CloudFront”, selecione no menu à esquerda a opção “Distributions”, localize a distribuição a ser deletada, selecione o “check-box” ao lado do ID referente a linha da distribuição que você deseja deletar, selecionando na sequencia o botão “Delete”. Você pode verificar um exemplo deste passo na Figura 18.
Após o passo de deleção da “CloudFront distribution” ter sido concluído, siga para a deleção da “CloudFront Function”. Para isso, a partir da console do Amazon CloudFront, selecione no menu à esquerda a opção “Functions”, localize a função a ser deletada, selecione o “check-box” ao lado do nome referente a linha da função que você deseja deletar, selecionando na sequencia o botão “Delete”. Você pode verificar um exemplo deste passo na Figura 19.
Conclusão
Neste blogpost tivemos a oportunidade de verificar que com o uso conjunto de serviços AWS, como o AWS Amplify e o Amazon Cloudfront, valendo-se de funcionalidades como o Cloudfront Functions, podemos restringir o acesso originados de IPs indesejados à aplicações criadas no AWS Amplify, cumprindo assim com possíveis requisitos de conformidade.
A abordagem apresentada é completamente serverless, o que a torna eficiente sob o ponto de vista de custos, além de prover capacidade de escalabilidade.
Sobre os Autores
Marcelo Oliveira é Arquiteto de Soluções na AWS para clientes do setor público de saúde. Tem foco em projetos que envolvam arquiteturas distribuídas e escaláveis, além de grande interesse nas áreas de Infraestrutura, Networking e Segurança da Informação. | |
Ernesto dos Santos (Tito) é Arquiteto de Soluções na AWS para clientes ISV, e está a 6 anos na AWS. Tito possui interesse em projetos que envolvam arquiteturas distribuídas e escaláveis, Cyber Security, Infraestrutura, Networking, e Serverless. | |
Letícia Dornelas é Arquiteta de Soluções na AWS para clientes do setor Financeiro. Trabalha com desenvolvimento de sistemas há mais de 8 anos, atuando em projetos com arquiteturas distribuídas, escaláveis e resilientes. Formada pelo IFSP, tem um interesse especial em Machine Learning, Databases, Serverless, e por livros.
|