College Online
0%

Redes na Pratica

Modulo 4 · Aula 3 ~25 min de leitura Nivel: Intermediario

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:

Diagrama
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
Python
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.

Diagrama
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)
*
WireGuard no Fly.io O Fly.io usa WireGuard internamente para conectar todas as VMs na sua rede privada. Quando você faz 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.

Referência
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
Diagrama
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.

Python
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:

Diagrama
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:

Python
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.

Diagrama
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

Homework

Exercício 1: Faça uma auditoria de segurança das conexões de rede do seu ambiente de desenvolvimento.

  1. Liste todas as portas TCP abertas no seu computador com ss -tlnp
  2. Para cada porta: qual processo está escutando? É necessário? Está exposta à rede ou só ao localhost?
  3. Identifique vulnerabilidades: serviços sem autenticação? Portas desnecessariamente abertas?

Exercício 2: Capture e analise tráfego DNS com tshark.

  1. Execute tshark -i eth0 -c 20 -f "port 53" enquanto navega na web
  2. Identifique: quantas queries DNS são feitas por página? Quais domínios são consultados?
  3. 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?

  • Criptografar dados entre aplicação e banco
  • Reutilizar conexões TCP existentes, evitando o custo de novos handshakes
  • Fazer backup automático do banco de dados
  • Comprimir queries SQL antes de enviar ao servidor

Verifique seu entendimento

Qual a diferença fundamental entre um firewall stateful e um packet filter?

  • O packet filter é mais seguro porque examina o payload
  • O stateful só funciona com UDP, enquanto o packet filter funciona com TCP
  • O stateful rastreia o estado das conexões (SYN, ESTABLISHED), enquanto o packet filter analisa cada pacote isoladamente
  • Não há diferença — são sinônimos

Verifique seu entendimento

Por que uma conexão Neon Postgres tem latência significativa no primeiro request (cold start)?

  • Porque o DNS precisa resolver o domínio pela primeira vez
  • Porque o compute (instância PostgreSQL) pode estar desligado e precisa ser iniciado sob demanda
  • Porque o TLS handshake é sempre lento na primeira conexão
  • Porque o PgBouncer precisa compilar a query antes de executá-la