Conexão segura com banco de dados na AWS utilizando RDS, SSM e EC2

Conexão segura com banco de dados na AWS utilizando RDS, SSM e EC2

Photo by Growtika on Unsplash

Quando estamos em um ambiente de cloud, existem diferentes formas de realizar a conexão com um banco de dados.

Fazer isso com segurança é essencial, por isso, muitas vezes optamos por utilizar uma máquina EC2 como bastion host em uma subnet pública. Dessa forma, é possível autenticar o usuário através de um par de chaves, permitindo a conexão via SSH.

Para alguns casos, essa é uma prática viável, porém lidar com a segurança e gerenciamento dessas chaves não é algo tão simples. Se, por exemplo, um desenvolvedor deixar o projeto por algum motivo, uma medida de segurança comum seria a troca das chaves de todas as máquinas às quais ele tinha acesso e a redistribuição de novas chaves para o restante da equipe, correto?

E se, além disso, limitássemos o acesso na porta 22 do bastion host para os IPs do time de forma individual, prevenindo inclusive ataques DDoS no bastion host?

Ainda assim, não poderíamos deixar de atualizar os IPs de diversos desenvolvedores sempre que o IP da máquina deles mudasse ou de conceder permissões de acesso em Security Groups para que eles mesmos façam as atualizações, abrindo brechas de segurança difíceis de serem monitoradas.

Sempre que um desenvolvedor é desligado ou muda para outro projeto, precisamos remover o seu IP em múltiplas contas da AWS, projetos e ambientes (desenvolvimento, homologação, produção, entre outros), aumentando a complexidade de gerenciamento.

Felizmente, temos uma solução efetiva na AWS que permite manter todo o gerenciamento de acessos pelo IAM e conectar em uma subnet privada através do SSM (Systems Manager Session Manager) e VPC Endpoints.

Confira abaixo o passo a passo detalhado de como fazer uma conexão no RDS com o SSM e realizar a configuração de cada recurso.

Imagem da arquitetura implementada:

Pré-requisitos

Para começar, é necessário configurar as seguintes ferramentas e serviços:

  • Subnet(s) privada(s)

  • Banco de dados no RDS

  • DBeaver ou similar para conexão com banco de dados local

Para verificar a instalação e as suas credenciais, utilize os comandos aws --version, session-manager-plugin e aws sts get-caller-identity.

Nesse tutorial, estou usando ambiente Linux via WSL.

Security Groups

Com tudo configurado, podemos criar Security Groups para os VPC Endpoints, Bastion Host e RDS. (Vou me referir a eles com o mesmo nome utilizado no momento da criação, SG_SSM_ENDPOINTS, SG_SSM_BH e SG_RDS, respectivamente).

Como o banco de dados foi criado anteriormente, você pode usar o mesmo Security Group do momento da criação ou um novo, como preferir.

SG_SSM_ENDPOINTS

Ao criar um novo Security Group, preencha o seu nome, descrição e VPC.

Inbound Rules: Entrada HTTPS para o CIDR da sua VPC.

Outbound Rules: Saída de dados para o CIDR da sua VPC.

SG_SSM_BH

Inbound Rules: Entrada do banco de dados para o SG_RDS.

Outbound Rules: Saída PostgreSQL e HTTPS para a internet.

SG_RDS

Inbound Rules: Entrada PostgreSQL para o SG_SSM_BH.

Outbound Rules: Saída para a rede.

Role IAM

O próximo passo será a criação de uma role no IAM do tipo serviços AWS.

Em EC2, selecione EC2 Role for AWS Systems Manager como na print abaixo:

A política gerenciada AmazonSSMManagedInstanceCore estará selecionada automaticamente, apenas prossiga.

Preencha o nome da role e finalize a criação.

Criação de VPC Endpoints

Estou utilizando os 5 VPC Endpoints listados abaixo, mas somente os 3 primeiros são obrigatórios. Essa variação acontece conforme a sua necessidade e você poderá encontrar os detalhes de cada endpoint na documentação da AWS.

