🐝

eBPF 트래픽 리다이렉트 — 커널에서 목적지를 바꿔치기하는 법

Keploy, Cilium, Istio가 앱 코드 수정 없이 트래픽을 제어하는 원리

먼저 eBPF가 뭔지

eBPF(extended Berkeley Packet Filter)는 리눅스 커널 안에서 사용자가 작성한 프로그램을 실행할 수 있게 해주는 기술이다. 커널 코드를 직접 수정하지 않고도 커널의 동작을 확장할 수 있다.

네트워크 패킷 처리, syscall 추적, 보안 정책 적용 등에 쓰인다. 핵심은 "커널 안에서 돌아간다"는 것. 유저 스페이스에서 도는 것보다 오버헤드가 훨씬 적다.

connect() syscall과 eBPF 훅

앱이 DB에 연결할 때 내부적으로 일어나는 일:

1. 앱 코드: db.connect("postgres://localhost:5432")
2. 라이브러리 (pg, psycopg2): socket() → connect() syscall 호출
3. 커널: TCP SYN → SYN-ACK → ACK (3-way handshake)
4. PostgreSQL wire protocol 통신 시작

eBPF는 2~3번 사이에 훅을 건다. connect() syscall이 실행되는 시점에 목적지 주소를 확인하고, 필요하면 다른 주소로 바꿔치기한다.

앱 입장에서는 postgres:5432로 연결한 것이다. 실제 TCP 패킷은 127.0.0.1:16789(프록시)로 간다. 앱은 이 사실을 모른다.

eBPF 프로그램 타입별 훅 포인트

SockOps (BPF_PROG_TYPE_SOCK_OPS) — TCP 이벤트(연결 수립, 종료 등)를 감시. cgroup에 부착해서 특정 컨테이너의 TCP 이벤트만 선별 가능.

connect4/connect6 (BPF_CGROUP_INET4_CONNECT) — connect() syscall 진입 시점에 목적지 IP:Port를 직접 수정. Keploy가 쓰는 핵심 훅이 이거다.

TC (Traffic Control) — 네트워크 인터페이스에 부착. 패킷 단위로 필터링/리다이렉트. Cilium이 Pod 간 트래픽 제어에 사용.

XDP (eXpress Data Path) — NIC에서 패킷이 커널 네트워크 스택에 진입하기 전에 처리. 가장 빠르지만 제약도 큼.

직접 확인하는 법

eBPF 트래픽 리다이렉트를 눈으로 보고 싶으면:

# 1. connect() syscall 추적 — 어떤 프로세스가 어디로 연결하는지
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_connect {
  printf("%s[%d] → connect()\n", comm, pid);
}'

# 2. TCP 연결 수립 추적 (목적지 확인)
sudo bpftrace -e 'kprobe:tcp_v4_connect {
  printf("%s → %s:%d\n", comm,
    ntop(((struct sockaddr_in *)arg1)->sin_addr.s_addr),
    ntohs(((struct sockaddr_in *)arg1)->sin_port));
}'

Keploy를 켠 상태에서 앱을 실행하면, connect()의 목적지가 postgres:5432가 아닌 127.0.0.1:프록시포트로 바뀌는 걸 볼 수 있다.

Keploy로 간단 테스트

# 설치 (Linux)
curl -O -L https://keploy.io/install.sh && source install.sh

# 녹화 — 앱 트래픽 캡처
keploy record -c "docker compose up" --container-name my-app
# → 브라우저에서 앱을 사용하면 HTTP + DB 트래픽이 keploy/ 폴더에 YAML로 저장

# 재생 — 녹화된 트래픽으로 자동 테스���
keploy test -c "docker compose up" --container-name my-app
# → 실제 DB 없이도 테스트가 돌아감

macOS에서는 Docker Desktop 위에서만 동작한다. eBPF가 리눅스 커널 기능이라서.

동작 흐름

1

eBPF 프로그램이 커널에 로드 — connect4 훅으로 connect() syscall 가로채기

2

앱이 connect(postgres:5432) 호출 → eBPF가 목적지를 프록시(127.0.0.1:proxyPort)로 수정

3

프록시가 진짜 목적지에 중계하면서 트래픽을 녹화 (녹화) 또는 녹화된 응답 반환 (재생)

4

앱은 목적지가 바뀐 걸 모름 — 커널 레벨 투명 리다이렉트

사용 사례

Keploy — connect4 훅으로 DB/API 트래픽을 프록시로 리다이렉트, 테스트 자동 생성 Cilium — TC 훅으로 Kubernetes Pod 간 트래픽 제어. iptables 대체 Istio ambient — eBPF로 사이드카 없이 서비스 메시 구현 Beyla — XDP/TC로 HTTP/gRPC/SQL을 자동 감지, OpenTelemetry 메트릭 수집