Tooling

GitHub이 eBPF로 배포 안전성을 높이는 방법 — 순환 의존성 차단기

GitHub이 배포 스크립트의 GitHub.com 의존성을 eBPF로 감지하고 차단해 배포 순환 의존성 문제를 해결한 방법을 분석한다.

7 min read
eBPFGitHub배포Linux인프라
GitHub이 eBPF로 배포 안전성을 높이는 방법 — 순환 의존성 차단기

GitHub은 자신의 코드를 GitHub에서 호스팅한다. 그런데 배포 시스템도 GitHub을 쓰면 어떻게 될까? GitHub이 장애나면 배포도 못 하고, 배포를 못 하면 장애를 고칠 수도 없다. 뱀이 자기 꼬리를 무는 상황이다.

이 문제를 GitHub은 eBPF로 풀었다.


순환 의존성이란

배포 시스템이 GitHub 자체에 의존하는 패턴은 3가지 형태로 나타난다.

유형설명예시
직접 의존성배포 스크립트가 GitHub에서 도구를 다운로드curl https://github.com/.../binary
숨은 의존성설치된 도구가 자동으로 업데이트 확인npm, pip, brew의 자동 체크
전이적 의존성배포가 호출한 내부 서비스가 GitHub을 필요로 함내부 API가 GitHub Auth를 사용

직접 의존성은 찾기 쉽지만, 숨은 의존성과 전이적 의존성은 보이지 않는다. 배포 도중에 갑자기 GitHub에 접속하려다 실패하는 경우가 생긴다.


왜 단순 차단으로 안 되나

"배포 중에 github.com을 그냥 차단하면 되지 않나?"라는 생각이 들 수 있다. 그런데 배포가 실행되는 호스트들은 동시에 고객 트래픽을 처리하고 있다. 전체 서버에서 github.com을 차단하면 고객이 GitHub을 쓰지 못한다.

필요한 것은 배포 스크립트 프로세스만 선택적으로 모니터링하고 차단하는 기능이다. eBPF가 여기서 등장한다.

[💡 잠깐! 이 용어는?] eBPF(extended Berkeley Packet Filter): Linux 커널에 커스텀 프로그램을 로드해서 네트워킹, 보안, 추적 같은 핵심 시스템 기능에 연결하는 기술. 커널 모듈을 새로 작성하지 않아도 커널 수준에서 동작한다.


eBPF 기반 구현

GitHub은 두 가지 eBPF 프로그램 타입을 결합했다.

프로그램 타입 1: BPF_PROG_TYPE_CGROUP_SKB

Linux cgroup에 연결되어 네트워크 트래픽을 필터링한다. IP 주소 기반으로 동작한다.

[💡 잠깐! 이 용어는?] cgroup(Control Group): Linux에서 프로세스 그룹의 리소스(CPU, 메모리, 네트워크)를 제한하고 격리하는 커널 기능. 컨테이너 기술의 기초다.

프로그램 타입 2: BPF_PROG_TYPE_CGROUP_SOCK_ADDR

소켓 생성 syscall을 후킹해서 DNS 쿼리(포트 53)를 localhost의 프록시로 리다이렉트한다.

eBPF 아키텍처
배포 스크립트 프로세스
  [cgroup에 배치]

  DNS 쿼리 발생 (포트 53)

  eBPF: 쿼리를 localhost 프록시로 리다이렉트

  DNS 프록시 (사용자 공간)
  → 차단 목록 확인
  → 허용: 실제 DNS 서버로 전달
  → 차단: 실패 응답 + 로그 기록

IP 주소 기반 차단보다 도메인 기반 차단이 더 유연하다. github.com이 CDN을 바꿔도 도메인 이름만 차단하면 된다.


프로세스 추적 — 어느 명령이 문제인가

단순히 차단하는 걸 넘어서, 어느 프로세스가 금지된 도메인에 접속하려 했는지를 추적한다.

DNS 트랜잭션 ID와 프로세스 ID(PID)를 eBPF Map으로 매핑한다. PID가 나오면 /proc/{PID}/cmdline을 읽어 전체 명령줄을 복원한다.

감사 로그 예시
WARN DNS BLOCKED domain=github.com pid=266767 cmd="curl https://github.com/org/repo/releases/download/v1.2.3/tool"

이 로그로 팀이 어느 스크립트가 GitHub에 의존하는지 정확히 알 수 있다.


추가 효과: 리소스 제한

cgroup으로 배포 스크립트를 묶는 부수효과가 하나 더 있다. 배포 스크립트의 CPU와 메모리 사용량도 제한할 수 있다. 잘못 작성된 배포 스크립트가 서버 리소스를 독차지하는 사고를 방지한다.


결과

6개월 롤아웃 후 시스템이 운영 중이다.

  • 자동 감지: 순환 의존성 발생 시 실시간 차단
  • 알림: 차단 발생 팀에 즉시 알림
  • 감사 목록: 배포 중 접속한 모든 도메인 기록
  • MTTR 단축: 더 빠른 사건 복구

실무 적용 시 고려사항

eBPF를 직접 쓰는 건 복잡도가 높다. Linux 커널 버전 호환성, cgroup v2 지원, eBPF Map 크기 관리 등을 고려해야 한다. GitHub 규모에서는 직접 구현이 필요했지만, 소규모 팀이라면 falco, tetragon 같은 eBPF 기반 보안 도구를 먼저 검토하는 게 현실적이다.

그러나 "배포 스크립트가 외부 네트워크에 접속하면 차단한다"는 아이디어 자체는 어떤 규모에서도 유효하다. 네트워크 격리가 없다면 배포 중에 어디에 접속하는지조차 모른다.


마무리

  • eBPF: 커널 수준에서 프로세스별 네트워크를 제어하는 유일한 실용적 방법
  • cgroup 격리: 배포 스크립트를 프로세스 단위로 격리해서 차단과 리소스 제한을 동시에
  • DNS 프록시: 도메인 기반 차단으로 IP 변경에 강건

배포 시스템이 배포 대상에 의존하는 순환은 언제든 생길 수 있다. GitHub이 아니더라도, 의존성 레지스트리나 CI 서버가 해당될 수 있다. 배포 중 외부 접속을 모니터링하고 차단하는 레이어가 하나 있어야 한다.


참고: