Voltar às atualizações
New releaseAug 20, 2026

LeitWacht Agent v0.9.0

eBPF + nftables + DNS proxy egress enforcement para contêineres de job CI/CD do GitLab Runner — plano de dados da edição comunitária https://leitwacht.eu/

Compartilhar

leitwacht-agent

https://leitwacht.eu — fonte da verdade: https://gitlab.com/leitwacht/leitwacht-agent. Issues, MRs e discussões ficam no GitLab.

Pré-1.0. A série 0.x é pré-estável; versões menores podem trazer mudanças que quebram compatibilidade nas APIs, nomes de env-vars, chaves do values.yaml do Helm e esquema do arquivo de regras até o lançamento da 1.0. Fixe em digests de imagem (não tags flutuantes) em produção. Veja CHANGELOG.md para notas de atualização.

O agente do plano de dados para o sistema de controle de egresso do GitLab Runner da leitwacht. eBPF + nftables + um proxy DNS no namespace de rede são anexados a cada contêiner do runner de CI e aplicam a política de egresso. A CE (este repositório) lê suas regras de um arquivo YAML local e é totalmente independente — sem backend, sem telefonar para casa, sem registro.

Uma Enterprise Edition licenciada separadamente (gitlab.com/leitwacht/leitwacht) adiciona um plano de controle gerenciado (IU de criação de regras, multi-inquilino, auditoria, integração com GitLab). O agente EE importa agentcore/ deste repositório e substitui o carregador YAML por um fluxo de regras gRPC.

Layout

agentcore/                   primitivas do plano de dados (MPL-2.0)
  enforcer/                  eBPF + nftables + proxy DNS + LSM cred/proc_mem
  watcher/                   fonte de eventos do ciclo de vida do contêiner (containerd, docker)
  handler/                   manipulador do ciclo de vida — neutro de edição
  policy/                    ResolvedPolicy + interface Source + carregador
  advisory/                  tipo advisory em Go puro + interface Sink
  violation/                 interface Sink de relatório de violação em Go puro
  wildcard/                  auxiliares de correspondência de padrões de domínio
  version/                   carimbo de versão de build (definido via -ldflags)
  cmd/
    leitwacht-initc/          contêiner de init do pod que bloqueia pontos de entrada até o anexo do agente

ce/                          Daemon Community Edition (MPL-2.0)
  cmd/agent-ce/              o binário
  config/                    configurações do daemon orientadas por env
  ruleyaml/                  carregador de regras YAML + hot-reload via fsnotify
  sinks/                     stdout NDJSON / Prometheus / webhook
  helm/agent-ce/             Chart Helm
  SCHEMA.md                  esquema de regras YAML (v1)

examples/
  rules.yaml                 conjunto inicial de regras

docs/
  EVENT_FLOW.md              fluxo watcher → handler → enforcer + ajustes (com mermaid)

Escopo do contêiner

O leitwacht-agent inspeciona apenas contêineres que possuem o rótulo gerenciado do GitLab Runner com.gitlab.gitlab-runner.managed=true. Contêineres sem este rótulo — qualquer coisa que você iniciar manualmente, sidecars, cargas de trabalho de aplicação — são ignorados completamente (sem eventos, sem aplicação, sem violações). Isso é proposital: leitwacht é o plano de dados para egresso do runner de CI, e cargas de trabalho que não são runners não devem ser interceptadas silenciosamente. Casos de uso que não são Runner estão fora do escopo para v0.1.0.

Limitações conhecidas (v0.1.0)

  • Apenas IPv4. Os programas eBPF e o proxy DNS aplicam a política no tráfego IPv4; o egresso IPv6 é descartado na fronteira do namespace de rede independentemente da política. Trabalhos de CI que exigem conectividade IPv6 não podem usar a aplicação do leitwacht até que isso seja resolvido.
  • Apenas Linux x86_64. Runners arm64 ainda não são suportados (a CI envia imagens amd64; arm64 virá assim que tivermos artefatos eBPF para essa arquitetura).
  • Apenas cargas de trabalho do GitLab Runner. Veja "Escopo do contêiner" acima.

Início rápido

# Build (CGO_ENABLED=0 permite que hosts não-Linux façam cross-compile limpo).
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ./...

# Imagem do contêiner
docker build -f Dockerfile.agent-ce -t leitwacht/agent-ce:dev .

# Instalação Helm (Kubernetes). dnsUpstream é obrigatório — aponte-o para o
# resolvedor DNS do seu cluster, não para um público, para que serviços internos
# continuem resolvendo e consultas não vazem.
KUBE_DNS_IP=$(kubectl -n kube-system get svc kube-dns -o jsonpath='{.spec.clusterIP}')
helm install leitwacht-ce ./ce/helm/agent-ce \
  -n leitwacht --create-namespace \
  --set-file rules=examples/rules.yaml \
  --set "dnsUpstream=${KUBE_DNS_IP}:53"

A referência completa do esquema para rules.yaml está em ce/SCHEMA.md.

Licença

agentcore/ e ce/ são distribuídos sob a Licença Pública Mozilla 2.0 — veja LICENSE. MPL-2.0 é uma licença copyleft em nível de arquivo: você pode usar, modificar e redistribuir estes arquivos em seus próprios produtos (comerciais ou não), mas quaisquer alterações que você fizer em arquivos licenciados sob MPL-2.0 devem ser disponibilizadas sob a mesma licença.

O backend da Enterprise Edition em gitlab.com/leitwacht/leitwacht é distribuído sob uma licença diferente. Os dois repositórios são co-desenvolvidos pela mesma equipe.

Contribuindo

Issues e merge requests no repositório GitLab canônico (https://gitlab.com/leitwacht/leitwacht-agent). Problemas de segurança devem seguir o processo em SECURITY.md. Notas sobre workflow e estilo estão em CONTRIBUTING.md.

Compilação

Apenas Linux (eBPF + nftables): GOOS=linux GOARCH=amd64 go build ./...

Os objetos eBPF (*_bpfel.o) estão mantidos porque regenerá-los requer clang + cabeçalhos do kernel; builds de CI dependem dos artefatos mantidos. Para regenerar localmente no Linux:

go generate ./agentcore/enforcer/

Categorias