
eBPF + nftables + DNS 프록시를 통한 GitLab Runner CI/CD 작업 컨테이너의 이그레스 강제 — 커뮤니티 에디션 데이터 플레인 https://leitwacht.eu/
https://leitwacht.eu — 정식 저장소: https://gitlab.com/leitwacht/leitwacht-agent. 이슈, MR 및 토론은 GitLab에서 이루어집니다.
Pre-1.0. 0.x 시리즈는 사전 안정화 단계입니다. 1.0이 출시될 때까지 마이너 릴리스에는 API, 환경 변수 이름, Helm
values.yaml키 및 규칙 파일 스키마에 대한 호환성이 깨지는 변경 사항이 포함될 수 있습니다. 프로덕션에서는 이미지 다이제스트(플로팅 태그가 아님)에 고정하세요. 업그레이드 참고 사항은 CHANGELOG.md를 참조하십시오.
leitwacht GitLab Runner egress-제어 시스템을 위한 데이터 플레인 에이전트. eBPF + nftables + in-netns DNS 프록시가 모든 CI 러너 컨테이너에 연결되어 egress 정책을 시행합니다. CE(이 저장소)는 로컬 YAML 파일에서 규칙을 읽으며 완전히 독립적입니다 — 백엔드, 전화 집, 등록이 필요하지 않습니다.
별도 라이선스의 엔터프라이즈 에디션
(gitlab.com/leitwacht/leitwacht)
은 관리형 컨트롤 플레인(규칙 작성 UI, 멀티 테넌시, 감사, GitLab 통합)을 추가합니다. EE 에이전트는 이 저장소에서 agentcore/를 가져와 YAML 로더를 gRPC 규칙 스트림으로 대체합니다.
agentcore/ 데이터 플레인 프리미티브 (MPL-2.0)
enforcer/ eBPF + nftables + DNS 프록시 + LSM cred/proc_mem
watcher/ 컨테이너 수명주기 이벤트 소스 (containerd, docker)
handler/ 수명주기 핸들러 — 에디션 중립적
policy/ ResolvedPolicy + Source 인터페이스 + 로더
advisory/ 일반 Go 자문 유형 + Sink 인터페이스
violation/ 일반 Go 위반 보고 Sink 인터페이스
wildcard/ 도메인 패턴 매칭 헬퍼
version/ 빌드 버전 스탬프 (-ldflags로 설정)
cmd/
leitwacht-initc/ 에이전트 연결 시 진입점을 차단하는 파드 init 컨테이너
ce/ 커뮤니티 에디션 데몬 (MPL-2.0)
cmd/agent-ce/ 바이너리
config/ 환경 기반 데몬 설정
ruleyaml/ YAML 규칙 로더 + fsnotify 핫 리로드
sinks/ stdout NDJSON / Prometheus / 웹훅
helm/agent-ce/ Helm 차트
SCHEMA.md YAML 규칙 스키마 (v1)
examples/
rules.yaml 시작 규칙 세트
docs/
EVENT_FLOW.md watcher → handler → enforcer 흐름 + 튜닝 가능 항목 (mermaid 포함)
leitwacht-agent는 GitLab Runner 관리 레이블 com.gitlab.gitlab-runner.managed=true가 있는 컨테이너만 검사합니다. 이 레이블이 없는 컨테이너 — 수동으로 띄운 것, 사이드카, 애플리케이션 워크로드 — 는 완전히 무시됩니다(이벤트 없음, 시행 없음, 위반 없음). 이는 의도적입니다: leitwacht는 CI 러너 egress를 위한 데이터 플레인이며, 비러너 워크로드는 자동으로 가로채지 않아야 합니다. 비러너 사용 사례는 v0.1.0 범위에 포함되지 않습니다.
# 빌드 (CGO_ENABLED=0은 비Linux 호스트에서도 깨끗하게 크로스 컴파일 가능).
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ./...
# 컨테이너 이미지
docker build -f Dockerfile.agent-ce -t leitwacht/agent-ce:dev .
# Helm 설치 (Kubernetes). dnsUpstream은 필수입니다 — 클러스터 DNS 리졸버를 가리키도록 설정하고,
# 공용 DNS를 가리키지 마십시오. 그래야 내부 서비스가 계속 확인되고 쿼리가 누출되지 않습니다.
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"
rules.yaml의 전체 스키마 참조는 ce/SCHEMA.md에 있습니다.
agentcore/ 및 ce/는 Mozilla Public License 2.0에 따라 배포됩니다 — LICENSE를 참조하십시오. MPL-2.0은 파일 수준의 카피레프트 라이선스입니다: 이 파일들을 자체 제품(상업용 또는 기타)에서 사용, 수정 및 재배포할 수 있지만, MPL-2.0 라이선스 파일에 대한 모든 변경 사항은 동일한 라이선스로 제공되어야 합니다.
gitlab.com/leitwacht/leitwacht의 엔터프라이즈 에디션 백엔드는 다른 라이선스로 배포됩니다. 두 저장소는 동일한 팀에 의해 공동 개발됩니다.
정규 GitLab 저장소(https://gitlab.com/leitwacht/leitwacht-agent)의 이슈 및 병합 요청. 보안 문제는 SECURITY.md의 절차를 따라야 합니다. 워크플로 및 스타일 참고 사항은 CONTRIBUTING.md에 있습니다.
Linux 전용 (eBPF + nftables): GOOS=linux GOARCH=amd64 go build ./...
eBPF 객체(*_bpfel.o)는 커밋되어 있습니다. 재생성하려면 clang + 커널 헤더가 필요하며, CI 빌드는 커밋된 아티팩트에 의존합니다. Linux에서 로컬로 재생성하려면:
go generate ./agentcore/enforcer/