# Acesso seguro ao RDS: bastion host e túnel SSH

> Como fechar o acesso público do RDS e continuar conectando pelo DBeaver: uma EC2 como porteiro, security groups e um túnel SSH.

- Autor: Henrylle Maia, consultor AWS
- Publicado em: 2026-10-15
- Assuntos: Segurança, Banco de dados
- URL: https://pages.formacaoaws.com.br/blog/acesso-seguro-ao-rds-bastion-host/
- Aula de origem: "Hands-on: Como acessar seu banco na AWS sem expor a segurança da sua aplicação" (https://www.youtube.com/watch?v=ZnbsHaY--oo)

Um banco no Amazon RDS marcado como publicamente acessível fica ao alcance de qualquer pessoa da sua rede que tenha o endpoint, o login e a senha. Aqui eu fecho esse acesso público e continuo conectando da minha máquina pelo DBeaver, passando por uma EC2 que eu apelido de porteiro (o nome técnico é bastion host), dois security groups e um túnel SSH.

## O problema: banco público e lista de IPs

A forma que muita gente usa para acessar o banco remotamente: marcar o RDS como publicamente acessível e liberar no security group o IP de quem precisa entrar. Foi assim que eu deixei o meu, um MySQL de um WordPress, antes de mudar. O console mostrava "Public accessibility: Yes" e a regra de entrada liberava só o meu IP.

![O bloco Security do RDS do laboratório antes da mudança, com Public accessibility em Yes (security group borrado)](https://pages.formacaoaws.com.br/blog/assets/posts/acesso-seguro-ao-rds-bastion-host/rds-publico.webp)

Funciona, e é uma fragilidade grande. Quem estiver na sua rede e tiver endpoint, login e senha do banco consegue conectar. Em rede corporativa, é provável que várias pessoas saiam com o mesmo IP. Se mais gente puder editar esse security group, alguém pode liberar `0.0.0.0/0` para facilitar, o que é quase um crime com a sua aplicação. E toda vez que o IP de um desenvolvedor muda, alguém precisa voltar ao security group e trocar a regra.

> **Importante:** não trabalhe mais com banco publicamente acessível.

## O porteiro: como o acesso passa a funcionar

O bastion host é um servidor, no caso uma EC2, que serve de ponte para o banco. O banco deixa de ser público e a regra de entrada dele muda de lugar: em vez de uma lista de IPs, o security group do RDS libera a porta do banco só para o security group do porteiro. No desenho com que eu explico o conceito a porta é a 5432 (PostgreSQL); no laboratório abaixo é a 3306, do MySQL.

O porteiro, por sua vez, tem um security group que libera SSH, e quem se conecta a ele precisa da chave `.pem`. Mesmo no pior cenário, com SSH aberto para o mundo, cada desenvolvedor precisa dessa chave para chegar ao porteiro. Quem entra faz um túnel SSH e passa a alcançar o RDS por dentro da VPC.

![O porteiro na frente do banco: o RDS (security group 1) libera a porta 5432 só para o security group 2 da EC2, que libera SSH, e cada desenvolvedor chega à EC2 com a chave PEM](https://pages.formacaoaws.com.br/blog/assets/posts/acesso-seguro-ao-rds-bastion-host/desenho-porteiro.svg)

Esse modelo é essencial para recursos que não têm acesso público, como o Aurora Serverless e o ElastiCache. E dá para ir além: se a empresa só trabalha das 8h às 17h, você pode criar um mecanismo que liga o porteiro às 8h e desliga às 17h. Fora desse horário ninguém conecta no banco, porque não há porteiro para liberar a entrada.

**Fluxo:** Seu computador (DBeaver em localhost:3307) → Porteiro (EC2) (túnel SSH com chave .pem) → Amazon RDS (privado, porta 3306)

## Passo 1: fechar o acesso público do RDS

No console do RDS, abra a instância e altere a configuração para o banco **não** ser mais publicamente acessível. Aplique imediatamente. A alteração leva um tempinho: depois dela, o endpoint do banco deixa de responder para a sua máquina.

## Passo 2: criar o security group e a EC2 do porteiro

Primeiro o security group, em **EC2 > Security Groups**. Chame de `porteiro`. A regra de entrada é SSH, e a origem é o seu IP.

> **Importante:** eu cometi um erro na gravação e coloquei essa regra em *outbound*. A regra do porteiro é de **entrada** (inbound). Na saída não se mexe. Com a regra no lugar errado, a conexão ficou parada; removi a regra que eu tinha colocado na saída e criei a de entrada.

Depois, lance a instância:

- **Nome:** `porteiro`. O nome importa: faz a analogia e você sempre lembra do papel dele.
- **Imagem:** Amazon Linux, 64 bits. Arquitetura ARM também serve.
- **Tipo:** `t4g.micro`, uma instância baratinha.
- **Key pair:** crie uma só para o porteiro, separada das demais, porque é essa chave que você compartilha com quem terá acesso ao banco. Guarde o `.pem` em uma pasta segura (a minha estava em Downloads só para a demonstração).
- **Security group:** o `porteiro`, que você acabou de criar.
- **Volume:** gp3 de 8 GB, o suficiente.

## Passo 3: liberar o porteiro no security group do RDS

Agora o RDS precisa aceitar o porteiro. Abra o security group do banco e vá nas regras de entrada. Apague a regra que liberava o meu IP (não faz mais sentido, já que o banco não é público) e crie uma nova:

- **Tipo:** MySQL, porta 3306.
- **Origem:** o security group `porteiro`.

Com isso só o porteiro chega ao banco.

## Passo 4: abrir o túnel SSH

Antes de rodar, proteja a chave: ela não pode estar acessível para outros usuários. Na gravação, o meu primeiro SSH no porteiro foi recusado com `Permissions 0664 for 'porteiro.pem' are too open`, e a chave foi ignorada. No Linux, resolve com:

```bash
chmod 400 porteiro.pem
```

No Windows a proteção da chave é mais enrolada; uma saída é usar o Git Bash para conectar por SSH.

O comando do túnel, com os trechos que você troca entre `<>`:

```bash
ssh -f -N -i porteiro.pem ec2-user@<endereço-do-porteiro> -L 3307:<endpoint-do-rds>:3306
```

O que cada parte faz:

- `-f` manda o túnel para segundo plano, e o terminal não fica preso.
- `-N` impede que o SSH execute qualquer comando remoto. Só quero o túnel aberto, sem interação.
- `-i porteiro.pem` passa a chave do porteiro.
- `-L 3307:<endpoint-do-rds>:3306` é o redirecionamento de porta, o passo-chave: a porta 3307 da sua máquina leva até a porta 3306 do RDS.

Usei a 3307 localmente porque eu já tinha um servidor rodando na 3306 na minha máquina. O usuário e o endereço do porteiro eu copiei da tela de conexão SSH da própria instância (Connect, SSH client), e o endpoint do RDS aparece na página do banco.

![O terminal na gravação: o SSH recusa a chave com permissão 0664, o chmod 400 resolve e o túnel com -L 3307 volta ao prompt rodando em segundo plano (endereços borrados)](https://pages.formacaoaws.com.br/blog/assets/posts/acesso-seguro-ao-rds-bastion-host/tunel-ssh-chmod-400.webp)

Se o túnel ficar parado sem conectar, interrompa e teste só o SSH no porteiro, sem o túnel. Foi assim que eu achei os meus dois problemas: primeiro a regra do porteiro no lugar errado (Passo 2), depois a chave desprotegida.

## Passo 5: conectar pelo DBeaver e testar o porteiro

No DBeaver, configure a conexão MySQL. Como o túnel entrega o banco na sua própria máquina, o servidor deixa de ser o endpoint do RDS:

- **Server host:** `localhost`
- **Port:** `3307`
- **Database:** o nome do seu banco (no meu caso, `wordpress`)
- **Username e password:** os do banco

![A conexão no DBeaver apontando para localhost, porta 3307 (usuário e senha borrados)](https://pages.formacaoaws.com.br/blog/assets/posts/acesso-seguro-ao-rds-bastion-host/dbeaver-localhost-3307.webp)

Teste a conexão e finalize. Eu vi os bancos disponíveis e as tabelas do WordPress, remotamente, com o RDS fechado.

Para provar que o porteiro faz o trabalho, pare a instância dele. A conexão no DBeaver cai, e se você tentar editar a conexão e conectar de novo, o acesso não existe mais. Ao parar o porteiro, você fecha também o acesso ao RDS.

Um ponto de operação: ao parar e ligar o porteiro de novo, o IP dele pode mudar, e o comando do túnel precisa do endereço novo. Dá para automatizar o desligar e o ligar com a CLI, para o processo ficar transparente.

## Checklist

- Marque o RDS como não publicamente acessível e aplique a alteração.
- Crie o security group do porteiro com SSH de **entrada**, origem no seu IP.
- Lance a EC2 do porteiro com uma key pair exclusiva.
- No security group do RDS, apague a regra do seu IP e libere a porta do banco para o security group do porteiro.
- Proteja a chave com `chmod 400` e abra o túnel com `ssh -f -N -i`.
- Se o túnel ficar parado, teste só o SSH no porteiro para achar a causa.
- Aponte o DBeaver para `localhost` e a porta local do túnel.
- Pare o porteiro e confirme que o acesso ao banco some.

O banco continua acessível para quem precisa e deixa de ficar exposto para quem não precisa. A partir de agora, banco publicamente acessível fica de fora do seu ambiente.
