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
runningcom 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ção | Tráfego que chega na instância | Trá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 SG | Tudo negado | Tudo liberado (0.0.0.0/0 All traffic) |
| Exemplos | Usuá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
- Console EC2 → Instances → selecione a instância → aba Security.
- Clique no security group listado (ex.:
launch-wizard-1). - Observe as duas abas: Inbound rules e Outbound rules.
3.2 Confirmar o estado atual
- Em Inbound rules, você deve ver: SSH (22), HTTP (80), HTTPS (443).
- No navegador, abra
http://IP_PUBLICO, página do nginx no ar. ✅
3.3 Remover as regras de HTTP e HTTPS
- Aba Inbound rules → Edit inbound rules.
- Clique em Delete nas linhas do HTTP (80) e do HTTPS (443), deixe o SSH (22)!
- Save rules.
3.4 Observar o efeito (imediato)
- Recarregue
http://IP_PUBLICOno navegador → timeout / não conecta. ❌ - 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 localhostfuncionando + 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
- No SG → Inbound rules → Edit inbound rules → Add rule (2x):
| Type | Protocol | Port range | Source | Descrição sugerida |
|---|---|---|---|---|
| HTTP | TCP | 80 | 0.0.0.0/0 | site publico |
| HTTPS | TCP | 443 | 0.0.0.0/0 | site publico tls |
- Save rules.
- 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:
| Source | Significado | Quando usar |
|---|---|---|
0.0.0.0/0 | Qualquer IP da internet | Serviços realmente públicos (80/443 de um site) |
My IP | Só o seu IP atual | SSH/administração, o mais seguro para lab |
Um CIDR (ex.: 10.0.0.0/8) | Uma faixa de rede | Redes corporativas/VPN |
| Outro Security Group | Qualquer instância que use aquele SG | Comunicaçã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
| Conceito | Lembrete-chave |
|---|---|
| Security Group | Firewall 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 |
| Stateful | A resposta de uma conexão permitida passa sozinha, sem regra no sentido oposto |
| Source = outro SG | Libera "quem usa aquele crachá", sem IPs, o padrão para camadas app ↔ db |
| Efeito imediato | Mudança de regra vale na hora, para todas as instâncias do SG |