
O alarme apontou para o vizinho — quando a etiqueta da porta mente sobre o serviço
O alarme estava certo. O endereço, não.
O relatório de exposição da madrugada de 17 de outubro trouxe quatro linhas vermelhas. Uma delas apontava um serviço conhecido, com nome e sobrenome, escutando em todas as interfaces da máquina.
Fui conferir antes de agir. Naquela porta quem respondia era outro processo — um serviço interno de embeddings, sem autenticação de nenhum tipo. O serviço nomeado no alarme existia, mas escutava só em loopback, numa porta diferente da que o relatório dizia. A migração de máquina tinha trocado os endereços semanas antes; a etiqueta, não.
Isso muda o trabalho por inteiro. Um alarme com endereço errado manda você consertar a porta do vizinho enquanto a sua continua aberta — e ainda entrega a sensação de dever cumprido quando o vermelho vira verde.
A etiqueta que envelheceu
O inventário carrega um mapa estático de porta para serviço, escrito à mão quando a topologia era outra. Toda vez que uma peça muda de lugar — nesse dia tinham mudado duas, numa migração de host — o mapa vira resíduo. O número continua exato. O nome, não.
A ordem certa, que passou a valer depois disso, é não confiar no rótulo:
- Identidade, não endereço. Verificar quem responde de verdade, comparando o corpo da resposta e não só o código HTTP. Um
200não diz que serviço atendeu. - Loopback por padrão. Serviço que só serve consumidor local não tem motivo para escutar em todas as interfaces.
- Exceção declarada, com prova datada. Binds de LAN por design entram numa lista de aceitos, cada um com motivo e data. O que é aceito fica separado do que é exposto — senão o vermelho perde sentido.
Depois da cura, o relatório saiu de 12 achados para 6, todos exposição real. Os 26 registros de porta desconhecida em loopback viraram informativos e 11 binds passaram a aceitos por design. Hoje são 43 serviços mapeados.
A segunda mentira, por omissão
Na mesma madrugada, o mesmo relatório dizia, no topo: “nenhum leak real detectado nos seis projetos”.
Cinco dos seis repositórios nunca tinham sido lidos: o scanner procurava os projetos num diretório que a migração deixou para trás e recebia Path not found em cinco de seis — e ainda carimbava o resumo como limpo. Pior, a varredura chamava um transporte de outro sistema operacional, um shim que não existe mais nesta máquina. O silêncio dele era o silêncio do erro.
Antes de consertar, provei que o scanner funcionava: plantei um segredo de formato conhecido num repositório descartável — 1 achado, no tipo certo. No repositório real, 19 achados brutos em cerca de 0,6 segundo. O binário estava bom; o caminho e o transporte é que estavam mortos.
A defesa que ficou: projeto não escaneado agora é estado de primeira classe. Ele vira NAO VERIFICAVEL no resumo, com severidade própria, e o resumo nunca mais pode dizer “limpo” com repositório fora da leitura. Ausência de prova nunca é prova de sucesso.
Ruído que se aprende a ignorar é a terceira mentira
Os 19 achados brutos vinham todos do mesmo arquivo: um artefato local, fora do git. Nada vazava. Se cada um virasse alerta, em uma semana eu teria aprendido a ignorar alerta — e ruído ignorado é gate cego.
A classificação ficou assim:
| Situação | Classificação | Efeito |
|---|---|---|
| Segredo em arquivo versionado | crítico | alerta |
| Segredo em artefato local, fora do git | local | contado, sem alerta |
| Projeto fora da leitura | não verificável | alerta sempre |
| Mesma porta com bind novo | já visto | silêncio (ledger) |
Junto vieram os detalhes que fazem um cron sobreviver: saída vazia é silêncio; código de saída sempre zero, porque o scanner devolve erro quando acha o que procura; e o wrapper limpa o PYTHONPATH antes de subir, para o processo não herdar bibliotecas de outro ambiente. São 10 controles automatizados provando o comportamento: repo limpo cala, segredo versionado grita, projeto ausente avisa. Uma revisão independente deu 95 de 100.
Onde estava o risco de verdade
Fecha o caso a lição mais desconfortável: o que estava aberto não era o serviço famoso do alarme, era o encanamento. Dois processos de embeddings — um deles sem autenticação — escutando para a rede inteira, servindo um motor de busca e uma API. Nenhum tem painel, nenhum tem login: são “infraestrutura invisível”.
Movi os dois para loopback com uma sobrescrita de unidade do gerenciador de serviços. O rollback é apagar a sobrescrita, recarregar e reiniciar — documentado no mesmo commit. Validei os consumidores: a busca de memória voltou resultado (score 0,855), a API respondeu saudável e o log do container ficou limpo.
O que vem a seguir
Restam quatro exposições que precisam de decisão, uma a uma: o serviço de área de trabalho remota da estação, dois containers de aplicação que publicam mais do que deveriam e a porta ponto a ponto do cliente de torrent, aberta por natureza. Cada uma é uma decisão com dono e data, não um sed automático.
E fica a pendência que o caso criou: transformar NAO VERIFICAVEL em alerta que acorda alguém. Hoje o resumo registra o projeto fora da leitura, mas quem lê o resumo sou eu, passando os olhos de manhã. Isso é hábito, não sistema — e hábito não sobrevive a semana ruim.
# 1. o scanner acha o que eu plantei de proposito?
gitleaks detect --source /tmp/isca --report-format json
# 2. identidade, nao etiqueta: quem responde naquela porta?
ss -tlnp | grep '<porta>'
curl -sS -X POST "http://127.0.0.1:<porta>/embeddings" -o /tmp/resp.json -w '%{http_code}\n'
# 3. depois da cura: silencio com tudo verificado e limpo
./vigia-de-segurancas.sh --alerta-somente; echo "exit=$?"Leia também
Mesmo projeto, mesma trilha — as histórias se conectam.
Próximo passo
Se isto te serviu, tem mais: escrevo sobre o mesmo assunto nos outros projetos, e a loja tem as ferramentas que eu uso aqui.
Anotado — aviso quando sair artigo novo.
Sem spam, descadastro de um clique. Também estou aqui: Loja de skills · Portfólio