Pular para conteúdo

Aula 20 - Projeto Capstone: Utilitário de Rede CLI em Go Autônomo 🚀

Objetivo Pedagógico

Objetivo: Conceber e implementar um utilitário de rede e diagnóstico de sistemas completo em Go: interface CLI robusta com Cobra/Viper, inspeção de portas e rotas em rede de baixo nível, telemetria de latência e compilação em binário estático ultracompacto.


📑 1. Fundamentos Teóricos & Análise Técnica

O Projeto Capstone de Sistemas em Go consolida o desenvolvimento de software utilitário de infraestrutura de alto desempenho: 1. Ferramenta de Diagnóstico Autônoma (Network Probe & Scanner): - Capaz de inspecionar portas TCP, medir handshakes com precisão de microssegundos, coletar banners de serviços e avaliar a saúde de redes distribuídas. 2. Execução Concorrente com Worker Pool: - Varredura de milhares de nós em paralelo utilizando padrões de concorrência com canais e WaitGroups sem esgotar os recursos de CPU da máquina operadora. 3. Distribuição Enterprise: - Empacotamento em contêiner Docker scratch e binário único otimizado com telemetria exportável em formato JSON/Prometheus.

📐 Arquitetura Conceitual & Diagrama de Fluxo

graph TD
    CLI["CLI Command: goprobe scan --range 10.0.0.0/24 --workers 50"] --> Pool["Worker Pool Concorrente (50 Goroutines)"]
    Pool --> TaskCh["Canal de Tarefas (IPs a inspecionar)"]
    TaskCh --> Probe1["Goroutine Worker: Socket Connect + Medição RTT"]
    TaskCh --> Probe2["Goroutine Worker: Socket Connect + Medição RTT"]
    Probe1 & Probe2 --> ResultCh["Canal de Resultados (Status, Latência, Banner)"]
    ResultCh --> Aggregator["Agregador de Métricas"]
    Aggregator --> Output["Saída Formatada: Tabela de Terminal ou JSON"]
    style CLI fill:#e1f5fe,stroke:#01579b
    style Pool fill:#fff3e0,stroke:#e65100
    style TaskCh fill:#f3e5f5,stroke:#7b1fa2
    style ResultCh fill:#e8f5e9,stroke:#2e7d32
    style Aggregator fill:#e0f2f1,stroke:#00695c

🔍 Pilares e Diretrizes Técnicas

Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Padrão Worker Pool em Go: Controle rigoroso de paralelismo impedindo saturação acidental de interfaces de rede locais. - Medição Precisa de Latência: Cálculo de microssegundos no estabelecimento de conexões TCP. - Zero Dependências Externas: Binário único executável em qualquer distribuição Linux sem instalação de pacotes adicionais. - Métricas Estruturadas: Compatibilidade com automação por scripts e pipelines de observabilidade corporativa.


🛠️ 2. Implementação Prática em Engenharia de Sistemas em Go, Sockets Raw e Observabilidade

Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:

// goprobe_capstone.go (Scanner de Rede Concorrente com Worker Pool)
package main

import (
    "fmt"
    "net"
    "sync"
    "time"
)

type ScanResult struct {
    Port   int
    Open   bool
    Timing time.Duration
}

func scanWorker(target string, ports <-chan int, results chan<- ScanResult, wg *sync.WaitGroup) {
    defer wg.Done()
    for port := range ports {
        address := fmt.Sprintf("%s:%d", target, port)
        start := time.Now()
        conn, err := net.DialTimeout("tcp", address, 500*time.Millisecond)
        elapsed := time.Since(start)

        if err == nil {
            conn.Close()
            results <- ScanResult{Port: port, Open: true, Timing: elapsed}
        } else {
            results <- ScanResult{Port: port, Open: false, Timing: elapsed}
        }
    }
}

func main() {
    target := "127.0.0.1"
    portsToScan := []int{22, 80, 443, 3306, 5432, 6379, 8080}

    portsChan := make(chan int, len(portsToScan))
    resultsChan := make(chan ScanResult, len(portsToScan))
    var wg sync.WaitGroup

    // Inicia pool de 4 workers concorrentes
    for i := 0; i < 4; i++ {
        wg.Add(1)
        go scanWorker(target, portsChan, resultsChan, &wg)
    }

    for _, p := range portsToScan {
        portsChan <- p
    }
    close(portsChan)

    wg.Wait()
    close(resultsChan)

    fmt.Printf("=== Diagnóstico de Portas para %s ===\n", target)
    for res := range resultsChan {
        status := "FECHADA"
        if res.Open {
            status = "ABERTA"
        }
        fmt.Printf("Porta %5d/TCP: %-8s (RTT: %v)\n", res.Port, status, res.Timing)
    }
}

💡 Análise Passo a Passo do Código

  1. Uso de Canais Buffered e Fechamento Seguro: Alimenta tarefas e coleta respostas de forma determinística sem vazamento de goroutines.
  2. Timeout Estrito com DialTimeout: Evita travamentos em portas protegidas por firewalls que descartam pacotes silenciosamente (Drop).
  3. Sincronização com sync.WaitGroup: Garante que a função principal aguarde a conclusão de todos os workers antes de imprimir o relatório.

🎯 3. Próximos Passos & Sequência Didática