
Sensor de rede Spip escrito em Go
Spip é um sensor honeypot de rede leve e de baixa interação. Ele escuta tráfego TCP de entrada arbitrário (simples e TLS), captura o que scanners e bots enviam, e registra cada conexão como JSON estruturado (em formato ECS) para fácil ingestão no seu SIEM ou data lake.
Os sensores Spip alimentam HoneyLabs, uma plataforma gratuita e pesquisável de inteligência de ameaças construída sobre os dados que eles capturam. Para ver o que o Spip coleta na prática, navegue pelos relatórios ao vivo por IP lá ou pelo relatório semanal de ameaças gerado pela rede de sensores.

Pré-requisitos
iptablesgit clone https://github.com/honeylabshq/Spip-Go.git
cd Spip-Go
go build -o spip-agent ./cmd/spip-agent
sudo ./scripts/initial_setup.sh
Este assistente escreve um config.toml (ele solicita um curto usado nos logs), pode gerar chaves TLS autoassinadas, opcionalmente configura Loom (URL, sensor_id, token, etc.), e opcionalmente aplica o redirecionamento PREROUTING do iptables usado nos exemplos abaixo.
nameconfig.toml
config.toml mínimo:name = "spip-agent"
ip = "127.0.0.1"
port = 8080
Chaves de configuração opcionais:
cert_path / key_path — habilita TLS se ambos definidos; podem ser relativos ao arquivo de configuração (o script de configuração escreve caminhos relativos para que o config funcione a partir de qualquer diretório de trabalho)log_file (local) e/ou [loom] (remoto). Veja Saída de log abaixo.read_timeout_seconds / write_timeout_seconds — timeouts de conexãorate_limit_per_second / rate_limit_burst — limitação de taxa de conexãocommunity_id_seed — semente opcional de 16 bits para hashing de fluxo Community ID v1 (omitir ou 0 para padrão)Se esses campos de ajuste de tempo de execução forem omitidos ou definidos como 0, o Spip aplica os seguintes padrões:
read_timeout_seconds: 30write_timeout_seconds: 10rate_limit_per_second: 20rate_limit_burst: 50000sudo iptables -t nat -F
sudo iptables -t nat -A PREROUTING -p tcp --dport 22 -j RETURN
sudo iptables -t nat -A PREROUTING -p tcp -j REDIRECT --to-port 8080
./spip-agent -config config.toml
Spip escreve logs ECS em um único destino local e pode opcionalmente enviar os mesmos logs para um servidor Loom:
| Destino | Config | Comportamento |
|---|---|---|
| Local | log_file | Padrão: omitir ou deixar vazio → stdout. Defina um caminho → esse arquivo. Um dos dois, sempre ativo. |
| Loom | [loom] com enabled = true | Opcional. Os mesmos eventos são agrupados e enviados via POST para sua URL de ingestão Loom, além do local. |
Portanto: local padrão é stdout; substitua com log_file para um arquivo. Opcionalmente adicione Loom por cima. Ambos usam o mesmo formato ECS.
log_file comentado/vazio (stdout) ou defina um caminho.[loom] com url, sensor_id, token (veja Loom abaixo).Spip emite cada conexão como um único objeto JSON. A saída é formatada para ser compatível com ECS usando apenas os campos que o Spip pode fornecer (sem enriquecimento ASN/geo). Campos típicos produzidos incluem:
@timestamp — timestamp RFC3339 para o eventoevent.id — identificador de sessão por conexãoobserver.hostname / host.name — name do agente da configuraçãosource.ip, source.port e destination.ip, destination.portnetwork.transport — ex.: tcphttp.request.body / url.path — quando o payload claramente se assemelha a HTTPuser_agent.original — quando disponívelevent.summary — payload bruto para sondagens não-HTTPevent.original_payload_hex — hex do payload bruto (sempre preservado)network.community_id, tls.client.*, http.request.hash.ja4h, ssh.client.hash.hassh quando aplicável.Exemplo de registro (formato ECS) produzido pelo Spip:
{
"@timestamp": "2025-12-01T19:35:18.123Z",
"event": {
"id": "bd30cdc1-95b0-49aa-b8fe-e77230b6a04f",
"summary": "BitTorrent protocol",
"original_payload_hex": "426974546f7272656e742070726f746f636f6c",
"ingested_by": "spip"
},
"observer": {"hostname": "spip-agent"},
"host": {"name": "spip-agent"},
"source": {"ip": "146.70.1.1", "port": 35882},
"destination": {"ip": "146.190.1.1", "port": 6881},
"network": {"transport": "tcp"}
}
Nota: o agente apenas emite campos que pode derivar do payload e metadados da conexão. Sistemas downstream podem enriquecer esses registros (geo, ASN, etc.) se desejado.
Spip pode adicionar campos de fingerprinting passivo a cada registro de conexão (compatível com ECS, sem alteração na captura de payload):
network.community_id) — hash de fluxo v1 do 5-tuplo (IP de origem/destino e porta, protocolo). Quando o tráfego é redirecionado via iptables, o Spip usa o destino original (antes do REDIRECT) para que o hash corresponda ao que outras ferramentas (ex.: Zeek, Suricata) calculariam para o mesmo fluxo.tls.client.server_name (SNI), tls.client.supported_protocols (lista ALPN), tls.client.hash.ja4 (fingerprint JA4).http.request.hash.ja4h (JA4H).SSH-2.0- e contém um KEXINIT: ssh.client.hash.hassh (Hassh).Todos esses são aditivos; o comportamento existente (log local, Loom, hex do payload, parsing HTTP) permanece inalterado.
Referências (para verificação e atribuição):
Community ID: Corelight Community ID spec.
JA4 / JA4H: FoxIO JA4.
Hassh: Salesforce HASSH.
TLS fingerprinting uses github.com/psanford/tlsfingerprint (MIT).
Parte da saída de log: quando [loom] tem enabled = true, os mesmos registros ECS também são agrupados e enviados via POST para sua URL de ingestão Loom. Necessário quando habilitado: url, sensor_id, token. Opcionais: batch_size (padrão 50), flush_interval (ex.: "10s"), insecure_skip_verify (para certificados Loom autoassinados). O exportador roda assincronamente e não bloqueia o loop de captura; POSTs com falha são registrados no stderr e o lote é descartado (fail-open).
.
├── cmd/ # Ponto de entrada principal da aplicação
├── internal/ # Config, logging, rede, TLS, fingerprinting, exportadores (ex.: Loom)
├── pkg/ # Auxiliares de socket Linux (SO_ORIGINAL_DST via syscall)
├── test/ # Auxiliares de teste fim a fim
└── scripts/ # Scripts utilitários (incluindo `initial_setup.sh`)
Execute testes unitários com:
go test ./...
Testes fim a fim exigem privilégios para manipular iptables. Execute-os através do script (a partir da raiz do repositório):
sudo -E ./scripts/run_e2e_tests.sh
O script configura o ambiente e o iptables. Alternativamente, use o auxiliar de contêiner: ./scripts/run_e2e_in_container.sh. E2E valida o comportamento principal (captura de payload, origem/destino, detecção TLS, agrupamento Loom, fingerprinting).
Spip realiza detecção de requisições HTTP de melhor esforço a partir do payload capturado. Quando o payload claramente se assemelha a uma requisição HTTP (linha de requisição válida mais cabeçalhos básicos ou ALPN), o agente emite campos http.*, url.path e user_agent.original. Quando não, o Spip recorre ao armazenamento do payload em event.summary e sempre preserva o hex do payload bruto em event.original_payload_hex.
Como o Spip reflete o IP de origem em suas respostas e aceita tráfego TCP de entrada arbitrário, ele é destinado ao uso como sensor estilo honeypot ou coletor de borda em ambientes controlados/monitorados, não em endpoints de usuário arbitrários.
Execute o assistente interativo a partir da raiz do repositório (requer root ao aplicar regras de iptables):
sudo ./scripts/initial_setup.sh
O script solicita: um name curto (escrito no config.toml, usado nos logs como observer.hostname / host.name), IP e porta de escuta, geração opcional de certificado TLS autoassinado (caminhos são escritos relativos ao config para funcionar de qualquer diretório), configuração opcional de Loom (URL, sensor_id, token, batch_size, flush_interval, verificação TLS), caminho do arquivo de log e redirecionamento opcional iptables PREROUTING.