
AWS Session Manager Port Forwarding to Remote Host
O AWS Systems Manager Session Manager permite criar sessões de port forwarding entre uma máquina local e recursos privados acessíveis através de uma instância EC2 gerenciada pelo Systems Manager. Esse recurso permite acessar aplicações, bancos de dados e outros serviços executados dentro de uma rede privada sem a necessidade de expor esses recursos para a internet ou possuir conectividade de rede direta entre o computador do usuário e o recurso de destino.
O AWS Systems Manager Session Manager permite criar sessões de port forwarding entre uma máquina local e recursos privados acessíveis através de uma instância EC2 gerenciada pelo Systems Manager.
Esse recurso permite acessar aplicações, bancos de dados e outros serviços executados dentro de uma rede privada sem a necessidade de expor esses recursos para a internet ou possuir conectividade de rede direta entre o computador do usuário e o recurso de destino.
Neste projeto, utilizaremos uma instância EC2 em uma subnet privada como ponto intermediário para acessar um Amazon RDS PostgreSQL também privado.
1
Notebook localhost:5432 -> AWS Systems Manager -> SSM Agent -> EC2 -> RDS PostgreSQL:5432
Nesse modelo, tanto a EC2 quanto o RDS podem permanecer sem acesso público.
A comunicação entre nossa máquina e a EC2 é transportada através de uma sessão do AWS Systems Manager. A partir da EC2, a conexão com o RDS utiliza a conectividade privada existente dentro da VPC.
EC2 em subnet privada
A instância EC2 utilizada neste projeto será executada em uma subnet privada.
Uma subnet privada não possui rota direta para um Internet Gateway. Dessa forma, a instância não precisa possuir endereço IP público e não pode receber conexões iniciadas diretamente através da internet.
A Route Table associada à subnet privada utiliza um NAT Gateway para permitir conexões de saída:
1
2
10.0.0.0/16 -> local
0.0.0.0/0 -> NAT Gateway
O NAT Gateway fica localizado em uma subnet pública e possui conectividade com a internet através do Internet Gateway.
A comunicação de saída da instância acontece da seguinte forma:
1
EC2 privada -> NAT Gateway -> Internet Gateway -> Internet
No caso do Session Manager, o SSM Agent inicia a comunicação HTTPS necessária com a infraestrutura da AWS. O NAT Gateway fornece o caminho de saída necessário para essa comunicação.
Isso não torna a EC2 acessível através da internet. A instância continua privada e sem a necessidade de possuir regras de entrada para permitir o acesso através do Session Manager.
Amazon RDS em subnet privada
O Amazon RDS PostgreSQL utilizado neste projeto também será executado de forma privada dentro da VPC.
O banco não precisa possuir acesso público porque nossa máquina não estabelecerá uma conexão diretamente com o endpoint do RDS.
Não teremos:
1
Notebook -> Internet -> RDS:5432
O acesso ao banco acontecerá através da conectividade existente entre a EC2 e o RDS:
1
EC2 -> RDS PostgreSQL:5432
Por isso, nossa máquina não precisa possuir rota para as subnets privadas onde o banco está localizado.
O requisito de rede existe entre a EC2 e o RDS.
Session Manager Port Forwarding to Remote Host
O Session Manager permite encaminhar uma porta da nossa máquina para um host remoto acessível através da instância EC2 utilizada como target da sessão.
Para isso, podemos utilizar o documento:
1
AWS-StartPortForwardingSessionToRemoteHost
Nesse modelo temos:
1
localhost:<LOCAL_PORT> -> Session Manager -> SSM Agent -> EC2 -> <REMOTE_HOST>:<REMOTE_PORT>
A EC2 funciona como o managed node da sessão e precisa possuir conectividade de rede com o remote host.
Neste projeto, o remote host será o endpoint privado de um RDS PostgreSQL:
1
localhost:5432 -> Session Manager -> SSM Agent -> EC2 -> RDS PostgreSQL:5432
O notebook não estabelece uma conexão TCP diretamente com o endereço privado da EC2 ou com o RDS.
O Session Manager transporta a comunicação até a instância e, a partir dela, a rede da VPC é utilizada para alcançar o banco.
Criando a sessão de Port Forwarding
Para criar a sessão podemos utilizar:
1
2
3
4
5
6
7
8
9
10
aws ssm start-session \
--target <INSTANCE_ID> \
--region <AWS_REGION> \
--profile <PROFILE> \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{
"host":["<REMOTE_HOST>"],
"portNumber":["<REMOTE_PORT>"],
"localPortNumber":["<LOCAL_PORT>"]
}'
Existem três parâmetros importantes nesse comando.
host representa o hostname ou endereço do recurso remoto que será acessado através da EC2.portNumber representa a porta utilizada pelo serviço no remote host.localPortNumber representa a porta que ficará disponível na nossa máquina.Para um RDS PostgreSQL podemos utilizar:
1
2
3
4
5
6
7
8
9
10
aws ssm start-session \
--target i-0123456789abcdef0 \
--region us-east-1 \
--profile <PROFILE> \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{
"host":["database.xxxxxxxxxxxx.us-east-1.rds.amazonaws.com"],
"portNumber":["5432"],
"localPortNumber":["5432"]
}'
Nesse cenário:
1
localhost:5432 -> EC2 -> RDS PostgreSQL:5432
A porta local não precisa ser igual à porta utilizada pelo recurso remoto.
Também poderíamos utilizar:
1
localhost:15432 -> RDS PostgreSQL:5432
configurando:
1
2
3
4
5
{
"host": ["database.xxxxxxxxxxxx.us-east-1.rds.amazonaws.com"],
"portNumber": ["5432"],
"localPortNumber": ["15432"]
}
Nesse caso, nosso cliente PostgreSQL utilizaria:
1
localhost:15432
enquanto o RDS continuaria recebendo a conexão na porta
5432.Como o tráfego chega até o RDS
Quando a sessão de port forwarding está ativa, o Session Manager Plugin passa a escutar a porta definida em
localPortNumber na nossa máquina.No nosso exemplo:
1
localhost:5432
Quando uma aplicação como DBeaver ou
psql conecta nessa porta, o tráfego é recebido pelo Session Manager Plugin e transportado através da sessão do Systems Manager até o SSM Agent executado na EC2.O SSM Agent então encaminha a comunicação para o host e porta definidos na sessão:
1
database.xxxxxxxxxxxx.us-east-1.rds.amazonaws.com:5432
A partir desse ponto, a EC2 utiliza sua própria conectividade de rede para alcançar o RDS.
Podemos representar o fluxo completo como:
1
DBeaver -> localhost:5432 -> Session Manager Plugin -> AWS Systems Manager -> SSM Agent -> EC2 -> RDS:5432
A resposta do PostgreSQL percorre o caminho contrário até chegar novamente ao cliente local.
Por isso conseguimos utilizar
localhost:5432 mesmo que o banco esteja localizado em uma subnet privada e nossa máquina não possua uma rota até ele.Resolução do endpoint do RDS
O endpoint informado no parâmetro
host precisa ser alcançável a partir da instância EC2.No nosso cenário:
1
EC2 -> database.xxxxxxxxxxxx.us-east-1.rds.amazonaws.com:5432
A EC2 precisa conseguir resolver o endpoint do RDS e possuir conectividade de rede com os endereços retornados.
Nossa máquina não precisa estabelecer essa conexão diretamente.
O fluxo continua sendo:
1
Notebook -> localhost:5432 -> Session Manager -> EC2 -> RDS endpoint:5432
Por isso o requisito de conectividade existe entre:
1
EC2 -> RDS
e não entre:
1
Notebook -> RDS
Security Groups
Os Security Groups possuem responsabilidades importantes nessa arquitetura.
A EC2 não precisa possuir uma regra de entrada permitindo conexões do nosso notebook para a porta
5432.Também não precisamos liberar SSH para acessar a instância:
1
EC2 Inbound TCP 22 -> 0.0.0.0/0
A sessão é estabelecida através do AWS Systems Manager.
Entretanto, existe uma conexão de rede entre a EC2 e o RDS:
1
EC2 -> RDS:5432
Por isso, o Security Group do RDS precisa permitir conexões TCP na porta
5432 originadas pelo Security Group utilizado pela EC2.1
2
3
RDS Security Group
Inbound TCP 5432 <- EC2 Security Group
Esse modelo permite controlar a comunicação utilizando a identidade do Security Group da EC2 em vez de liberar o banco para uma faixa de endereços externa.
Não precisamos configurar:
1
RDS Inbound TCP 5432 <- 0.0.0.0/0
O RDS continua privado e aceita a conexão necessária através da rede da VPC.
A EC2 como ponto intermediário
A instância EC2 funciona como o ponto intermediário entre a sessão do Systems Manager e o recurso privado.
Ela não precisa executar PostgreSQL, DBeaver ou qualquer aplicação relacionada ao banco.
Ela precisa estar configurada como managed node do Systems Manager e possuir conectividade de rede com o remote host.
1
Notebook -> AWS Systems Manager -> EC2 -> Remote Host
No nosso projeto:
1
Notebook -> AWS Systems Manager -> EC2 privada -> RDS PostgreSQL privado
O remote host também não precisa necessariamente ser um RDS.
O mesmo modelo pode ser utilizado para outros serviços TCP privados que sejam alcançáveis pela EC2.
Acessando o PostgreSQL com psql
Com a sessão ativa, podemos utilizar um cliente PostgreSQL instalado na nossa própria máquina.
1
2
3
4
5
psql \
--host localhost \
--port 5432 \
--username <DB_USER> \
--dbname <DB_NAME>
Para o
psql, o banco está disponível através de:1
localhost:5432
O cliente não precisa conhecer o endereço privado da EC2 e nem possuir conectividade direta com o endpoint do RDS.
A comunicação é transportada através da sessão até a EC2 e encaminhada para o banco.
Acessando o PostgreSQL com DBeaver
Também podemos utilizar o DBeaver para acessar o banco.
Enquanto a sessão estiver ativa, podemos configurar:
1
2
3
4
5
Host: localhost
Port: 5432
Database: <DB_NAME>
Username: <DB_USER>
Password: <DB_PASSWORD>
O DBeaver abre uma conexão TCP para:
1
localhost:5432
O Session Manager Plugin recebe essa conexão e transporta o tráfego através da sessão:
1
DBeaver -> localhost:5432 -> Session Manager Plugin -> AWS Systems Manager -> SSM Agent -> EC2 -> RDS:5432
Para o DBeaver, estamos conectando em um PostgreSQL disponível localmente.
O banco, entretanto, continua executando de forma privada dentro da AWS.
Port Forwarding não torna o RDS público
Criar uma sessão utilizando
AWS-StartPortForwardingSessionToRemoteHost não altera a configuração de rede do RDS.O banco continua privado.
Não criamos:
1
Internet -> RDS:5432
Também não transformamos o endpoint privado em um endpoint público.
O caminho existe enquanto a sessão estiver ativa:
1
localhost:5432 -> Session Manager -> EC2 -> RDS:5432
Quando a sessão é encerrada, a porta local deixa de fornecer esse caminho até o banco.
O RDS continua funcionando normalmente dentro da VPC.
Arquitetura
A infraestrutura utilizada neste projeto possui subnets públicas e privadas distribuídas entre duas Availability Zones.
A instância EC2 é executada em uma subnet privada, sem endereço IP público.
O Amazon RDS PostgreSQL também permanece privado e não recebe conexões diretamente da internet.
O NAT Gateway localizado na camada pública fornece conectividade de saída para que o SSM Agent alcance os endpoints públicos necessários do AWS Systems Manager.
O acesso ao banco acontece através do Session Manager Port Forwarding to Remote Host.
1
Notebook localhost:5432 -> AWS Systems Manager -> SSM Agent -> EC2 privada -> RDS PostgreSQL:5432
É importante separar os dois fluxos envolvidos nessa arquitetura.
A comunicação necessária para o SSM Agent alcançar o Systems Manager:
1
EC2 -> NAT Gateway -> Internet Gateway -> AWS Systems Manager
E a comunicação da EC2 com o banco:
1
EC2 -> Rede privada da VPC -> RDS PostgreSQL:5432
O NAT Gateway não transporta a conexão entre a EC2 e o RDS.
O Session Manager fornece o caminho entre nossa máquina e a instância. A partir da EC2, a conectividade privada da VPC fornece o caminho até o banco.
Comparação de arquitetura
Se o banco estivesse publicamente acessível, poderíamos ter:
1
Notebook -> Internet -> RDS Public Endpoint:5432
Nesse cenário, seria necessário fornecer conectividade pública ao banco e controlar quais origens poderiam acessar sua porta.
Uma arquitetura utilizando um bastion host e SSH poderia utilizar:
1
Notebook -> SSH -> Bastion Host -> RDS:5432
Com o Session Manager Port Forwarding to Remote Host:
1
Notebook localhost:5432 -> AWS Systems Manager -> SSM Agent -> EC2 privada -> RDS privado:5432
Não precisamos tornar o RDS publicamente acessível para permitir o acesso através da nossa máquina.
Também não precisamos expor a porta
22 da EC2 para criar um SSH tunnel.A EC2 e o RDS podem permanecer privados enquanto o acesso é estabelecido através do AWS Systems Manager e da conectividade interna da VPC.
Conclusão
O AWS Systems Manager Session Manager permite utilizar Port Forwarding to Remote Host para acessar recursos privados que possuem conectividade com uma instância gerenciada pelo Systems Manager.
Nesse modelo, o Session Manager transporta o tráfego de uma porta local até a EC2 e, a partir dela, a conectividade da VPC é utilizada para alcançar o remote host.
1
localhost:<LOCAL_PORT> -> Session Manager -> SSM Agent -> EC2 -> <REMOTE_HOST>:<REMOTE_PORT>
Neste projeto, utilizamos uma EC2 privada como managed node para acessar um Amazon RDS PostgreSQL também privado.
1
DBeaver -> localhost:5432 -> Session Manager -> SSM Agent -> EC2 -> RDS PostgreSQL:5432
O banco não precisa possuir acesso público e nossa máquina não precisa possuir conectividade de rede direta com as subnets privadas da VPC.
A EC2 precisa apenas estar conectada ao Systems Manager e possuir conectividade de rede com o endpoint do RDS.
Dessa forma, conseguimos utilizar ferramentas locais como
psql e DBeaver para acessar um PostgreSQL privado através do localhost, mantendo a EC2 e o banco isolados da internet e utilizando IAM e AWS Systems Manager para controlar o estabelecimento da sessão.Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article