Começaremos com o endpoint com.amazonaws.region.ssm.

Passo 1: Preencha o nome, selecione AWS Services e busque por ssm. Em seguida, selecione o com.amazonaws.region.ssm.

Passo 2: Escolha a VPC, habilite o DNS e selecione suas subnets privadas.

Passo 3: Escolha o security group SG_SSM_ENDPOINTS.

Para esse tutorial, estou utilizando a política com acesso completo.

Agora é só clicar em “Criar endpoint”. Lembrando que você deverá repetir essas etapas para cada um dos endpoints mencionados acima.

Se estiver tudo certo, todos os endpoints configurados estarão listados e disponíveis.

Criação do Bastion Host no EC2

Escolha um nome, sistema operacional e tipo de instância e siga sem associar pares de chaves.

Em configurações de rede:

  • Selecione sua VPC, uma subnet privada que também esteja associada ao seu banco de dados e o security group do Bastion Host (SG_BH_SSM).

  • A opção de Auto IP Público deve ficar desabilitada.

Em opções avançadas, selecione a role que criamos (EC2_SSM_CONNECT) no campo perfil IAM da instância.

Clique em criar instância para finalizar e aguarde a máquina ser ativada.

Ainda nessa página, copie e guarde o ID completo da instância, que tem esse formato: I-0xyz123.

Agente SSM

Verifique se o agente do SSM já está ativo na máquina. Dependendo do sistema operacional, ele já vem instalado, caso contrário, você deverá instalá-lo manualmente.

Se o agente já estiver instalado, seu ec2 estará listado no “Fleet Manager” e pronto para ser acessado.

Se ainda não apareceu, verifique se o agente está ativo na máquina. Você também poderá um guia para fazer a instalação manualmente em diferentes sistemas operacionais na documentação.

Sessão SSM e conexão com o banco de dados

Para preparar o comando e iniciar a sessão no SSM, edite o comando abaixo preenchendo o ID do EC2 e o host do banco de dados.

No portNumber, preencha com a porta do banco de dados configurada no RDS.

No localPortNumber, preencha com a porta que utilizará para conectar no banco local.

As barras (\) no comando são apenas para melhorar a visibilidade. Dependendo do seu sistema, elas podem não funcionar. Nesse caso, retire as barras deixando apenas espaços entre os parâmetros.

aws ssm start-session \
--target i-ID-ec2-bastion-host \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"host":["database.id.region.rds.amazonaws.com"],"portNumber":["5432"], "localPortNumber":["5001"]}'

Se tudo estiver correto, você verá a mensagem abaixo no terminal, confirmando que a sua sessão foi iniciada no SSM com o número da porta local de conexão.

Mantenha o terminal aberto para conectar no banco.

No DBeaver ou similar, preencha o usuário e senha apontando o localhost para a porta escolhida.

Pronto, agora você está conectado com segurança!

Se você está utilizando um acesso com altos privilégios na AWS, você não terá problemas com permissões, mas caso sua equipe utilize acessos mais restritos, é importante adicionar o SSM na política de acesso deles.

Conclusão

Agora você já está conectado no banco de dados de forma segura e gerencia de forma prática os acessos no RDS, mas é importante destacar que embora a abordagem discutida ofereça um alto nível de segurança, existem outras práticas e isso pode variar conforme a política interna de cada empresa. Vou citar algumas que podem ser exploradas:

  • Evitar armazenamento de credenciais direto no código com o uso do AWS Secrets Manager ou AWS Parameter Store.

  • Utilização do RDS IAM Authentication para eliminar a gestão de credenciais.

  • Auditorias e monitoramento de ameaças com AWS CloudTrail e Amazon CloudWatch.

  • Estabelecer outras camadas de segurança através de conexão VPN, AWS Direct Connect ou AWS PrivateLink.

O Session Manager ainda oferece logs de sessões que podem ser salvos no CloudWatch ou S3, possibilita a especificação de variáveis e inclusão de comandos shell ao iniciar sessões, integração com KMS, gerenciamento do tempo de sessão e muito mais.