Redes na Pratica
Video da aula estara disponivel em breve
Firewalls
Um firewall é um dispositivo (hardware ou software) que filtra tráfego de rede baseado em regras. É a primeira linha de defesa de qualquer rede, controlando o que entra e o que sai. Existem três categorias principais, cada uma operando em camadas diferentes do modelo OSI:
- Packet filter (camada 3/4): inspeciona headers (IP, porta, protocolo) de cada pacote individualmente. Simples e rápido, mas sem contexto — não sabe se um pacote pertence a uma conexão legítima.
- Stateful inspection (camada 4): rastreia o estado das conexões TCP (SYN, ESTABLISHED, etc.). Permite respostas a conexões iniciadas internamente e bloqueia pacotes que não pertencem a nenhuma conexão conhecida.
- Application-layer gateway / WAF (camada 7): inspeciona o payload (conteúdo HTTP, SQL, etc.). Mais lento, mas detecta ataques como SQL injection, XSS e path traversal.
Regras de firewall (iptables/nftables — Linux):
Chain INPUT (pacotes que chegam ao host):
ACCEPT tcp dport 22 src 192.168.1.0/24 # SSH da rede interna
ACCEPT tcp dport 443 src 0.0.0.0/0 # HTTPS de qualquer lugar
ACCEPT tcp dport 80 src 0.0.0.0/0 # HTTP de qualquer lugar
DROP all src 0.0.0.0/0 # Bloqueia todo o resto
Chain FORWARD (pacotes roteados pelo host):
ACCEPT tcp dport 5432 src 10.0.0.0/8 # Postgres da VPC interna
DROP all src 0.0.0.0/0 # Bloqueia resto
Chain OUTPUT (pacotes que saem do host):
ACCEPT all dst 0.0.0.0/0 # Permite toda saída
Stateful: regra especial que permite respostas
ACCEPT all state ESTABLISHED,RELATED # Respostas a conexões ativas
import subprocess
# Verificar regras de firewall ativas (Linux)
def show_firewall_rules():
"""Lista regras iptables ativas no sistema."""
result = subprocess.run(
["iptables", "-L", "-n", "-v", "--line-numbers"],
capture_output=True, text=True
)
print(result.stdout)
# Verificar portas abertas no host
def check_open_ports():
"""Lista portas TCP em estado LISTEN."""
result = subprocess.run(
["ss", "-tlnp"],
capture_output=True, text=True
)
print("Portas TCP abertas:")
for line in result.stdout.splitlines():
print(f" {line}")
check_open_ports()
VPN e tunneling
Uma VPN (Virtual Private Network) cria um "túnel" criptografado sobre a Internet pública, permitindo comunicação segura entre redes privadas. O conceito central é o encapsulamento: o pacote original é encriptado e colocado dentro de outro pacote IP, como uma carta dentro de um envelope.
Sem VPN:
Laptop --[HTTP/TCP/IP]--> Internet --> Servidor
(dados visíveis para qualquer ponto intermediário)
Com VPN (tunneling):
Laptop --[dados|TCP|IP|ENCRIPTADO|IP_externo]--> VPN Server --> Servidor
| |
+---- Túnel VPN (IPsec/WireGuard) ------+
(dados invisíveis para intermediários)
Encapsulamento (o que acontece ao pacote):
┌────────────────────────────────────────────────────┐
│ IP Header (externo) │ UDP Header │ WireGuard │
│ src: IP_laptop │ dport: 51820│ encrypted │
│ dst: IP_vpn_server │ │ payload: │
│ │ │ ┌──────────┐│
│ │ │ │IP original││
│ │ │ │TCP header ││
│ │ │ │HTTP data ││
│ │ │ └──────────┘│
└────────────────────────────────────────────────────┘
Protocolos VPN:
IPsec: Padrão, complexo, suporte nativo em SO. Dois modos:
- Transport mode: encripta só payload IP
- Tunnel mode: encripta pacote IP inteiro
WireGuard: Moderno, simples, rápido (~4000 linhas de código)
Usa Curve25519, ChaCha20, Poly1305
OpenVPN: Maduro, flexível, baseado em SSL/TLS
Opera na camada de aplicação (user-space)
fly proxy 5432, está criando um túnel WireGuard do seu computador até a VM no datacenter. Isso é networking na prática — cada comando que roda no deploy usa conceitos desta aula.
Cloud networking
Em ambientes cloud (AWS, GCP, Fly.io), conceitos de rede tradicionais ganham novas abstrações. O engenheiro precisa entender ambos os níveis — a abstração cloud e o protocolo de rede por baixo.
Conceito cloud Equivalente de rede Camada OSI
────────────────── ────────────────────────── ──────────
VPC Rede privada virtual (/16) Camada 3
Subnet Sub-rede dentro do VPC Camada 3
Security Group Firewall stateful Camada 3/4
NACL (Network ACL) Packet filter (stateless) Camada 3
Load Balancer (ALB) Reverse proxy + LB Camada 7
Load Balancer (NLB) TCP/UDP load balancer Camada 4
NAT Gateway NAT para subnets privadas Camada 3
Peering Conexão direta entre VPCs Camada 3
Private Link Acesso sem sair da rede Camada 3
Transit Gateway Hub central entre VPCs Camada 3
Arquitetura de rede cloud típica (AWS/GCP):
┌── VPC (10.0.0.0/16) ──────────────────────────────────────┐
│ │
│ ┌── Subnet pública (10.0.1.0/24) ─────────────────────┐ │
│ │ [Internet GW] [NAT GW] [Load Balancer] │ │
│ │ │ │ │ │ │
│ └───────┼─────────────┼───────────┼────────────────────┘ │
│ │ │ │ │
│ ┌── Subnet privada (10.0.2.0/24) ─────────────────────┐ │
│ │ [App Server A] [App Server B] [App Server C] │ │
│ │ │ │ │ │ │
│ └───────┼─────────────┼───────────┼────────────────────┘ │
│ │ │ │ │
│ ┌── Subnet dados (10.0.3.0/24) ───────────────────────┐ │
│ │ [RDS Postgres] [ElastiCache Redis] │ │
│ │ (sem acesso direto à Internet) │ │
│ └──────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────┘
Fluxo: Internet → LB → App (subnet privada) → DB (subnet dados)
App → NAT GW → Internet (para atualizações, APIs externas)
Análise de tráfego com Wireshark
O Wireshark (e sua versão CLI tshark) é a ferramenta padrão para captura e análise de pacotes. Permite visualizar cada camada do modelo OSI em tempo real.
import subprocess
# Capturar pacotes com tshark (CLI do Wireshark)
# Requer permissões de root/admin
def capture_dns_traffic(interface="eth0", count=10):
"""Captura pacotes DNS e mostra as queries."""
result = subprocess.run([
"tshark", "-i", interface,
"-c", str(count),
"-f", "port 53", # Filtro de captura: só DNS
"-T", "fields",
"-e", "ip.src",
"-e", "ip.dst",
"-e", "dns.qry.name", # Domínio consultado
"-e", "dns.qry.type", # Tipo (A, AAAA, CNAME)
], capture_output=True, text=True, timeout=30)
print("Tráfego DNS capturado:")
print(result.stdout)
def capture_tcp_handshake(host, interface="eth0"):
"""Captura o three-way handshake TCP para um host."""
result = subprocess.run([
"tshark", "-i", interface,
"-c", "10",
"-f", f"host {host}",
"-T", "fields",
"-e", "frame.number",
"-e", "ip.src",
"-e", "ip.dst",
"-e", "tcp.flags.str", # SYN, SYN-ACK, ACK
"-e", "tcp.seq",
"-e", "tcp.ack",
], capture_output=True, text=True, timeout=30)
print(f"TCP handshake com {host}:")
print(result.stdout)
Conexões Neon Postgres
Entender networking é essencial para configurar e debugar conexões ao banco de dados. Cada conexão Postgres atravessa múltiplas camadas de rede:
Conexão Neon Postgres (o que realmente acontece):
App/Agent
|
|-- 1. DNS resolve: ep-xxx.us-east-2.aws.neon.tech → IP
|-- 2. TCP handshake (SYN/SYN-ACK/ACK) — ~1 RTT
|-- 3. TLS handshake (ClientHello, ServerHello, certs) — ~2 RTTs
|-- 4. PostgreSQL startup (authentication, database) — ~1 RTT
|
v
Neon Proxy (PgBouncer)
|-- Connection pooling (reutiliza conexões ao compute)
|-- SNI routing (usa Server Name Indication para rotear)
|-- Wakes up compute if cold-started (~300ms-2s de cold start)
|
v
Neon Compute (PostgreSQL)
|-- Executa queries
|-- Retorna resultados via TCP stream
|
v
Neon Storage (pageserver)
|-- Separação compute/storage (arquitetura serverless)
|-- Pages carregados sob demanda do storage
Connection string:
postgresql://user:pass@ep-xxx.us-east-2.aws.neon.tech/dbname?sslmode=require
Cada parte mapeia para conceitos de rede:
user:pass → Autenticação (camada de aplicação)
ep-xxx... → DNS (camada de aplicação)
:5432 → Porta TCP (camada de transporte)
sslmode=require → TLS (entre transporte e aplicação)
Latência total de uma query:
DNS + TCP handshake + TLS handshake + PG auth + query execution
≈ 5ms + 10ms + 20ms + 5ms + query_time
Cold start adiciona: ~500ms-2s (compute precisa acordar)
Diagnóstico de rede na prática
Ferramentas essenciais para diagnóstico de problemas de rede em produção:
import subprocess
import socket
import ssl
import time
def full_network_diagnosis(host, port=443):
"""Diagnóstico completo de conectividade com um host."""
# 1. Resolução DNS
print(f"=== Diagnóstico de rede para {host}:{port} ===")
start = time.perf_counter()
try:
ips = socket.getaddrinfo(host, port)
dns_time = (time.perf_counter() - start) * 1000
ip = ips[0][4][0]
print(f" DNS: {host} → {ip} ({dns_time:.1f}ms)")
except socket.gaierror as e:
print(f" DNS FALHOU: {e}")
return
# 2. Conexão TCP
start = time.perf_counter()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
try:
sock.connect((ip, port))
tcp_time = (time.perf_counter() - start) * 1000
print(f" TCP: handshake OK ({tcp_time:.1f}ms)")
except (socket.timeout, ConnectionRefusedError) as e:
print(f" TCP FALHOU: {e}")
return
# 3. TLS handshake
start = time.perf_counter()
ctx = ssl.create_default_context()
try:
ssock = ctx.wrap_socket(sock, server_hostname=host)
tls_time = (time.perf_counter() - start) * 1000
cert = ssock.getpeercert()
print(f" TLS: {ssock.version()} ({tls_time:.1f}ms)")
print(f" Cert: {cert['subject'][0][0][1]}")
print(f" Expira: {cert['notAfter']}")
ssock.close()
except ssl.SSLError as e:
print(f" TLS FALHOU: {e}")
full_network_diagnosis("ep-xxx.us-east-2.aws.neon.tech", 5432)
No harness.os
Esta aula integra todos os conceitos práticos que aparecem diariamente no harness.os — firewalls protegem os endpoints, VPN/WireGuard conecta os nodes, e o diagnóstico de rede é essencial quando tool calls falham.
Auditoria de segurança de rede do harness.os:
1. MCP Server (Fly.io)
[x] HTTPS obrigatório (TLS 1.3)
[x] Fly.io private networking (WireGuard interno)
[ ] Rate limiting em endpoints públicos
[ ] mTLS entre nodes do mesh
2. Neon Postgres
[x] SSL required (sslmode=require)
[x] Connection pooling (PgBouncer)
[x] IP allowlist (Neon dashboard)
[ ] Rotação automática de credenciais
3. Claude CLI → MCP (local)
[x] stdio (sem rede, mais seguro)
[x] Nenhuma exposição de porta
4. Fly.io networking
[x] Anycast IP (distribuição global)
[x] Auto-TLS (Let's Encrypt)
[x] Private networking entre apps (WireGuard mesh)
[ ] DDoS protection (built-in Fly.io)
Diagnóstico de falhas mais comuns:
"MCP tool call timeout"
→ Verificar: DNS resolve? TCP conecta? TLS válido? Neon cold start?
"Connection refused ao Neon"
→ Verificar: IP allowlist atualizado? Compute ativo? Porta 5432?
"Latência alta nas queries"
→ Verificar: região do compute vs app? Connection pooling? Cold start?
Resumo
- Firewalls filtram tráfego por regras — packet filter, stateful inspection e WAF operam em camadas diferentes
- VPNs criam túneis criptografados sobre redes públicas, usando encapsulamento de pacotes
- Cloud networking abstrai conceitos tradicionais (VPC, security groups, load balancers) mas o engenheiro precisa entender ambos os níveis
- Conexões Neon Postgres atravessam DNS, TCP, TLS e PostgreSQL wire protocol — cada etapa adiciona latência
- Connection pooling (PgBouncer) reutiliza conexões TCP existentes, eliminando o custo de handshakes repetidos
- Ferramentas como Wireshark/tshark, ss, traceroute e scripts de diagnóstico são essenciais para debugging em produção
Homework
Exercício 1: Faça uma auditoria de segurança das conexões de rede do seu ambiente de desenvolvimento.
- Liste todas as portas TCP abertas no seu computador com
ss -tlnp - Para cada porta: qual processo está escutando? É necessário? Está exposta à rede ou só ao localhost?
- Identifique vulnerabilidades: serviços sem autenticação? Portas desnecessariamente abertas?
Exercício 2: Capture e analise tráfego DNS com tshark.
- Execute
tshark -i eth0 -c 20 -f "port 53"enquanto navega na web - Identifique: quantas queries DNS são feitas por página? Quais domínios são consultados?
- Compare o tempo de resolução DNS para domínios já cacheados vs. novos
Exercício 3: Escreva um script Python que mede a latência total de conexão (DNS + TCP + TLS) para três endpoints diferentes e gera um relatório comparativo.
Exercício 4: Projete regras de firewall (iptables) para proteger um servidor que roda apenas um MCP server na porta 8080 e um banco Postgres na porta 5432.
Verifique seu entendimento
Qual a principal função do connection pooling (PgBouncer) em conexões Neon Postgres?
Verifique seu entendimento
Qual a diferença fundamental entre um firewall stateful e um packet filter?
Verifique seu entendimento
Por que uma conexão Neon Postgres tem latência significativa no primeiro request (cold start)?