Skip to main content

EC2 na prática: Security Groups, Ingress e Egress

Manual passo a passo para entender e operar o firewall das instâncias EC2, removendo e readicionando as portas HTTP/HTTPS ao vivo, e entendendo de vez a diferença entre inbound (ingress) e outbound (egress).

Pré-requisito: instância running com nginx instalado e acessível via navegador (manuais 01 e 02).


Parte 1: O que é um Security Group​

O Security Group (SG) é um firewall stateful por instância, aplicado na "placa de rede" virtual (ENI), fora do sistema operacional.

Características que o diferenciam de um firewall tradicional:

  • Só existem regras de allow: não há regra de "deny". O que não está liberado está negado.
  • Stateful: se a conexão entrou por uma regra, a resposta sai automaticamente (e vice-versa), sem precisar de regra no outro sentido.
  • Reutilizável: o mesmo SG pode estar em N instâncias, mudou a regra, valeu para todas na hora, sem reboot.
  • Uma instância pode ter vários SGs ao mesmo tempo (as regras se somam).

💡 Equivalente on-prem: um firewall de borda dedicado por VM (ou uma política NSX), gerenciado central e aplicado instantaneamente.


Parte 2: Ingress vs Egress: a diferença fundamental​

Todo SG tem duas listas de regras, e confundi-las é a fonte nº 1 de "não consigo acessar":

Inbound (ingress)Outbound (egress)
DireçãoTráfego que chega na instânciaTráfego que sai da instância
Pergunta que responde"Quem pode me acessar, e em qual porta?""Onde a minha instância pode se conectar?"
Padrão ao criar um SGTudo negadoTudo liberado (0.0.0.0/0 All traffic)
ExemplosUsuário acessando o site (80/443), você via SSH (22)apt update, chamada a uma API externa, consulta a um banco

A regra de bolso para nunca mais confundir:

Ingress = você é o servidor. Alguém de fora inicia a conexão para a instância. Egress = você é o cliente. A instância inicia a conexão para fora.

E o detalhe que o stateful resolve: quando um usuário acessa o site (ingress na 80), a resposta do nginx para o usuário não precisa de regra de egress, o SG reconhece que é a volta de uma conexão permitida. Regras de egress só importam para conexões iniciadas pela instância.

💡 No mundo on-prem, firewalls stateless exigem liberar ida e volta (portas efêmeras etc.). O SG elimina essa metade do trabalho.


Parte 3: Prática: removendo o HTTP/HTTPS ao vivo​

Vamos quebrar o acesso ao site de propósito, e ver que o SSH continua funcionando.

3.1 Localizar o Security Group da instância​

  1. Console EC2 → Instances → selecione a instância → aba Security.
  2. Clique no security group listado (ex.: launch-wizard-1).
  3. Observe as duas abas: Inbound rules e Outbound rules.

3.2 Confirmar o estado atual​

  1. Em Inbound rules, você deve ver: SSH (22), HTTP (80), HTTPS (443).
  2. No navegador, abra http://IP_PUBLICO, página do nginx no ar. ✅

3.3 Remover as regras de HTTP e HTTPS​

  1. Aba Inbound rules → Edit inbound rules.
  2. Clique em Delete nas linhas do HTTP (80) e do HTTPS (443), deixe o SSH (22)!
  3. Save rules.

3.4 Observar o efeito (imediato)​

  1. Recarregue http://IP_PUBLICO no navegador → timeout / não conecta. ❌
  2. Na sessão SSH (que continua aberta e funcionando), verifique que o nginx está rodando normalmente:
systemctl status nginx        # active (running)
curl http://localhost # responde! o serviço está de pé

💡 Momento-chave da aula: o serviço está no ar, mas a porta está fechada na borda. No troubleshooting real, curl localhost funcionando + acesso externo falhando = problema de Security Group (ou NACL/rota), não da aplicação. Esse reflexo de diagnóstico vale ouro.

Repare também: a regra some para todas as instâncias que usam esse SG, no mesmo segundo, sem reiniciar nada.

3.5 Testar o egress (opcional, para fixar a direção)​

Mesmo sem inbound 80/443, rode na instância:

curl -I https://www.google.com     # funciona!

Funciona porque essa conexão é iniciada pela instância (egress, liberado por padrão). As regras de inbound que removemos só bloqueiam conexões iniciadas de fora. Não há demonstração melhor da diferença entre as duas direções.


Parte 4: Adicionando as regras de volta​

4.1 Recriar HTTP e HTTPS​

  1. No SG → Inbound rules → Edit inbound rules → Add rule (2x):
TypeProtocolPort rangeSourceDescrição sugerida
HTTPTCP800.0.0.0/0site publico
HTTPSTCP4430.0.0.0/0site publico tls
  1. Save rules.
  2. Recarregue o navegador → nginx de volta no ar. ✅ (Efeito imediato, sem reboot.)

💡 Ao escolher o Type (HTTP, HTTPS, SSH, MySQL...), a console preenche protocolo e porta sozinha. Para portas fora da lista, use Custom TCP.

4.2 Entendendo o campo Source​

O Source define quem pode usar a regra de inbound:

SourceSignificadoQuando usar
0.0.0.0/0Qualquer IP da internetServiços realmente públicos (80/443 de um site)
My IPSó o seu IP atualSSH/administração, o mais seguro para lab
Um CIDR (ex.: 10.0.0.0/8)Uma faixa de redeRedes corporativas/VPN
Outro Security GroupQualquer instância que use aquele SGComunicação entre camadas (ver abaixo)

⭐ Source = outro SG é o recurso mais elegante do modelo. Exemplo clássico: no SG do banco de dados, libere a porta 3306 com Source = sg-do-app. Tradução: "só quem veste o crachá do app fala com o banco", sem gerenciar um único IP, e válido automaticamente para instâncias que nascem e morrem no auto scaling.


Parte 5: Boas práticas essenciais​

  • Menor privilégio: libere só as portas necessárias, com o Source mais restrito possível. SSH aberto para 0.0.0.0/0 é aceitável só em lab descartável.
  • Descreva cada regra (campo Description), daqui a 6 meses ninguém lembra por que a porta 8443 está aberta.
  • Um SG por função, não por instância: sg-web, sg-app, sg-db. Instâncias novas da mesma função reutilizam o SG.
  • Egress também merece atenção em produção: o padrão "tudo liberado para fora" é cômodo, mas ambientes regulados restringem egress (ex.: servidor de banco não precisa falar com a internet). Para o lab, o padrão está ok.
  • SG não substitui o firewall do SO nem WAF, são camadas complementares (defesa em profundidade).

Resumo dos conceitos deste manual​

ConceitoLembrete-chave
Security GroupFirewall stateful por instância, só regras de allow
Ingress (inbound)Conexões iniciadas de fora para a instância, negado por padrão
Egress (outbound)Conexões iniciadas pela instância, liberado por padrão
StatefulA resposta de uma conexão permitida passa sozinha, sem regra no sentido oposto
Source = outro SGLibera "quem usa aquele crachá", sem IPs, o padrão para camadas app ↔ db
Efeito imediatoMudança de regra vale na hora, para todas as instâncias do SG